new stink bug, termites, started to fix new kraken

This commit is contained in:
craisinlord committed 2026-06-25 23:41:43 -05:00
1 parent 36b7530104
commit b00ee762ab
48 files changed
+4786 -1152

No files matched your search

@@ -90,6 +90,8 @@ public final class AntarchySettings {
private static ResourceKey<Level> rainbowAntNonInfinityFallbackDimension = dimensionKey("antarchy:elythia");
private static double krakenHealth = 1500.0D;
private static double krakenAttackDamage = 45.0D;
private static double octopusBombHealth = 250.0D;
private static double octopusBombAttackDamage = 16.0D;
private static double brutalflyHealth = 400.0D;
private static double brutalflySwipeDamage = 15.0D;
private static double brutalflySpitDamage = 5.0D;
@@ -733,6 +735,18 @@ public final class AntarchySettings {
return krakenAttackDamage;
}
public static double octopusBombHealth() {
return octopusBombHealth;
}
public static void setOctopusBombHealth(double value) { octopusBombHealth = value; }
public static double octopusBombAttackDamage() {
return octopusBombAttackDamage;
}
public static void setOctopusBombAttackDamage(double value) { octopusBombAttackDamage = value; }
public static double brutalflyHealth() {
return brutalflyHealth;
}
@@ -18,6 +18,7 @@ import com.craisinlord.antarchy.content.entity.brutalfly.BrutalflyOrbEntity;
import com.craisinlord.antarchy.content.block.entity.HushweedBlockEntity;
import com.craisinlord.antarchy.content.entity.flying_squirrel.FlyingSquirrelEntity;
import com.craisinlord.antarchy.content.entity.MissileSquidEntity;
import com.craisinlord.antarchy.content.entity.OctopusBombEntity;
import com.craisinlord.antarchy.content.entity.kraken.KrakenEntity;
import com.craisinlord.antarchy.content.entity.MolewormEntity;
import com.craisinlord.antarchy.content.entity.MantisEntity;
@@ -53,6 +54,8 @@ public final class AntarchyObjects {
@SuppressWarnings("unchecked")
public static Supplier<EntityType<MissileSquidEntity>> MISSILE_SQUID = (Supplier<EntityType<MissileSquidEntity>>) UNBOUND;
@SuppressWarnings("unchecked")
public static Supplier<EntityType<OctopusBombEntity>> OCTOPUS_BOMB = (Supplier<EntityType<OctopusBombEntity>>) UNBOUND;
@SuppressWarnings("unchecked")
public static Supplier<EntityType<MolewormEntity>> MOLEWORM = (Supplier<EntityType<MolewormEntity>>) UNBOUND;
@SuppressWarnings("unchecked")
public static Supplier<EntityType<MantisEntity>> MANTIS = (Supplier<EntityType<MantisEntity>>) UNBOUND;
@@ -404,6 +407,10 @@ public final class AntarchyObjects {
return state.is(DUPLICATOR_LOG.get()) || state.is(DUPLICATOR_SAPLING.get());
}
public static void setOctopusBomb(Supplier<EntityType<OctopusBombEntity>> supplier) {
OCTOPUS_BOMB = supplier;
}
public static BlockBehaviour.Properties shellstoneProperties() {
return BlockBehaviour.Properties.ofFullCopy(Blocks.STONE).requiresCorrectToolForDrops();
}
@@ -12,9 +12,7 @@ public class KrakenModel extends GeoModel<KrakenEntity> {
@Override
public ResourceLocation getTextureResource(KrakenEntity animatable) {
return animatable.isPhaseTwo()
? ResourceLocation.fromNamespaceAndPath("antarchy", "textures/entity/kraken_purple.png")
: ResourceLocation.fromNamespaceAndPath("antarchy", "textures/entity/kraken.png");
return ResourceLocation.fromNamespaceAndPath("antarchy", "textures/entity/kraken.png");
}
@Override
@@ -0,0 +1,22 @@
package com.craisinlord.antarchy.content.client.model;
import com.craisinlord.antarchy.content.entity.OctopusBombEntity;
import net.minecraft.resources.ResourceLocation;
import software.bernie.geckolib.model.GeoModel;
public class OctopusBombModel extends GeoModel<OctopusBombEntity> {
@Override
public ResourceLocation getModelResource(OctopusBombEntity animatable) {
return ResourceLocation.fromNamespaceAndPath("antarchy", "geo/octopus_bomb.geo.json");
}
@Override
public ResourceLocation getTextureResource(OctopusBombEntity animatable) {
return ResourceLocation.fromNamespaceAndPath("antarchy", "textures/entity/octopus_bomb.png");
}
@Override
public ResourceLocation getAnimationResource(OctopusBombEntity animatable) {
return ResourceLocation.fromNamespaceAndPath("antarchy", "animations/octopus_bomb.animation.json");
}
}
@@ -0,0 +1,27 @@
package com.craisinlord.antarchy.content.client.model;
import com.craisinlord.antarchy.Antarchy;
import com.craisinlord.antarchy.content.entity.ant.TermiteEntity;
import net.minecraft.resources.ResourceLocation;
import software.bernie.geckolib.model.GeoModel;
public class TermiteModel extends GeoModel<TermiteEntity> {
private static final ResourceLocation MODEL = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "geo/termite.geo.json");
private static final ResourceLocation TEXTURE = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "textures/entity/termite.png");
private static final ResourceLocation ANIMATIONS = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "animations/termite.animation.json");
@Override
public ResourceLocation getModelResource(TermiteEntity animatable) {
return MODEL;
}
@Override
public ResourceLocation getTextureResource(TermiteEntity animatable) {
return TEXTURE;
}
@Override
public ResourceLocation getAnimationResource(TermiteEntity animatable) {
return ANIMATIONS;
}
}
@@ -8,7 +8,7 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer;
public class KrakenRenderer extends GeoEntityRenderer<KrakenEntity> {
public KrakenRenderer(EntityRendererProvider.Context context) {
super(context, new KrakenModel());
this.shadowRadius = 3.6F;
this.withScale(3.0F);
this.shadowRadius = 2.0F;
this.withScale(1.5F);
}
}
@@ -0,0 +1,13 @@
package com.craisinlord.antarchy.content.client.renderer;
import com.craisinlord.antarchy.content.client.model.OctopusBombModel;
import com.craisinlord.antarchy.content.entity.OctopusBombEntity;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
import software.bernie.geckolib.renderer.GeoEntityRenderer;
public class OctopusBombRenderer extends GeoEntityRenderer<OctopusBombEntity> {
public OctopusBombRenderer(EntityRendererProvider.Context context) {
super(context, new OctopusBombModel());
this.shadowRadius = 1.2F;
}
}
@@ -2,34 +2,16 @@ package com.craisinlord.antarchy.content.client.renderer;
import com.craisinlord.antarchy.content.client.model.StinkBugModel;
import com.craisinlord.antarchy.content.entity.StinkBugEntity;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
import org.jetbrains.annotations.Nullable;
import software.bernie.geckolib.cache.object.BakedGeoModel;
import software.bernie.geckolib.renderer.GeoEntityRenderer;
public class StinkBugRenderer extends GeoEntityRenderer<StinkBugEntity> {
private static final float ADULT_SCALE = 0.75F;
private static final float BABY_SCALE = 0.50F;
private static final float ADULT_SHADOW_RADIUS = 0.6F;
private static final float ADULT_SCALE = 0.95F;
private static final float ADULT_SHADOW_RADIUS = 0.2F;
public StinkBugRenderer(EntityRendererProvider.Context context) {
super(context, new StinkBugModel());
this.shadowRadius = ADULT_SHADOW_RADIUS;
this.withScale(ADULT_SCALE);
}
@Override
public void preRender(PoseStack poseStack, StinkBugEntity animatable, BakedGeoModel model, @Nullable MultiBufferSource bufferSource, @Nullable VertexConsumer buffer, boolean isReRender, float partialTick, int packedLight, int packedOverlay, int colour) {
super.preRender(poseStack, animatable, model, bufferSource, buffer, isReRender, partialTick, packedLight, packedOverlay, colour);
if (animatable.isBaby()) {
poseStack.scale(BABY_SCALE, BABY_SCALE, BABY_SCALE);
this.shadowRadius = ADULT_SHADOW_RADIUS * BABY_SCALE;
} else {
this.shadowRadius = ADULT_SHADOW_RADIUS;
}
}
}
@@ -0,0 +1,35 @@
package com.craisinlord.antarchy.content.client.renderer;
import com.craisinlord.antarchy.content.client.model.TermiteModel;
import com.craisinlord.antarchy.content.entity.ant.TermiteEntity;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
import org.jetbrains.annotations.Nullable;
import software.bernie.geckolib.cache.object.BakedGeoModel;
import software.bernie.geckolib.renderer.GeoEntityRenderer;
public class TermiteRenderer extends GeoEntityRenderer<TermiteEntity> {
private static final float ADULT_SHADOW_RADIUS = 0.3F;
private static final float ADULT_SCALE = 0.85F;
private static final float BABY_SCALE = 0.5F;
public TermiteRenderer(EntityRendererProvider.Context context) {
super(context, new TermiteModel());
this.shadowRadius = ADULT_SHADOW_RADIUS;
}
@Override
public void preRender(PoseStack poseStack, TermiteEntity animatable, BakedGeoModel model, @Nullable MultiBufferSource bufferSource, @Nullable VertexConsumer buffer, boolean isReRender, float partialTick, int packedLight, int packedOverlay, int colour) {
super.preRender(poseStack, animatable, model, bufferSource, buffer, isReRender, partialTick, packedLight, packedOverlay, colour);
if (animatable.isBaby()) {
poseStack.scale(ADULT_SCALE * BABY_SCALE, ADULT_SCALE * BABY_SCALE, ADULT_SCALE * BABY_SCALE);
this.shadowRadius = ADULT_SHADOW_RADIUS * BABY_SCALE;
} else {
poseStack.scale(ADULT_SCALE, ADULT_SCALE, ADULT_SCALE);
this.shadowRadius = ADULT_SHADOW_RADIUS;
}
}
}
@@ -0,0 +1,684 @@
package com.craisinlord.antarchy.content.entity;
import com.craisinlord.antarchy.content.AntarchySoundEvents;
import com.craisinlord.antarchy.content.damage.AntarchyDamageSources;
import net.minecraft.core.BlockPos;
import net.minecraft.tags.FluidTags;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.util.Mth;
import net.minecraft.util.RandomSource;
import net.minecraft.world.DifficultyInstance;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.*;
import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.ai.control.FlyingMoveControl;
import net.minecraft.world.entity.ai.control.SmoothSwimmingMoveControl;
import net.minecraft.world.entity.ai.goal.LookAtPlayerGoal;
import net.minecraft.world.entity.ai.goal.RandomLookAroundGoal;
import net.minecraft.world.entity.ai.goal.target.HurtByTargetGoal;
import net.minecraft.world.entity.ai.navigation.FlyingPathNavigation;
import net.minecraft.world.entity.ai.navigation.PathNavigation;
import net.minecraft.world.entity.ai.navigation.WaterBoundPathNavigation;
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.phys.AABB;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.Nullable;
import software.bernie.geckolib.animatable.GeoEntity;
import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache;
import software.bernie.geckolib.animation.*;
import software.bernie.geckolib.animation.AnimationState;
import software.bernie.geckolib.animation.keyframe.event.builtin.AutoPlayingSoundKeyframeHandler;
import software.bernie.geckolib.util.GeckoLibUtil;
import java.util.List;
import java.util.Objects;
public class OctopusBombEntity extends Monster implements GeoEntity {
private static final EntityDataAccessor<Integer> ATTACK_STATE = SynchedEntityData.defineId(OctopusBombEntity.class, EntityDataSerializers.INT);
private static final EntityDataAccessor<Boolean> ROARING = SynchedEntityData.defineId(OctopusBombEntity.class, EntityDataSerializers.BOOLEAN);
private static final EntityDataAccessor<Integer> ANIMATION_STATE = SynchedEntityData.defineId(OctopusBombEntity.class, EntityDataSerializers.INT);
private static final EntityDataAccessor<Boolean> CAN_FLY = SynchedEntityData.defineId(OctopusBombEntity.class, EntityDataSerializers.BOOLEAN);
private static final String ATTACK_COOLDOWN_KEY = "AttackCooldown";
private static final String ACTION_TICKS_KEY = "ActionTicks";
private static final String LAST_ATTACK_STATE_KEY = "LastAttackState";
private static final String AGGRO_TRIGGERED_KEY = "AggroTriggered";
private static final String GRAB_TARGET_KEY = "GrabTarget";
private static final String CAN_FLY_KEY = "CanFly";
private static final String SPAWNED_BY_KRAKEN_KEY = "SpawnedByKraken";
private static final int ATTACK_NONE = 0;
private static final int ATTACK_GRAB = 1;
private static final int ATTACK_SWIPE = 2;
private static final int ANIM_IDLE = 0;
private static final int ANIM_SWIM = 2;
private static final int ANIM_SWIPE = 3;
private static final int ANIM_GRAB = 4;
private static final int ANIM_DEATH = 5;
private static final int DEATH_ANIM_TICKS = 60;
private static final int INK_SPRAY_RANGE = 6;
private static final int INK_SPRAY_COOLDOWN = 80;
private static final RawAnimation IDLE_ANIM = RawAnimation.begin().thenLoop("idle");
private static final RawAnimation SWIM_ANIM = RawAnimation.begin().thenLoop("swim");
private static final RawAnimation SWIPE_ANIM = RawAnimation.begin().thenPlay("Swipe");
private static final RawAnimation GRAB_ANIM = RawAnimation.begin().thenPlay("Grab");
private static final RawAnimation DEATH_ANIM = RawAnimation.begin().thenPlay("Death");
private final AnimatableInstanceCache geoCache = GeckoLibUtil.createInstanceCache(this);
private float wanderDx, wanderDy, wanderDz;
private int wanderRetargetTicks;
private int attackCooldown;
private int actionTicks;
private int lastAttackState;
private boolean aggroTriggered;
private int grabbedTargetId = -1;
private int strafeRetargetTicks;
private int inkSprayCooldown;
private float orbitDirection = 1.0F;
private boolean spawnedByKraken;
public OctopusBombEntity(EntityType<? extends Monster> entityType, Level level) {
super(entityType, level);
this.moveControl = new SmoothSwimmingMoveControl(this, 80, 8, 0.06F, 0.12F, true);
this.xpReward = 15;
}
public static AttributeSupplier.Builder createAttributes() {
return Mob.createMobAttributes()
.add(Attributes.MAX_HEALTH, 250.0D)
.add(Attributes.ATTACK_DAMAGE, 16.0D)
.add(Attributes.MOVEMENT_SPEED, 0.28D)
.add(Attributes.FLYING_SPEED, 0.28D)
.add(Attributes.FOLLOW_RANGE, 32.0D)
.add(Attributes.KNOCKBACK_RESISTANCE, 0.4D);
}
public static boolean canSpawn(EntityType<OctopusBombEntity> entityType, ServerLevelAccessor level, MobSpawnType spawnReason, BlockPos pos, RandomSource random) {
return level.getFluidState(pos).is(FluidTags.WATER) && level.getFluidState(pos.above()).is(FluidTags.WATER);
}
@Override
protected void defineSynchedData(SynchedEntityData.Builder builder) {
super.defineSynchedData(builder);
builder.define(ATTACK_STATE, ATTACK_NONE);
builder.define(ROARING, false);
builder.define(ANIMATION_STATE, ANIM_IDLE);
builder.define(CAN_FLY, false);
}
@Override
public void onSyncedDataUpdated(EntityDataAccessor<?> key) {
super.onSyncedDataUpdated(key);
if (CAN_FLY.equals(key)) {
this.moveControl = this.canFly()
? new FlyingMoveControl(this, 20, true)
: new SmoothSwimmingMoveControl(this, 80, 8, 0.06F, 0.12F, true);
this.navigation = this.canFly()
? new FlyingPathNavigation(this, this.level())
: new WaterBoundPathNavigation(this, this.level());
}
}
@Override
protected void registerGoals() {
this.goalSelector.addGoal(6, new LookAtPlayerGoal(this, Player.class, 20.0F));
this.goalSelector.addGoal(7, new RandomLookAroundGoal(this));
HurtByTargetGoal hurtByTargetGoal = new HurtByTargetGoal(this);
hurtByTargetGoal.setAlertOthers(MissileSquidEntity.class);
this.targetSelector.addGoal(1, hurtByTargetGoal);
}
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
controllers.add(new AnimationController<>(this, "main_controller", 0, this::mainAnimController)
.setSoundKeyframeHandler(new AutoPlayingSoundKeyframeHandler<>()));
}
private PlayState mainAnimController(AnimationState<OctopusBombEntity> state) {
return switch (this.getAnimationState()) {
case ANIM_GRAB -> state.setAndContinue(GRAB_ANIM);
case ANIM_SWIPE -> state.setAndContinue(SWIPE_ANIM);
case ANIM_SWIM -> state.setAndContinue(SWIM_ANIM);
case ANIM_DEATH -> state.setAndContinue(DEATH_ANIM);
default -> state.setAndContinue(IDLE_ANIM);
};
}
@Override
public AnimatableInstanceCache getAnimatableInstanceCache() {
return this.geoCache;
}
@Override
protected PathNavigation createNavigation(Level level) {
return new WaterBoundPathNavigation(this, level);
}
@Override
public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnReason, @Nullable SpawnGroupData spawnData) {
Objects.requireNonNull(this.getAttribute(Attributes.MAX_HEALTH)).setBaseValue(com.craisinlord.antarchy.config.AntarchySettings.octopusBombHealth());
this.setHealth((float) com.craisinlord.antarchy.config.AntarchySettings.octopusBombHealth());
Objects.requireNonNull(this.getAttribute(Attributes.ATTACK_DAMAGE)).setBaseValue(com.craisinlord.antarchy.config.AntarchySettings.octopusBombAttackDamage());
return super.finalizeSpawn(level, difficulty, spawnReason, spawnData);
}
@Override
public void baseTick() {
int airSupply = this.getAirSupply();
super.baseTick();
if (!this.canFly()) {
this.handleAirSupply(airSupply);
} else {
this.setAirSupply(this.getMaxAirSupply());
}
}
@Override
public void tick() {
super.tick();
this.setNoGravity(this.isInWater() || this.canFly());
if (this.level().isClientSide) {
this.updateSwimRotation();
return;
}
if (this.attackCooldown > 0) {
this.attackCooldown--;
}
if (this.inkSprayCooldown > 0) {
this.inkSprayCooldown--;
}
LivingEntity target = this.getTarget();
this.tickDefensiveInkSpray();
if (target == null || !target.isAlive()) {
this.resetCombatState();
if (this.isInWater()) {
this.tickWanderMovement();
}
this.updateSwimRotation();
this.updateAnimationState();
return;
}
this.getLookControl().setLookAt(target, 25.0F, 20.0F);
if (!this.aggroTriggered) {
this.startAggroRoar();
}
if (this.isRoaring()) {
this.tickRoarState(target);
this.updateSwimRotation();
this.updateAnimationState();
return;
}
if (this.getAttackState() != ATTACK_NONE) {
this.tickCurrentAttack(target);
this.updateSwimRotation();
this.updateAnimationState();
return;
}
this.tickPursuitMovement(target);
if (this.attackCooldown <= 0) {
int nextAttack = this.chooseNextAttack(target);
if (nextAttack != ATTACK_NONE) {
this.startAttack(nextAttack);
}
}
this.updateSwimRotation();
this.updateAnimationState();
}
@Override
public void travel(Vec3 travelVector) {
if (this.isEffectiveAi() && (this.isInWater() || this.canFly())) {
this.moveRelative(this.getSpeed(), travelVector);
this.move(MoverType.SELF, this.getDeltaMovement());
this.setDeltaMovement(this.getDeltaMovement().scale(this.isInWater() ? 0.92D : 0.91D));
return;
}
super.travel(travelVector);
}
@Override
protected boolean shouldDespawnInPeaceful() {
return false;
}
@Override
public boolean removeWhenFarAway(double distanceToClosestPlayer) {
return false;
}
@Override
@Nullable
protected SoundEvent getAmbientSound() {
return null;
}
@Override
protected SoundEvent getHurtSound(DamageSource damageSource) {
return AntarchySoundEvents.KRAKEN_HURT.get();
}
@Override
protected SoundEvent getDeathSound() {
return AntarchySoundEvents.KRAKEN_DEATH.get();
}
@Override
protected float getSoundVolume() {
return 1.2F;
}
@Override
public void addAdditionalSaveData(CompoundTag tag) {
super.addAdditionalSaveData(tag);
tag.putInt(ATTACK_COOLDOWN_KEY, this.attackCooldown);
tag.putInt(ACTION_TICKS_KEY, this.actionTicks);
tag.putInt(LAST_ATTACK_STATE_KEY, this.lastAttackState);
tag.putBoolean(AGGRO_TRIGGERED_KEY, this.aggroTriggered);
tag.putBoolean(CAN_FLY_KEY, this.canFly());
tag.putBoolean(SPAWNED_BY_KRAKEN_KEY, this.spawnedByKraken);
if (this.grabbedTargetId >= 0) {
tag.putInt(GRAB_TARGET_KEY, this.grabbedTargetId);
}
tag.putBoolean("Roaring", this.isRoaring());
tag.putInt("AttackState", this.getAttackState());
tag.putInt("AnimationState", this.getAnimationState());
}
@Override
public void readAdditionalSaveData(CompoundTag tag) {
super.readAdditionalSaveData(tag);
this.attackCooldown = tag.getInt(ATTACK_COOLDOWN_KEY);
this.actionTicks = tag.getInt(ACTION_TICKS_KEY);
this.lastAttackState = tag.contains(LAST_ATTACK_STATE_KEY) ? tag.getInt(LAST_ATTACK_STATE_KEY) : ATTACK_NONE;
this.aggroTriggered = tag.getBoolean(AGGRO_TRIGGERED_KEY);
this.setCanFly(tag.getBoolean(CAN_FLY_KEY));
this.spawnedByKraken = tag.getBoolean(SPAWNED_BY_KRAKEN_KEY);
this.grabbedTargetId = tag.contains(GRAB_TARGET_KEY) ? tag.getInt(GRAB_TARGET_KEY) : -1;
this.entityData.set(ROARING, tag.getBoolean("Roaring"));
this.entityData.set(ATTACK_STATE, tag.getInt("AttackState"));
this.entityData.set(ANIMATION_STATE, tag.contains("AnimationState") ? tag.getInt("AnimationState") : ANIM_IDLE);
this.updateAnimationState();
}
public boolean isRoaring() {
return this.entityData.get(ROARING);
}
public boolean canFly() {
return this.entityData.get(CAN_FLY);
}
public int getAttackState() {
return this.entityData.get(ATTACK_STATE);
}
public int getAnimationState() {
return this.entityData.get(ANIMATION_STATE);
}
private void setRoaring(boolean roaring) {
this.entityData.set(ROARING, roaring);
}
public void setCanFly(boolean canFly) {
this.entityData.set(CAN_FLY, canFly);
}
public void launchAsProjectile(net.minecraft.world.entity.Entity owner, net.minecraft.world.phys.Vec3 velocity) {
this.spawnedByKraken = true;
this.setCanFly(true);
this.setDeltaMovement(velocity);
}
private void setAttackState(int attackState) {
this.entityData.set(ATTACK_STATE, attackState);
}
private void setAnimationState(int animationState) {
this.entityData.set(ANIMATION_STATE, animationState);
}
private void startAggroRoar() {
this.aggroTriggered = true;
this.actionTicks = 30;
this.setRoaring(true);
this.playSound(AntarchySoundEvents.KRAKEN_ROAR.get(), 1.4F, 1.07F);
this.getNavigation().stop();
this.setDeltaMovement(this.getDeltaMovement().scale(0.2D));
this.updateAnimationState();
}
private void tickRoarState(LivingEntity target) {
this.getNavigation().stop();
this.getMoveControl().setWantedPosition(this.getX(), this.getY(), this.getZ(), 0.0D);
this.setDeltaMovement(this.getDeltaMovement().scale(0.6D));
this.getLookControl().setLookAt(target, 25.0F, 20.0F);
if (--this.actionTicks <= 0) {
this.actionTicks = 0;
this.setRoaring(false);
this.attackCooldown = 18;
}
}
private void tickCurrentAttack(LivingEntity target) {
this.getNavigation().stop();
this.getLookControl().setLookAt(target, 30.0F, 25.0F);
this.setDeltaMovement(this.getDeltaMovement().scale(0.8D));
switch (this.getAttackState()) {
case ATTACK_GRAB -> this.tickGrabAttack(target);
case ATTACK_SWIPE -> this.tickSwipeAttack();
default -> this.finishAttack();
}
}
private void startAttack(int attackState) {
this.setAttackState(attackState);
this.grabbedTargetId = -1;
if (attackState == ATTACK_GRAB) {
this.actionTicks = 55;
this.playSound(AntarchySoundEvents.KRAKEN_ATTACK.get(), 1.2F, 1.07F);
} else if (attackState == ATTACK_SWIPE) {
this.actionTicks = 40;
this.playSound(AntarchySoundEvents.KRAKEN_SPIN.get(), 1.1F, 1.13F);
}
}
private void tickGrabAttack(LivingEntity target) {
if (this.actionTicks == 48 && this.distanceToSqr(target) <= 42.25D) {
this.grabbedTargetId = target.getId();
}
LivingEntity grabbedTarget = this.getGrabbedTarget();
if (grabbedTarget != null && grabbedTarget.isAlive()) {
this.holdGrabbedTarget(grabbedTarget);
if (this.actionTicks <= 45 && this.actionTicks > 10 && this.actionTicks % 10 == 0) {
if (this.level() instanceof ServerLevel serverLevel) {
grabbedTarget.hurt(AntarchyDamageSources.krakenMauling(serverLevel, this), 4.0F);
}
}
}
if (--this.actionTicks <= 0) {
if (grabbedTarget != null && grabbedTarget.isAlive()) {
this.pullDown(grabbedTarget, 2.5D);
}
this.grabbedTargetId = -1;
this.finishAttack();
}
}
private void tickSwipeAttack() {
if (this.actionTicks == 10) {
this.performSwipe();
}
if (--this.actionTicks <= 0) {
this.finishAttack();
}
}
private void finishAttack() {
int finished = this.getAttackState();
this.setAttackState(ATTACK_NONE);
this.actionTicks = 0;
this.attackCooldown = 18;
this.grabbedTargetId = -1;
this.lastAttackState = finished;
this.updateAnimationState();
}
private void tickPursuitMovement(LivingEntity target) {
if (this.strafeRetargetTicks-- <= 0) {
this.strafeRetargetTicks = 10 + this.random.nextInt(12);
if (this.random.nextFloat() < 0.4F) {
this.orbitDirection *= -1.0F;
}
}
Vec3 attackPoint = this.createCombatTarget(target);
this.getMoveControl().setWantedPosition(attackPoint.x, attackPoint.y, attackPoint.z, 1.1D);
}
private void resetCombatState() {
this.setAttackState(ATTACK_NONE);
this.setRoaring(false);
this.setTarget(null);
this.actionTicks = 0;
this.grabbedTargetId = -1;
this.aggroTriggered = false;
this.updateAnimationState();
}
private void handleAirSupply(int previousAirSupply) {
if (this.isInWaterOrBubble()) {
this.setAirSupply(this.getMaxAirSupply());
return;
}
this.setAirSupply(previousAirSupply - 1);
if (this.getAirSupply() <= -20) {
this.setAirSupply(0);
this.hurt(this.damageSources().drown(), 2.0F);
}
}
private void tickDefensiveInkSpray() {
if (this.inkSprayCooldown > 0 || !(this.level() instanceof ServerLevel serverLevel)) {
return;
}
Player nearbyPlayer = this.level().getNearestPlayer(this, INK_SPRAY_RANGE);
if (nearbyPlayer == null || nearbyPlayer.isCreative() || nearbyPlayer.isSpectator()) {
return;
}
this.inkSprayCooldown = INK_SPRAY_COOLDOWN;
this.playSound(AntarchySoundEvents.KRAKEN_HURT.get(), 1.0F, 1.49F);
double centerY = this.getY() + this.getBbHeight() * 0.5D;
serverLevel.sendParticles(ParticleTypes.SQUID_INK, this.getX(), centerY, this.getZ(), 55, 1.2D, 0.8D, 1.2D, 0.02D);
serverLevel.sendParticles(ParticleTypes.SQUID_INK, this.getX(), centerY, this.getZ(), 35, 2.0D, 1.1D, 2.0D, 0.01D);
}
private int chooseNextAttack(LivingEntity target) {
double distSqr = this.distanceToSqr(target);
boolean canGrab = distSqr <= 42.25D;
boolean canSwipe = distSqr <= 81.0D && this.isTargetInFront(target, -0.15D);
if (!canGrab && !canSwipe) {
return ATTACK_NONE;
}
int grabWeight = canGrab ? (this.lastAttackState == ATTACK_GRAB ? 1 : 4) : 0;
int swipeWeight = canSwipe ? (this.lastAttackState == ATTACK_SWIPE ? 1 : 5) : 0;
int total = grabWeight + swipeWeight;
if (total == 0) return ATTACK_NONE;
int roll = this.random.nextInt(total);
if (roll < grabWeight) return ATTACK_GRAB;
return ATTACK_SWIPE;
}
private void performSwipe() {
AABB hitBox = this.getBoundingBox().inflate(7.0D, 3.0D, 7.0D);
List<Player> players = this.level().getEntitiesOfClass(Player.class, hitBox, player -> player.isAlive() && this.isTargetInFront(player, -0.15D));
float damage = (float) this.getAttributeValue(Attributes.ATTACK_DAMAGE);
for (Player player : players) {
if (this.level() instanceof ServerLevel serverLevel) {
player.hurt(AntarchyDamageSources.krakenMauling(serverLevel, this), damage);
Vec3 direction = player.position().subtract(this.position());
Vec3 horizontal = new Vec3(direction.x, 0.0D, direction.z).normalize().scale(1.75D);
player.push(horizontal.x, 0.3D, horizontal.z);
player.hurtMarked = true;
}
}
}
private void holdGrabbedTarget(LivingEntity target) {
Vec3 anchor = this.position().add(0.0D, -this.getBbHeight() * 0.4D, 0.0D);
target.setDeltaMovement(anchor.subtract(target.position()).scale(0.35D));
target.resetFallDistance();
if (target instanceof ServerPlayer serverPlayer) {
serverPlayer.connection.teleport(anchor.x, anchor.y, anchor.z, target.getYRot(), target.getXRot());
} else {
target.moveTo(anchor.x, anchor.y, anchor.z, target.getYRot(), target.getXRot());
}
target.hurtMarked = true;
}
private void pullDown(LivingEntity target, double downwardStrength) {
target.push(0.0D, -downwardStrength, 0.0D);
target.hurtMarked = true;
}
@Nullable
private LivingEntity getGrabbedTarget() {
if (this.grabbedTargetId < 0) {
return null;
}
net.minecraft.world.entity.Entity entity = this.level().getEntity(this.grabbedTargetId);
return entity instanceof LivingEntity livingEntity ? livingEntity : null;
}
private boolean isTargetInFront(LivingEntity target, double minimumDot) {
Vec3 forward = this.getViewVector(1.0F);
Vec3 toTarget = target.position().subtract(this.position()).normalize();
return forward.dot(toTarget) >= minimumDot;
}
private Vec3 createCombatTarget(LivingEntity target) {
double radius = 9.0D;
double angle = this.tickCount * 0.16D * this.orbitDirection + this.getId() * 0.11D;
double x = target.getX() + Math.cos(angle) * radius;
double z = target.getZ() + Math.sin(angle) * radius;
double y = Mth.clamp(
target.getY() + 1.0D + Math.sin((this.tickCount + this.getId()) * 0.18D),
target.getY() - 3.0D,
target.getY() + 4.0D
);
return new Vec3(x, y, z);
}
private void updateSwimRotation() {
Vec3 velocity = this.getDeltaMovement();
if (velocity.horizontalDistanceSqr() > 1.0E-4D) {
float targetYaw = (float) (Mth.atan2(velocity.z, velocity.x) * (180.0D / Math.PI)) - 90.0F;
this.setYRot(Mth.approachDegrees(this.getYRot(), targetYaw, 6.0F));
this.yBodyRot = this.getYRot();
this.yHeadRot = this.getYRot();
}
if (velocity.lengthSqr() > 1.0E-4D) {
float targetPitch = (float) (-(Mth.atan2(velocity.y, velocity.horizontalDistance()) * (180.0D / Math.PI)));
this.setXRot(Mth.approachDegrees(this.getXRot(), targetPitch, 4.0F));
}
}
@Override
public void die(DamageSource damageSource) {
if (!this.level().isClientSide) {
this.setAnimationState(ANIM_DEATH);
this.actionTicks = 0;
this.attackCooldown = 0;
this.setAttackState(ATTACK_NONE);
this.setRoaring(false);
this.setDeltaMovement(Vec3.ZERO);
this.getNavigation().stop();
}
super.die(damageSource);
}
@Override
protected void tickDeath() {
this.deathTime++;
if (this.deathTime == 1) {
this.setAnimationState(ANIM_DEATH);
}
if (this.deathTime >= DEATH_ANIM_TICKS) {
this.remove(RemovalReason.KILLED);
this.dropExperience(this);
}
}
private void updateAnimationState() {
if (this.isDeadOrDying()) {
this.setAnimationState(ANIM_DEATH);
return;
}
if (this.isRoaring()) {
this.setAnimationState(ANIM_IDLE);
return;
}
switch (this.getAttackState()) {
case ATTACK_GRAB -> {
this.setAnimationState(ANIM_GRAB);
return;
}
case ATTACK_SWIPE -> {
this.setAnimationState(ANIM_SWIPE);
return;
}
default -> {
}
}
if (!this.isInWater()) {
this.setAnimationState(ANIM_SWIM);
return;
}
Vec3 velocity = this.getDeltaMovement();
double horizontalSpeedSqr = velocity.horizontalDistanceSqr();
double verticalSpeedSqr = velocity.y * velocity.y;
if (horizontalSpeedSqr > 0.03D && horizontalSpeedSqr > verticalSpeedSqr * 2.5D) {
this.setAnimationState(ANIM_SWIM);
return;
}
this.setAnimationState(ANIM_IDLE);
}
private void tickWanderMovement() {
if (--this.wanderRetargetTicks <= 0) {
this.wanderRetargetTicks = 40 + this.random.nextInt(40);
float angle = this.random.nextFloat() * (float) (Math.PI * 2);
this.wanderDx = Mth.cos(angle) * 0.1f;
this.wanderDy = -0.05f + this.random.nextFloat() * 0.1f;
this.wanderDz = Mth.sin(angle) * 0.1f;
}
this.setDeltaMovement(this.getDeltaMovement().add(this.wanderDx, this.wanderDy, this.wanderDz));
}
}
@@ -7,8 +7,6 @@ import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.RandomSource;
import net.minecraft.world.Difficulty;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.tags.EntityTypeTags;
import net.minecraft.world.entity.AgeableMob;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.Mob;
@@ -37,9 +35,12 @@ import software.bernie.geckolib.util.GeckoLibUtil;
public class StinkBugEntity extends Animal implements GeoEntity {
private static final RawAnimation IDLE_ANIM = RawAnimation.begin().thenLoop("idle");
private static final RawAnimation WALK_ANIM = RawAnimation.begin().thenLoop("walk");
private static final RawAnimation FART_ANIM = RawAnimation.begin().thenPlay("fart");
private static final int FART_ANIMATION_TICKS = 30;
private static final int STINK_BURST_PARTICLES = 32;
private final AnimatableInstanceCache geoCache = GeckoLibUtil.createInstanceCache(this);
private int fartAnimationTicks;
public StinkBugEntity(EntityType<? extends StinkBugEntity> entityType, Level level) {
super(entityType, level);
@@ -73,18 +74,8 @@ public class StinkBugEntity extends Animal implements GeoEntity {
public void tick() {
super.tick();
if (this.level().isClientSide || this.tickCount % 10 != 0) {
return;
}
for (var target : this.level().getEntitiesOfClass(
net.minecraft.world.entity.LivingEntity.class,
this.getBoundingBox().inflate(StinkyBehavior.STINK_BUG_AURA_RADIUS),
entity -> entity != this
&& entity.isAlive()
&& !entity.getType().is(EntityTypeTags.SENSITIVE_TO_BANE_OF_ARTHROPODS)
)) {
target.addEffect(new MobEffectInstance(AntarchyObjects.STINKY_EFFECT.get(), StinkyBehavior.STINKY_EFFECT_DURATION_TICKS, 0, false, true, true));
if (this.fartAnimationTicks > 0) {
this.fartAnimationTicks--;
}
}
@@ -92,6 +83,7 @@ public class StinkBugEntity extends Animal implements GeoEntity {
public boolean hurt(DamageSource source, float amount) {
boolean hurt = super.hurt(source, amount);
if (hurt) {
this.triggerFartAnimation();
StinkyBehavior.emitBurst(this, STINK_BURST_PARTICLES);
}
return hurt;
@@ -119,7 +111,15 @@ public class StinkBugEntity extends Animal implements GeoEntity {
}
private <T extends StinkBugEntity> PlayState mainAnimController(AnimationState<T> animationState) {
if (this.fartAnimationTicks > 0) {
animationState.setAnimation(FART_ANIM);
return PlayState.CONTINUE;
}
animationState.setAnimation(animationState.isMoving() ? WALK_ANIM : IDLE_ANIM);
return PlayState.CONTINUE;
}
private void triggerFartAnimation() {
this.fartAnimationTicks = FART_ANIMATION_TICKS;
}
}
@@ -63,9 +63,11 @@ public class ToreterrorEntity extends Monster implements GeoEntity {
private static final int ANIM_WALK = 1;
private static final int ANIM_SHOOT = 2;
private static final int ANIM_JUMP_ATTACK = 3;
private static final int ANIM_SPIN = 4;
private static final int ANIM_DEATH = 5;
private static final int ANIM_RAPID_SHOOT = 6;
private static final int ANIM_SPIN_START = 4;
private static final int ANIM_SPIN_LOOP = 5;
private static final int ANIM_SPIN_END = 6;
private static final int ANIM_DEATH = 7;
private static final int ANIM_RAPID_SHOOT = 8;
private static final int ATTACK_RAPID_FIRE = 0;
private static final int ATTACK_HUGE_BOMB = 1;
@@ -81,15 +83,21 @@ public class ToreterrorEntity extends Monster implements GeoEntity {
private static final int JUMP_TOTAL_TICKS = 40;
private static final int JUMP_LAUNCH_TICK = 10;
private static final int JUMP_SHAKE_TICKS = 25;
private static final int SPIN_TOTAL_TICKS = 40;
private static final int SPIN_START_TICK = 3;
private static final int SPIN_END_TICK = 22;
private static final int SPIN_START_TOTAL_TICKS = 5;
private static final int SPIN_LOOP_MIN_TICKS = 200;
private static final int SPIN_LOOP_MAX_TICKS = 300;
private static final int SPIN_END_TOTAL_TICKS = 10;
private static final int SPIN_HIT_INTERVAL = 5;
private static final int SPIN_STUCK_FAIL_LIMIT = 10;
private static final double CLOSE_RANGE_SQR = 64.0D;
private static final double JUMP_RANGE_SQR = 400.0D;
private static final double RANGED_MAX_RANGE_SQR = 625.0D;
private static final double SPIN_TRIGGER_RANGE_SQR = 225.0D;
private static final double SPIN_LEASH_RANGE_SQR = 225.0D;
private static final double SPIN_RADIUS = 4.5D;
private static final double SPIN_MOVE_SPEED = 1.7D;
private static final double SPIN_ANIMATION_SPEED = 0.7D;
private static final double JUMP_SHOCKWAVE_RADIUS = 6.0D;
private static final RawAnimation IDLE_ANIM = RawAnimation.begin().thenLoop("Idle");
@@ -97,7 +105,9 @@ public class ToreterrorEntity extends Monster implements GeoEntity {
private static final RawAnimation SHOOT_ANIM = RawAnimation.begin().thenPlay("shoot").thenLoop("Idle");
private static final RawAnimation RAPID_SHOOT_ANIM = RawAnimation.begin().thenLoop("shoot");
private static final RawAnimation JUMP_ANIM = RawAnimation.begin().thenPlay("jump_attack").thenLoop("Idle");
private static final RawAnimation SPIN_ANIM = RawAnimation.begin().thenPlay("spin_attack").thenLoop("Idle");
private static final RawAnimation SPIN_START_ANIM = RawAnimation.begin().thenPlay("spin_attack_start");
private static final RawAnimation SPIN_LOOP_ANIM = RawAnimation.begin().thenLoop("spin_attack");
private static final RawAnimation SPIN_END_ANIM = RawAnimation.begin().thenPlay("spin_attack_end");
private static final RawAnimation DEATH_ANIM = RawAnimation.begin().thenPlayAndHold("death");
private final AnimatableInstanceCache geoCache = GeckoLibUtil.createInstanceCache(this);
@@ -105,7 +115,10 @@ public class ToreterrorEntity extends Monster implements GeoEntity {
private int shootAnimTicks;
private int jumpAnimTicks;
private int spinAnimTicks;
private int spinStartTicks;
private int spinLoopTicks;
private int spinEndTicks;
private int spinLoopTotalTicks;
private int shootCooldown;
private int jumpCooldown;
private int spinCooldown;
@@ -116,6 +129,9 @@ public class ToreterrorEntity extends Monster implements GeoEntity {
private boolean shootBomberFired;
private boolean shootBomberFiredSecond;
private int rapidFireNextTick;
private Vec3 spinDirection = Vec3.ZERO;
private int spinStrafeSign = 1;
private int spinStuckTicks;
private final Map<UUID, Integer> spinHitCooldowns = new HashMap<>();
public ToreterrorEntity(EntityType<? extends ToreterrorEntity> entityType, Level level) {
@@ -166,12 +182,18 @@ public class ToreterrorEntity extends Monster implements GeoEntity {
private PlayState mainAnimController(AnimationState<ToreterrorEntity> state) {
int animState = this.getAnimationState();
state.getController().setAnimationSpeed(1.0D);
return switch (animState) {
case ANIM_WALK -> state.setAndContinue(WALK_ANIM);
case ANIM_SHOOT -> state.setAndContinue(SHOOT_ANIM);
case ANIM_RAPID_SHOOT -> state.setAndContinue(RAPID_SHOOT_ANIM);
case ANIM_JUMP_ATTACK -> state.setAndContinue(JUMP_ANIM);
case ANIM_SPIN -> state.setAndContinue(SPIN_ANIM);
case ANIM_SPIN_START -> state.setAndContinue(SPIN_START_ANIM);
case ANIM_SPIN_LOOP -> {
state.getController().setAnimationSpeed(SPIN_ANIMATION_SPEED);
yield state.setAndContinue(SPIN_LOOP_ANIM);
}
case ANIM_SPIN_END -> state.setAndContinue(SPIN_END_ANIM);
case ANIM_DEATH -> state.setAndContinue(DEATH_ANIM);
default -> state.setAndContinue(IDLE_ANIM);
};
@@ -209,8 +231,8 @@ public class ToreterrorEntity extends Monster implements GeoEntity {
this.tickShootAnimation();
} else if (this.jumpAnimTicks > 0) {
this.tickJumpAnimation();
} else if (this.spinAnimTicks > 0) {
this.tickSpinAnimation();
} else if (this.isSpinSequenceActive()) {
this.tickSpinSequence();
} else {
this.updateIdleAnimation();
}
@@ -242,7 +264,6 @@ public class ToreterrorEntity extends Monster implements GeoEntity {
private void enterPhase2() {
this.entityData.set(PHASE_2, true);
this.bossEvent.setColor(BossEvent.BossBarColor.RED);
}
public boolean isPhase2() {
@@ -303,7 +324,7 @@ public class ToreterrorEntity extends Monster implements GeoEntity {
this.setAnimationState(ANIM_DEATH);
this.shootAnimTicks = 0;
this.jumpAnimTicks = 0;
this.spinAnimTicks = 0;
this.stopSpinSequence();
this.setDeltaMovement(Vec3.ZERO);
this.getNavigation().stop();
}
@@ -339,7 +360,11 @@ public class ToreterrorEntity extends Monster implements GeoEntity {
}
private boolean isInAttackAnimation() {
return this.shootAnimTicks > 0 || this.jumpAnimTicks > 0 || this.spinAnimTicks > 0;
return this.shootAnimTicks > 0 || this.jumpAnimTicks > 0 || this.isSpinSequenceActive();
}
private boolean isSpinSequenceActive() {
return this.spinStartTicks > 0 || this.spinLoopTicks > 0 || this.spinEndTicks > 0;
}
private void tickShootAnimation() {
@@ -405,21 +430,220 @@ public class ToreterrorEntity extends Monster implements GeoEntity {
}
}
private void tickSpinAnimation() {
this.setAnimationState(ANIM_SPIN);
int elapsed = SPIN_TOTAL_TICKS - this.spinAnimTicks;
private void tickSpinSequence() {
this.getNavigation().stop();
this.setDeltaMovement(this.getDeltaMovement().multiply(0.7D, 1.0D, 0.7D));
if (elapsed >= SPIN_START_TICK && elapsed <= SPIN_END_TICK && elapsed % SPIN_HIT_INTERVAL == 0) {
if (this.spinStartTicks > 0) {
this.tickSpinStart();
return;
}
if (this.spinLoopTicks > 0) {
this.tickSpinLoop();
return;
}
this.tickSpinEnd();
}
private void tickSpinStart() {
this.setAnimationState(ANIM_SPIN_START);
this.setDeltaMovement(this.getDeltaMovement().scale(0.75D));
LivingEntity target = this.getTarget();
if (target != null) {
Vec3 towardTarget = horizontalDirectionTo(target.position());
if (towardTarget.lengthSqr() > 1.0E-4D) {
this.spinDirection = towardTarget;
this.lookInDirection(towardTarget);
}
}
this.spinStartTicks--;
}
private void tickSpinLoop() {
this.setAnimationState(ANIM_SPIN_LOOP);
LivingEntity target = this.getTarget();
if (target == null || !target.isAlive()) {
this.beginSpinEnd();
return;
}
this.updateSpinDirection(target);
if (!this.moveDuringSpin()) {
this.spinStuckTicks++;
if (this.spinStuckTicks >= SPIN_STUCK_FAIL_LIMIT) {
this.beginSpinEnd();
return;
}
} else {
this.spinStuckTicks = 0;
}
int elapsed = this.spinLoopTotalTicks - this.spinLoopTicks;
if (elapsed % SPIN_HIT_INTERVAL == 0) {
this.applySpinDamage();
}
this.spinAnimTicks--;
if (this.spinAnimTicks <= 0) {
this.spinCooldown = 160 + this.random.nextInt(80);
this.lookInDirection(this.spinDirection);
this.spinLoopTicks--;
if (this.spinLoopTicks <= 0) {
this.beginSpinEnd();
}
}
private void tickSpinEnd() {
this.setAnimationState(ANIM_SPIN_END);
this.setDeltaMovement(this.getDeltaMovement().multiply(0.7D, 1.0D, 0.7D));
this.spinEndTicks--;
if (this.spinEndTicks <= 0) {
this.stopSpinSequence();
this.spinCooldown = 260 + this.random.nextInt(80);
this.spinHitCooldowns.clear();
}
}
private void updateSpinDirection(LivingEntity target) {
Vec3 towardTarget = horizontalDirectionTo(target.position());
if (towardTarget.lengthSqr() <= 1.0E-4D) {
return;
}
if (this.distanceToSqr(target) > SPIN_LEASH_RANGE_SQR) {
this.spinDirection = towardTarget;
return;
}
Vec3 forward = this.spinDirection.lengthSqr() > 1.0E-4D ? this.spinDirection.normalize() : towardTarget;
Vec3 strafe = new Vec3(-towardTarget.z, 0.0D, towardTarget.x).scale(this.spinStrafeSign);
Vec3 combined = forward.scale(1.2D).add(towardTarget.scale(0.15D)).add(strafe.scale(1.35D));
this.spinDirection = combined.lengthSqr() > 1.0E-4D ? combined.normalize() : towardTarget;
}
private boolean moveDuringSpin() {
Vec3 direction = this.spinDirection.lengthSqr() > 1.0E-4D ? this.spinDirection.normalize() : Vec3.ZERO;
if (direction == Vec3.ZERO) {
return false;
}
if (this.trySpinMoves(direction, false)) {
return true;
}
this.spinStrafeSign *= -1;
Vec3 bounced = rotateHorizontal(direction, this.spinStrafeSign * 35.0D);
if (this.trySpinMoves(bounced, true)) {
return true;
}
Vec3 reversed = direction.scale(-1.0D);
if (this.trySpinMoves(reversed, true)) {
return true;
}
Vec3 reversedBounce = rotateHorizontal(reversed, this.spinStrafeSign * 25.0D);
return this.trySpinMoves(reversedBounce, true);
}
private boolean trySpinMoves(Vec3 baseDirection, boolean bounced) {
Vec3[] attempts = new Vec3[]{
baseDirection,
rotateHorizontal(baseDirection, 28.0D * this.spinStrafeSign),
rotateHorizontal(baseDirection, -28.0D * this.spinStrafeSign),
rotateHorizontal(baseDirection, 52.0D * this.spinStrafeSign),
rotateHorizontal(baseDirection, -52.0D * this.spinStrafeSign)
};
for (Vec3 attempt : attempts) {
if (this.trySpinMove(attempt, 0.0D, 0.0D) || this.trySpinMove(attempt, 1.0D, 0.42D) || this.trySpinMove(attempt, -1.0D, -0.28D)) {
this.spinDirection = attempt.normalize();
if (bounced) {
this.spinStrafeSign *= -1;
}
return true;
}
}
return false;
}
private boolean trySpinMove(Vec3 direction, double yOffset, double verticalVelocity) {
Vec3 horizontalMove = new Vec3(direction.x * SPIN_MOVE_SPEED, 0.0D, direction.z * SPIN_MOVE_SPEED);
AABB movedBox = this.getBoundingBox().move(horizontalMove.x, yOffset, horizontalMove.z);
if (!this.level().noCollision(this, movedBox)) {
return false;
}
if (!this.hasSpinSupport(movedBox)) {
return false;
}
this.setDeltaMovement(horizontalMove.x, verticalVelocity, horizontalMove.z);
this.hasImpulse = true;
return true;
}
private boolean hasSpinSupport(AABB box) {
double probeY = box.minY - 0.2D;
double[][] probes = new double[][]{
{box.getCenter().x, box.getCenter().z},
{box.minX + 0.25D, box.minZ + 0.25D},
{box.minX + 0.25D, box.maxZ - 0.25D},
{box.maxX - 0.25D, box.minZ + 0.25D},
{box.maxX - 0.25D, box.maxZ - 0.25D}
};
for (double[] probe : probes) {
BlockPos supportPos = BlockPos.containing(probe[0], probeY, probe[1]);
if (this.level().loadedAndEntityCanStandOnFace(supportPos, this, Direction.UP)) {
return true;
}
BlockPos lowerSupportPos = supportPos.below();
if (this.level().loadedAndEntityCanStandOnFace(lowerSupportPos, this, Direction.UP)) {
return true;
}
}
return false;
}
private Vec3 horizontalDirectionTo(Vec3 targetPos) {
Vec3 diff = targetPos.subtract(this.position());
Vec3 horizontal = new Vec3(diff.x, 0.0D, diff.z);
return horizontal.lengthSqr() > 1.0E-4D ? horizontal.normalize() : Vec3.ZERO;
}
private void lookInDirection(Vec3 direction) {
if (direction.lengthSqr() <= 1.0E-4D) {
return;
}
float yaw = (float) (net.minecraft.util.Mth.atan2(direction.z, direction.x) * (180.0D / Math.PI)) - 90.0F;
this.setYRot(yaw);
this.yBodyRot = yaw;
this.yHeadRot = yaw;
this.setYHeadRot(yaw);
}
private static Vec3 rotateHorizontal(Vec3 direction, double degrees) {
if (direction.lengthSqr() <= 1.0E-4D) {
return Vec3.ZERO;
}
double radians = Math.toRadians(degrees);
double cos = Math.cos(radians);
double sin = Math.sin(radians);
double x = direction.x * cos - direction.z * sin;
double z = direction.x * sin + direction.z * cos;
return new Vec3(x, 0.0D, z).normalize();
}
private void beginSpinEnd() {
this.spinStartTicks = 0;
this.spinLoopTicks = 0;
if (this.spinEndTicks <= 0) {
this.spinEndTicks = SPIN_END_TOTAL_TICKS;
}
}
private void stopSpinSequence() {
this.spinStartTicks = 0;
this.spinLoopTicks = 0;
this.spinEndTicks = 0;
this.spinLoopTotalTicks = 0;
this.spinDirection = Vec3.ZERO;
this.spinStrafeSign = 1;
this.spinStuckTicks = 0;
}
private Vec3 calcLaunchVelocity(Vec3 from, Vec3 to, double minSpeed) {
Vec3 diff = to.subtract(from);
double dh = Math.sqrt(diff.x * diff.x + diff.z * diff.z);
@@ -618,22 +842,32 @@ public class ToreterrorEntity extends Monster implements GeoEntity {
LivingEntity target = ToreterrorEntity.this.getTarget();
if (target == null || ToreterrorEntity.this.isInAttackAnimation()) return false;
if (ToreterrorEntity.this.spinCooldown > 0) return false;
return ToreterrorEntity.this.distanceToSqr(target) <= CLOSE_RANGE_SQR && ToreterrorEntity.this.onGround();
return ToreterrorEntity.this.distanceToSqr(target) <= SPIN_TRIGGER_RANGE_SQR && ToreterrorEntity.this.onGround();
}
@Override
public void start() {
ToreterrorEntity.this.spinAnimTicks = SPIN_TOTAL_TICKS;
LivingEntity target = ToreterrorEntity.this.getTarget();
ToreterrorEntity.this.spinStartTicks = SPIN_START_TOTAL_TICKS;
ToreterrorEntity.this.spinLoopTotalTicks = SPIN_LOOP_MIN_TICKS + ToreterrorEntity.this.random.nextInt(SPIN_LOOP_MAX_TICKS - SPIN_LOOP_MIN_TICKS + 1);
ToreterrorEntity.this.spinLoopTicks = ToreterrorEntity.this.spinLoopTotalTicks;
ToreterrorEntity.this.spinEndTicks = 0;
ToreterrorEntity.this.spinStuckTicks = 0;
ToreterrorEntity.this.spinStrafeSign = ToreterrorEntity.this.random.nextBoolean() ? 1 : -1;
ToreterrorEntity.this.spinHitCooldowns.clear();
ToreterrorEntity.this.spinDirection = target == null
? Vec3.ZERO
: ToreterrorEntity.this.horizontalDirectionTo(target.position());
}
@Override
public boolean canContinueToUse() {
return ToreterrorEntity.this.spinAnimTicks > 0;
return ToreterrorEntity.this.isSpinSequenceActive();
}
@Override
public void stop() {
ToreterrorEntity.this.spinAnimTicks = 0;
ToreterrorEntity.this.stopSpinSequence();
}
}
}
@@ -5,8 +5,9 @@ import com.craisinlord.antarchy.content.AntarchyObjects;
import com.craisinlord.antarchy.content.AntarchySoundEvents;
import com.craisinlord.antarchy.content.damage.AntarchyDamageSources;
import com.craisinlord.antarchy.content.entity.MissileSquidEntity;
import com.craisinlord.antarchy.content.entity.OctopusBombEntity;
import com.craisinlord.antarchy.content.damage.AntarchyDamageTypes;
import java.util.List;
import java.util.Objects;
import net.minecraft.core.BlockPos;
@@ -68,24 +69,28 @@ public class KrakenEntity extends Monster implements GeoEntity {
private static final String ATTACK_COOLDOWN_KEY = "AttackCooldown";
private static final String ACTION_TICKS_KEY = "ActionTicks";
private static final String PHASE_TRANSITION_TICKS_KEY = "PhaseTransitionTicks";
private static final String NEXT_ATTACK_INDEX_KEY = "NextAttackIndex";
private static final String SLAM_COOLDOWN_KEY = "SlamCooldown";
private static final String PHASE_SUMMON_COOLDOWN_KEY = "PhaseSummonCooldown";
private static final String LAST_ATTACK_STATE_KEY = "LastAttackState";
private static final String AGGRO_TRIGGERED_KEY = "AggroTriggered";
private static final String GRAB_TARGET_KEY = "GrabTarget";
private static final double BOSS_BAR_RANGE = 40.0D;
private static final int ATTACK_NONE = 0;
private static final int ATTACK_GRAB = 1;
private static final int ATTACK_SWIPE = 2;
private static final int ATTACK_SLAM = 3;
private static final int ANIM_IDLE = 0;
private static final int ANIM_IDLE_TWO = 1;
private static final int ANIM_SWIM = 2;
private static final int ANIM_SWIPE = 3;
private static final int ANIM_GRAB = 4;
private static final int ATTACK_SWING_LEFT = 2;
private static final int ATTACK_SWING_RIGHT = 3;
// Synced animation state values
private static final int ANIM_NONE = 0;
private static final int ANIM_CRY = 1;
private static final int ANIM_GRAB = 2;
private static final int ANIM_SWING_LEFT = 3;
private static final int ANIM_SWING_RIGHT = 4;
private static final int ANIM_DEATH = 5;
private static final int DEATH_ANIM_TICKS = 60;
private static final ResourceLocation PHASE_TWO_SPEED_ID = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "kraken_phase_two_speed");
private static final ResourceLocation PHASE_TWO_FLYING_SPEED_ID = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "kraken_phase_two_flying_speed");
private static final ResourceLocation PHASE_TWO_DAMAGE_ID = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "kraken_phase_two_damage");
@@ -96,21 +101,21 @@ public class KrakenEntity extends Monster implements GeoEntity {
private static final AttributeModifier PHASE_TWO_DAMAGE = new AttributeModifier(PHASE_TWO_DAMAGE_ID, PHASE_TWO_DAMAGE_BONUS, AttributeModifier.Operation.ADD_VALUE);
private static final RawAnimation IDLE_ANIM = RawAnimation.begin().thenLoop("idle");
private static final RawAnimation SWIM_ANIM = RawAnimation.begin().thenLoop("swim");
private static final RawAnimation SWIPE_ANIM = RawAnimation.begin().thenPlay("Swipe");
private static final RawAnimation GRAB_ANIM = RawAnimation.begin().thenPlay("Grab");
private static final RawAnimation DEATH_ANIM = RawAnimation.begin().thenPlay("Death");
private static final RawAnimation CRY_ANIM = RawAnimation.begin().thenPlay("cry");
private static final RawAnimation GRAB_ANIM = RawAnimation.begin().thenPlay("grab");
private static final RawAnimation SWING_LEFT_ANIM = RawAnimation.begin().thenPlay("swing_left");
private static final RawAnimation SWING_RIGHT_ANIM = RawAnimation.begin().thenPlay("swing_right");
private static final RawAnimation DEATH_ANIM = RawAnimation.begin().thenPlay("death");
private final ServerBossEvent bossEvent = new ServerBossEvent(Component.literal("The Kraken"), BossEvent.BossBarColor.BLUE, BossEvent.BossBarOverlay.PROGRESS);
private final AnimatableInstanceCache geoCache = GeckoLibUtil.createInstanceCache(this);
@Nullable
private Vec3 patrolTarget;
private int patrolRetargetTicks;
private int attackCooldown;
private int actionTicks;
private int phaseTransitionTicks;
private int nextAttackIndex;
private int slamCooldown;
private int phaseSummonCooldown;
private int lastAttackState;
private boolean aggroTriggered;
@@ -121,6 +126,7 @@ public class KrakenEntity extends Monster implements GeoEntity {
private int strafeRetargetTicks;
private float orbitDirection = 1.0F;
private boolean stormActive;
public KrakenEntity(EntityType<? extends Monster> entityType, Level level) {
super(entityType, level);
this.moveControl = new FlyingMoveControl(this, 20, true);
@@ -149,7 +155,7 @@ public class KrakenEntity extends Monster implements GeoEntity {
builder.define(ATTACK_STATE, ATTACK_NONE);
builder.define(ROARING, false);
builder.define(PHASE_TWO, false);
builder.define(ANIMATION_STATE, ANIM_IDLE);
builder.define(ANIMATION_STATE, ANIM_NONE);
}
@Override
@@ -165,17 +171,26 @@ public class KrakenEntity extends Monster implements GeoEntity {
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
controllers.add(new AnimationController<>(this, "main_controller", 0, this::mainAnimController)
// idle_controller always loops idle; action_controller layers on top when active
controllers.add(new AnimationController<>(this, "idle_controller", 0, state -> {
if (this.getAnimationState() == ANIM_DEATH) {
return PlayState.STOP;
}
state.setAndContinue(IDLE_ANIM);
return PlayState.CONTINUE;
}).setSoundKeyframeHandler(new AutoPlayingSoundKeyframeHandler<>()));
controllers.add(new AnimationController<>(this, "action_controller", 0, this::actionAnimController)
.setSoundKeyframeHandler(new AutoPlayingSoundKeyframeHandler<>()));
}
private PlayState mainAnimController(AnimationState<KrakenEntity> state) {
private PlayState actionAnimController(AnimationState<KrakenEntity> state) {
return switch (this.getAnimationState()) {
case ANIM_CRY -> state.setAndContinue(CRY_ANIM);
case ANIM_GRAB -> state.setAndContinue(GRAB_ANIM);
case ANIM_SWIPE -> state.setAndContinue(SWIPE_ANIM);
case ANIM_SWIM -> state.setAndContinue(SWIM_ANIM);
case ANIM_SWING_LEFT -> state.setAndContinue(SWING_LEFT_ANIM);
case ANIM_SWING_RIGHT -> state.setAndContinue(SWING_RIGHT_ANIM);
case ANIM_DEATH -> state.setAndContinue(DEATH_ANIM);
default -> state.setAndContinue(IDLE_ANIM);
default -> PlayState.STOP;
};
}
@@ -221,9 +236,6 @@ public class KrakenEntity extends Monster implements GeoEntity {
if (this.attackCooldown > 0) {
this.attackCooldown--;
}
if (this.slamCooldown > 0) {
this.slamCooldown--;
}
if (this.phaseSummonCooldown > 0) {
this.phaseSummonCooldown--;
}
@@ -307,7 +319,8 @@ public class KrakenEntity extends Monster implements GeoEntity {
if (source.is(DamageTypeTags.IS_FIRE)
|| source.is(DamageTypes.LIGHTNING_BOLT)
|| source.is(AntarchyDamageTypes.KRAKEN_LIGHTNING)
|| source.getEntity() instanceof MissileSquidEntity) {
|| source.getEntity() instanceof MissileSquidEntity
|| source.getEntity() instanceof OctopusBombEntity) {
return false;
}
@@ -351,8 +364,6 @@ public class KrakenEntity extends Monster implements GeoEntity {
tag.putInt(ATTACK_COOLDOWN_KEY, this.attackCooldown);
tag.putInt(ACTION_TICKS_KEY, this.actionTicks);
tag.putInt(PHASE_TRANSITION_TICKS_KEY, this.phaseTransitionTicks);
tag.putInt(NEXT_ATTACK_INDEX_KEY, this.nextAttackIndex);
tag.putInt(SLAM_COOLDOWN_KEY, this.slamCooldown);
tag.putInt(PHASE_SUMMON_COOLDOWN_KEY, this.phaseSummonCooldown);
tag.putInt(LAST_ATTACK_STATE_KEY, this.lastAttackState);
tag.putBoolean(AGGRO_TRIGGERED_KEY, this.aggroTriggered);
@@ -374,8 +385,6 @@ public class KrakenEntity extends Monster implements GeoEntity {
this.attackCooldown = tag.getInt(ATTACK_COOLDOWN_KEY);
this.actionTicks = tag.getInt(ACTION_TICKS_KEY);
this.phaseTransitionTicks = tag.getInt(PHASE_TRANSITION_TICKS_KEY);
this.nextAttackIndex = tag.getInt(NEXT_ATTACK_INDEX_KEY);
this.slamCooldown = tag.getInt(SLAM_COOLDOWN_KEY);
this.phaseSummonCooldown = tag.getInt(PHASE_SUMMON_COOLDOWN_KEY);
this.lastAttackState = tag.contains(LAST_ATTACK_STATE_KEY) ? tag.getInt(LAST_ATTACK_STATE_KEY) : ATTACK_NONE;
this.aggroTriggered = tag.getBoolean(AGGRO_TRIGGERED_KEY);
@@ -384,7 +393,7 @@ public class KrakenEntity extends Monster implements GeoEntity {
this.entityData.set(ROARING, tag.getBoolean("Roaring"));
this.entityData.set(ATTACK_STATE, tag.getInt("AttackState"));
this.entityData.set(PHASE_TWO, tag.getBoolean("PhaseTwo"));
this.entityData.set(ANIMATION_STATE, tag.contains("AnimationState") ? tag.getInt("AnimationState") : ANIM_IDLE);
this.entityData.set(ANIMATION_STATE, tag.contains("AnimationState") ? tag.getInt("AnimationState") : ANIM_NONE);
this.lightningStrikeCooldown = tag.getInt("LightningStrikeCooldown");
this.lightningAmbientCooldown = tag.getInt("LightningAmbientCooldown");
this.stormActive = false;
@@ -475,7 +484,7 @@ public class KrakenEntity extends Monster implements GeoEntity {
this.getLookControl().setLookAt(target, 25.0F, 20.0F);
if (!this.spawnedPhaseMinions && this.phaseTransitionTicks <= 40) {
this.spawnPhaseMinions(1 + this.random.nextInt(2), true, target);
this.spawnMinions(1 + this.random.nextInt(2), target);
this.spawnedPhaseMinions = true;
}
@@ -499,8 +508,8 @@ public class KrakenEntity extends Monster implements GeoEntity {
switch (this.getAttackState()) {
case ATTACK_GRAB -> this.tickGrabAttack(target);
case ATTACK_SWIPE -> this.tickSwipeAttack();
case ATTACK_SLAM -> this.tickSlamAttack();
case ATTACK_SWING_LEFT -> this.tickSwingAttack(false);
case ATTACK_SWING_RIGHT -> this.tickSwingAttack(true);
default -> this.finishAttack();
}
}
@@ -512,12 +521,9 @@ public class KrakenEntity extends Monster implements GeoEntity {
if (attackState == ATTACK_GRAB) {
this.actionTicks = 55;
this.playSound(AntarchySoundEvents.KRAKEN_ATTACK.get(), 1.45F, 0.9F);
} else if (attackState == ATTACK_SWIPE) {
} else if (attackState == ATTACK_SWING_LEFT || attackState == ATTACK_SWING_RIGHT) {
this.actionTicks = 40;
this.playSound(AntarchySoundEvents.KRAKEN_SPIN.get(), 1.3F, 0.95F);
} else if (attackState == ATTACK_SLAM) {
this.actionTicks = 34;
this.playSound(AntarchySoundEvents.KRAKEN_ATTACK.get(), 1.5F, 0.82F);
}
}
@@ -545,19 +551,10 @@ public class KrakenEntity extends Monster implements GeoEntity {
}
}
private void tickSwipeAttack() {
// swingRight=true means ATTACK_SWING_RIGHT, which knocks players to the Kraken's LEFT
private void tickSwingAttack(boolean swingRight) {
if (this.actionTicks == 10) {
this.performSwipe();
}
if (--this.actionTicks <= 0) {
this.finishAttack();
}
}
private void tickSlamAttack() {
if (this.actionTicks == 8) {
this.performTentacleSlam();
this.performSwing(swingRight);
}
if (--this.actionTicks <= 0) {
@@ -566,15 +563,12 @@ public class KrakenEntity extends Monster implements GeoEntity {
}
private void finishAttack() {
int finishedAttack = this.getAttackState();
int finished = this.getAttackState();
this.setAttackState(ATTACK_NONE);
this.actionTicks = 0;
this.attackCooldown = this.isPhaseTwo() ? 12 : 18;
this.grabbedTargetId = -1;
this.lastAttackState = finishedAttack;
if (finishedAttack == ATTACK_SLAM) {
this.slamCooldown = this.isPhaseTwo() ? 110 : 150;
}
this.lastAttackState = finished;
this.updateAnimationState();
}
@@ -614,96 +608,57 @@ public class KrakenEntity extends Monster implements GeoEntity {
}
private int chooseNextAttack(LivingEntity target) {
int[] attackRotation = new int[] {ATTACK_GRAB, ATTACK_SWIPE, ATTACK_SLAM};
int[] weightedAttacks = new int[attackRotation.length];
int[] weights = new int[attackRotation.length];
int eligibleCount = 0;
int totalWeight = 0;
double distSqr = this.distanceToSqr(target);
boolean canGrab = distSqr <= 64.0D;
boolean canSwing = distSqr <= 81.0D;
for (int attack : attackRotation) {
if (!this.canUseAttack(attack, target)) {
continue;
}
int weight = this.getAttackWeight(attack);
if (attack == this.lastAttackState) {
weight = Math.max(1, weight / 3);
}
if (weight <= 0) {
continue;
}
weightedAttacks[eligibleCount] = attack;
weights[eligibleCount] = weight;
totalWeight += weight;
eligibleCount++;
}
if (eligibleCount == 0) {
if (!canGrab && !canSwing) {
return ATTACK_NONE;
}
int roll = this.random.nextInt(totalWeight);
for (int i = 0; i < eligibleCount; i++) {
roll -= weights[i];
if (roll < 0) {
return weightedAttacks[i];
}
int grabWeight = canGrab ? (this.lastAttackState == ATTACK_GRAB ? 1 : 4) : 0;
int swingWeight = canSwing ? (this.isSwingAttack(this.lastAttackState) ? 1 : 5) : 0;
int total = grabWeight + swingWeight;
if (total == 0) {
return ATTACK_NONE;
}
return weightedAttacks[eligibleCount - 1];
}
private int getAttackWeight(int attackState) {
return switch (attackState) {
case ATTACK_GRAB -> 4;
case ATTACK_SWIPE -> 5;
case ATTACK_SLAM -> this.isPhaseTwo() ? 1 : 0;
default -> 0;
};
}
private void tickPhaseTwoPressure(LivingEntity target) {
if (!this.isPhaseTwo() || this.phaseSummonCooldown > 0) {
return;
int roll = this.random.nextInt(total);
if (roll < grabWeight) {
return ATTACK_GRAB;
}
if (this.countNearbyMissileSquids() >= 12) {
this.phaseSummonCooldown = 40;
return;
}
this.spawnPhaseMinions(1 + this.random.nextInt(2), true, target);
this.phaseSummonCooldown = 90 + this.random.nextInt(50);
return this.resolveSwingDirection(target);
}
private int countNearbyMissileSquids() {
return this.level().getEntitiesOfClass(
MissileSquidEntity.class,
this.getBoundingBox().inflate(28.0D),
squid -> squid.isAlive()
).size();
private boolean isSwingAttack(int attackState) {
return attackState == ATTACK_SWING_LEFT || attackState == ATTACK_SWING_RIGHT;
}
private boolean canUseAttack(int attackState, LivingEntity target) {
double distanceToTarget = this.distanceToSqr(target);
return switch (attackState) {
case ATTACK_GRAB -> distanceToTarget <= 64.0D;
case ATTACK_SWIPE -> distanceToTarget <= 81.0D && this.isTargetInFront(target, 0.1D);
case ATTACK_SLAM -> this.slamCooldown <= 0 && distanceToTarget <= 144.0D;
default -> false;
};
}
private boolean isTargetInFront(LivingEntity target, double minimumDot) {
// Determines left vs right based on which side the target is on relative to the Kraken.
// Kraken's right vector is forward x world-up. If target is on the Kraken's right side,
// use swing_right (which knocks them left). If on the left, use swing_left (knocks them right).
private int resolveSwingDirection(LivingEntity target) {
Vec3 forward = this.getViewVector(1.0F);
Vec3 toTarget = target.position().subtract(this.position()).normalize();
return forward.dot(toTarget) >= minimumDot;
Vec3 right = forward.cross(new Vec3(0, 1, 0)).normalize();
Vec3 toTarget = target.position().subtract(this.position());
return right.dot(toTarget) > 0 ? ATTACK_SWING_RIGHT : ATTACK_SWING_LEFT;
}
private void performSwipe() {
private void performSwing(boolean swingRight) {
AABB hitBox = this.getBoundingBox().inflate(7.0D, 3.0D, 7.0D);
List<Player> players = this.level().getEntitiesOfClass(Player.class, hitBox, player -> player.isAlive() && this.isTargetInFront(player, -0.15D));
List<Player> players = this.level().getEntitiesOfClass(Player.class, hitBox, LivingEntity::isAlive);
float damage = (float) this.getAttributeValue(Attributes.ATTACK_DAMAGE);
Vec3 forward = this.getViewVector(1.0F);
// swingRight knocks to Kraken's left (-right), swingLeft knocks to Kraken's right (+right)
Vec3 right = forward.cross(new Vec3(0, 1, 0)).normalize();
Vec3 knockDir = swingRight ? right.scale(-1) : right;
for (Player player : players) {
this.hurtAndKnockback(player, (float)this.getAttributeValue(Attributes.ATTACK_DAMAGE), 1.75D, 0.45D);
if (!(this.level() instanceof ServerLevel serverLevel)) continue;
if (!player.hurt(AntarchyDamageSources.krakenMauling(serverLevel, this), damage)) continue;
player.push(knockDir.x * 1.75D, 0.4D, knockDir.z * 1.75D);
player.hurtMarked = true;
}
if (this.level() instanceof ServerLevel serverLevel) {
@@ -711,19 +666,6 @@ public class KrakenEntity extends Monster implements GeoEntity {
}
}
private void performTentacleSlam() {
AABB hitBox = this.getBoundingBox().inflate(8.5D, 2.5D, 8.5D);
List<Player> players = this.level().getEntitiesOfClass(Player.class, hitBox, LivingEntity::isAlive);
float damage = (float)this.getAttributeValue(Attributes.ATTACK_DAMAGE) * 0.75F;
for (Player player : players) {
this.hurtAndKnockback(player, damage, 1.35D, 0.62D);
}
if (this.level() instanceof ServerLevel serverLevel) {
serverLevel.sendParticles(ParticleTypes.SPLASH, this.getX(), this.getY() + 0.5D, this.getZ(), 36, 1.8D, 0.5D, 1.8D, 0.12D);
}
}
private void holdGrabbedTarget(LivingEntity target) {
Vec3 anchor = this.position()
.add(this.getViewVector(1.0F).normalize().scale(this.getBbWidth() * 0.65D))
@@ -738,14 +680,6 @@ public class KrakenEntity extends Monster implements GeoEntity {
target.hurtMarked = true;
}
private void hurtAndKnockback(LivingEntity target, float damage, double horizontalStrength, double verticalStrength) {
if (!(this.level() instanceof ServerLevel serverLevel) || !target.hurt(AntarchyDamageSources.krakenMauling(serverLevel, this), damage)) {
return;
}
this.knockAway(target, horizontalStrength, verticalStrength);
}
private void knockAway(LivingEntity target, double horizontalStrength, double verticalStrength) {
Vec3 direction = target.position().subtract(this.position());
Vec3 horizontal = new Vec3(direction.x, 0.0D, direction.z);
@@ -771,7 +705,25 @@ public class KrakenEntity extends Monster implements GeoEntity {
return entity instanceof LivingEntity livingEntity ? livingEntity : null;
}
private void spawnPhaseMinions(int desiredCount, boolean launched, @Nullable LivingEntity currentTarget) {
private void tickPhaseTwoPressure(LivingEntity target) {
if (!this.isPhaseTwo() || this.phaseSummonCooldown > 0) {
return;
}
if (this.countNearbyMinions() >= 12) {
this.phaseSummonCooldown = 40;
return;
}
this.spawnMinions(1 + this.random.nextInt(2), target);
this.phaseSummonCooldown = 90 + this.random.nextInt(50);
}
private int countNearbyMinions() {
net.minecraft.world.phys.AABB range = this.getBoundingBox().inflate(28.0D);
return this.level().getEntitiesOfClass(OctopusBombEntity.class, range, OctopusBombEntity::isAlive).size()
+ this.level().getEntitiesOfClass(MissileSquidEntity.class, range, MissileSquidEntity::isAlive).size();
}
private void spawnMinions(int desiredCount, @Nullable LivingEntity currentTarget) {
if (!(this.level() instanceof ServerLevel serverLevel)) {
return;
}
@@ -779,22 +731,23 @@ public class KrakenEntity extends Monster implements GeoEntity {
int spawned = 0;
for (int attempt = 0; attempt < desiredCount * 4 && spawned < desiredCount; attempt++) {
Vec3 spawnPos = this.findPhaseMinionSpawnPos(currentTarget);
MissileSquidEntity missileSquid = AntarchyObjects.MISSILE_SQUID.get().create(serverLevel);
if (missileSquid == null) {
continue;
}
Vec3 spawnPos = this.findBombSpawnPos(currentTarget);
boolean spawnBomb = this.random.nextBoolean();
missileSquid.setCanFly(true);
missileSquid.setSpawnedByKraken(true);
missileSquid.moveTo(spawnPos.x, spawnPos.y, spawnPos.z, this.getYRot(), 0.0F);
serverLevel.addFreshEntity(missileSquid);
if (launched) {
missileSquid.launchAsProjectile(this, this.createPhaseMinionLaunchVelocity(spawnPos, currentTarget));
} else if (currentTarget != null) {
missileSquid.setTarget(currentTarget);
if (spawnBomb) {
OctopusBombEntity bomb = AntarchyObjects.OCTOPUS_BOMB.get().create(serverLevel);
if (bomb == null) continue;
bomb.moveTo(spawnPos.x, spawnPos.y, spawnPos.z, this.getYRot(), 0.0F);
serverLevel.addFreshEntity(bomb);
bomb.launchAsProjectile(this, this.createBombLaunchVelocity(spawnPos, currentTarget));
serverLevel.sendParticles(ParticleTypes.BUBBLE, bomb.getX(), bomb.getY() + 0.4D, bomb.getZ(), 14, 0.3D, 0.25D, 0.3D, 0.03D);
} else {
MissileSquidEntity squid = AntarchyObjects.MISSILE_SQUID.get().create(serverLevel);
if (squid == null) continue;
squid.moveTo(spawnPos.x, spawnPos.y, spawnPos.z, this.getYRot(), 0.0F);
serverLevel.addFreshEntity(squid);
serverLevel.sendParticles(ParticleTypes.BUBBLE, squid.getX(), squid.getY() + 0.4D, squid.getZ(), 14, 0.3D, 0.25D, 0.3D, 0.03D);
}
serverLevel.sendParticles(ParticleTypes.BUBBLE, missileSquid.getX(), missileSquid.getY() + 0.4D, missileSquid.getZ(), 14, 0.3D, 0.25D, 0.3D, 0.03D);
spawned++;
}
@@ -803,7 +756,7 @@ public class KrakenEntity extends Monster implements GeoEntity {
}
}
private Vec3 findPhaseMinionSpawnPos(@Nullable LivingEntity currentTarget) {
private Vec3 findBombSpawnPos(@Nullable LivingEntity currentTarget) {
Vec3 anchor = currentTarget != null ? currentTarget.position() : this.position();
for (int attempt = 0; attempt < 18; attempt++) {
double angle = this.random.nextDouble() * Mth.TWO_PI;
@@ -822,7 +775,7 @@ public class KrakenEntity extends Monster implements GeoEntity {
return this.position().add(0.0D, this.getBbHeight() * 0.6D, 0.0D);
}
private Vec3 createPhaseMinionLaunchVelocity(Vec3 spawnPos, @Nullable LivingEntity currentTarget) {
private Vec3 createBombLaunchVelocity(Vec3 spawnPos, @Nullable LivingEntity currentTarget) {
Vec3 aimPoint = currentTarget != null
? currentTarget.getEyePosition()
: this.position().add(this.getViewVector(1.0F).scale(10.0D));
@@ -1043,14 +996,14 @@ public class KrakenEntity extends Monster implements GeoEntity {
private void updateSwimRotation() {
Vec3 velocity = this.getDeltaMovement();
if (velocity.horizontalDistanceSqr() > 1.0E-4D) {
float targetYaw = (float)(Mth.atan2(velocity.z, velocity.x) * (180.0D / Math.PI)) - 90.0F;
float targetYaw = (float) (Mth.atan2(velocity.z, velocity.x) * (180.0D / Math.PI)) - 90.0F;
this.setYRot(Mth.approachDegrees(this.getYRot(), targetYaw, 6.0F));
this.yBodyRot = this.getYRot();
this.yHeadRot = this.getYRot();
}
if (velocity.lengthSqr() > 1.0E-4D) {
float targetPitch = (float)(-(Mth.atan2(velocity.y, velocity.horizontalDistance()) * (180.0D / Math.PI)));
float targetPitch = (float) (-(Mth.atan2(velocity.y, velocity.horizontalDistance()) * (180.0D / Math.PI)));
this.setXRot(Mth.approachDegrees(this.getXRot(), targetPitch, 4.0F));
}
}
@@ -1090,8 +1043,13 @@ public class KrakenEntity extends Monster implements GeoEntity {
return;
}
if (this.phaseTransitionTicks > 0 || this.isRoaring()) {
this.setAnimationState(ANIM_IDLE);
if (this.isRoaring()) {
this.setAnimationState(ANIM_CRY);
return;
}
if (this.phaseTransitionTicks > 0) {
this.setAnimationState(ANIM_NONE);
return;
}
@@ -1100,22 +1058,18 @@ public class KrakenEntity extends Monster implements GeoEntity {
this.setAnimationState(ANIM_GRAB);
return;
}
case ATTACK_SWIPE, ATTACK_SLAM -> {
this.setAnimationState(ANIM_SWIPE);
case ATTACK_SWING_LEFT -> {
this.setAnimationState(ANIM_SWING_LEFT);
return;
}
case ATTACK_SWING_RIGHT -> {
this.setAnimationState(ANIM_SWING_RIGHT);
return;
}
default -> {
}
}
Vec3 velocity = this.getDeltaMovement();
double horizontalSpeedSqr = velocity.horizontalDistanceSqr();
double verticalSpeedSqr = velocity.y * velocity.y;
if (horizontalSpeedSqr > 0.03D && horizontalSpeedSqr > verticalSpeedSqr * 2.5D) {
this.setAnimationState(ANIM_SWIM);
return;
}
this.setAnimationState(this.isPhaseTwo() ? ANIM_IDLE_TWO : ANIM_IDLE);
this.setAnimationState(ANIM_NONE);
}
}
@@ -20,28 +20,41 @@ public class ElythiaBiomeSource extends BiomeSource {
Registries.BIOME,
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "moleworm_caves")
);
private static final ResourceKey<Biome> ELYTHIA_OCEAN = ResourceKey.create(
Registries.BIOME,
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "elythia_ocean")
);
private static final ResourceKey<Biome> ELYTHIA_BEACH = ResourceKey.create(
Registries.BIOME,
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "elythia_beach")
);
private static final int[] SURFACE_FALLBACK_BLOCK_YS = new int[]{192, 160, 128, 96, 64, 32, 0};
public static final MapCodec<ElythiaBiomeSource> CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group(
MultiNoiseBiomeSource.DIRECT_CODEC.forGetter(ElythiaBiomeSource::parameters),
Codec.INT.optionalFieldOf("moleworm_caves_max_y", 72).forGetter(ElythiaBiomeSource::molewormCavesMaxY),
Codec.INT.optionalFieldOf("surface_biome_sample_y", 160).forGetter(ElythiaBiomeSource::surfaceBiomeSampleY)
Codec.INT.optionalFieldOf("surface_biome_sample_y", 160).forGetter(ElythiaBiomeSource::surfaceBiomeSampleY),
Codec.INT.optionalFieldOf("ocean_max_y", 85).forGetter(ElythiaBiomeSource::oceanMaxY)
).apply(instance, ElythiaBiomeSource::new));
private final Climate.ParameterList<Holder<Biome>> parameters;
private final MultiNoiseBiomeSource delegate;
private final int molewormCavesMaxY;
private final int surfaceBiomeSampleY;
private final int oceanMaxY;
private final int molewormCavesMaxQuartY;
private final int surfaceBiomeSampleQuartY;
private final int oceanMaxQuartY;
public ElythiaBiomeSource(Climate.ParameterList<Holder<Biome>> parameters, int molewormCavesMaxY, int surfaceBiomeSampleY) {
public ElythiaBiomeSource(Climate.ParameterList<Holder<Biome>> parameters, int molewormCavesMaxY, int surfaceBiomeSampleY, int oceanMaxY) {
this.parameters = parameters;
this.delegate = MultiNoiseBiomeSource.createFromList(parameters);
this.molewormCavesMaxY = molewormCavesMaxY;
this.surfaceBiomeSampleY = surfaceBiomeSampleY;
this.oceanMaxY = oceanMaxY;
this.molewormCavesMaxQuartY = QuartPos.fromBlock(molewormCavesMaxY);
this.surfaceBiomeSampleQuartY = QuartPos.fromBlock(surfaceBiomeSampleY);
this.oceanMaxQuartY = QuartPos.fromBlock(oceanMaxY);
}
private Climate.ParameterList<Holder<Biome>> parameters() {
@@ -56,6 +69,10 @@ public class ElythiaBiomeSource extends BiomeSource {
return this.surfaceBiomeSampleY;
}
private int oceanMaxY() {
return this.oceanMaxY;
}
@Override
protected MapCodec<? extends BiomeSource> codec() {
return CODEC;
@@ -69,18 +86,31 @@ public class ElythiaBiomeSource extends BiomeSource {
@Override
public Holder<Biome> getNoiseBiome(int x, int y, int z, Climate.Sampler sampler) {
Holder<Biome> biome = this.delegate.getNoiseBiome(x, y, z, sampler);
if (!biome.is(MOLEWORM_CAVES) || y <= this.molewormCavesMaxQuartY) {
return biome;
// Cap moleworm caves below their max Y
if (biome.is(MOLEWORM_CAVES) && y > this.molewormCavesMaxQuartY) {
return resolveSurfaceFallback(x, y, z, sampler, MOLEWORM_CAVES);
}
// Cap ocean/beach biomes above sea level — if terrain noise puts these biomes
// too high, replace with whatever surface biome would naturally be there
if ((biome.is(ELYTHIA_OCEAN) || biome.is(ELYTHIA_BEACH)) && y > this.oceanMaxQuartY) {
return resolveSurfaceFallback(x, y, z, sampler, ELYTHIA_OCEAN, ELYTHIA_BEACH);
}
return biome;
}
@SafeVarargs
private Holder<Biome> resolveSurfaceFallback(int x, int y, int z, Climate.Sampler sampler, ResourceKey<Biome>... excluded) {
Holder<Biome> fallback = this.delegate.getNoiseBiome(x, this.surfaceBiomeSampleQuartY, z, sampler);
if (!fallback.is(MOLEWORM_CAVES)) {
if (!isExcluded(fallback, excluded)) {
return fallback;
}
for (int sampleBlockY : SURFACE_FALLBACK_BLOCK_YS) {
Holder<Biome> candidate = this.delegate.getNoiseBiome(x, QuartPos.fromBlock(sampleBlockY), z, sampler);
if (!candidate.is(MOLEWORM_CAVES)) {
if (!isExcluded(candidate, excluded)) {
return candidate;
}
}
@@ -88,9 +118,18 @@ public class ElythiaBiomeSource extends BiomeSource {
return fallback;
}
@SafeVarargs
private static boolean isExcluded(Holder<Biome> biome, ResourceKey<Biome>... excluded) {
for (ResourceKey<Biome> key : excluded) {
if (biome.is(key)) return true;
}
return false;
}
@Override
public void addDebugInfo(java.util.List<String> debug, net.minecraft.core.BlockPos pos, Climate.Sampler sampler) {
this.delegate.addDebugInfo(debug, pos, sampler);
debug.add("Elythia mole cave cap: y<=" + this.molewormCavesMaxY);
debug.add("Elythia ocean cap: y<=" + this.oceanMaxY);
}
}
@@ -0,0 +1,72 @@
package com.craisinlord.antarchy.mixins;
import com.craisinlord.antarchy.content.item.SquidzookaItem;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.Enchantments;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(Enchantment.class)
public abstract class SquidzookaEnchantMixin {
private static final Registry<Enchantment> ENCHANTMENT_REGISTRY = resolveEnchantmentRegistry();
@Inject(method = "canEnchant", at = @At("HEAD"), cancellable = true)
private void antarchy$limitSquidzookaCrossbowEnchants(ItemStack stack, CallbackInfoReturnable<Boolean> cir) {
this.antarchy$applySquidzookaEnchantRules(stack, cir);
}
@Inject(method = "isPrimaryItem", at = @At("HEAD"), cancellable = true)
private void antarchy$limitSquidzookaPrimaryItem(ItemStack stack, CallbackInfoReturnable<Boolean> cir) {
this.antarchy$applySquidzookaEnchantRules(stack, cir);
}
@Inject(method = "isSupportedItem", at = @At("HEAD"), cancellable = true)
private void antarchy$limitSquidzookaSupportedItem(ItemStack stack, CallbackInfoReturnable<Boolean> cir) {
this.antarchy$applySquidzookaEnchantRules(stack, cir);
}
private void antarchy$applySquidzookaEnchantRules(ItemStack stack, CallbackInfoReturnable<Boolean> cir) {
if (!(stack.getItem() instanceof SquidzookaItem)) {
return;
}
if (ENCHANTMENT_REGISTRY == null) {
return;
}
Enchantment enchantment = (Enchantment) (Object) this;
ResourceLocation enchantmentId = ENCHANTMENT_REGISTRY.getKey(enchantment);
if (enchantmentId == null) {
return;
}
if (enchantmentId.equals(Enchantments.MULTISHOT.location())) {
cir.setReturnValue(true);
return;
}
if (enchantmentId.equals(Enchantments.QUICK_CHARGE.location())
|| enchantmentId.equals(Enchantments.PIERCING.location())) {
cir.setReturnValue(false);
}
}
@SuppressWarnings("unchecked")
private static Registry<Enchantment> resolveEnchantmentRegistry() {
try {
return (Registry<Enchantment>) BuiltInRegistries.class.getField("ENCHANTMENT").get(null);
} catch (ReflectiveOperationException primary) {
try {
return (Registry<Enchantment>) BuiltInRegistries.class.getField("ENCHANTMENTS").get(null);
} catch (ReflectiveOperationException ignored) {
return null;
}
}
}
}
@@ -12,6 +12,7 @@
"FireVisualEntityMixin",
"GlowVinesUnderLeavesMixin",
"ServerPlayerGameModeMixin",
"SquidzookaEnchantMixin",
"StinkyLivingEntityMixin",
"TorchflowerBlockStateMixin",
"gravity.AbstractArrowGravityMixin",
@@ -4,6 +4,11 @@
"idle": {
"loop": true,
"animation_length": 4,
"sound_effects": {
"0.0": {
"effect": "antarchy:kraken_flying_loop|0.45|1.0"
}
},
"bones": {
"l_shoulder": {
"rotation": {
@@ -203,7 +203,7 @@
"animation_length": 2.5,
"sound_effects": {
"0.0": {
"effect": "antarchy:kraken_flying_loop|0.45|1.0"
"effect": "antarchy:kraken_flying_loop|0.45|1.19"
}
},
"bones": {
@@ -10276,7 +10276,7 @@
"animation_length": 1,
"sound_effects": {
"0.0": {
"effect": "antarchy:kraken_flying_sideways_loop|0.45|1.0"
"effect": "antarchy:kraken_flying_sideways_loop|0.45|1.19"
}
},
"bones": {
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -1,8 +1,8 @@
{
"variants": {
"facing=north": {"model": "antarchy:block/termite_nest"},
"facing=east": {"model": "antarchy:block/termite_nest", "y": 90},
"facing=east": {"model": "antarchy:block/termite_nest", "y": 90},
"facing=south": {"model": "antarchy:block/termite_nest", "y": 180},
"facing=west": {"model": "antarchy:block/termite_nest", "y": 270}
"facing=west": {"model": "antarchy:block/termite_nest", "y": 270}
}
}
@@ -3,80 +3,129 @@
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.stinkbug",
"texture_width": 32,
"identifier": "geometry.Stinkbug",
"texture_width": 64,
"texture_height": 32,
"visible_bounds_width": 2,
"visible_bounds_height": 1.5,
"visible_bounds_offset": [0, 0.25, 0]
"visible_bounds_height": 2.5,
"visible_bounds_offset": [0, 0.75, 0]
},
"bones": [
{
"name": "root",
"pivot": [0, 0, 0]
"pivot": [0, 1.14286, -0.57143]
},
{
"name": "right_leg",
"parent": "root",
"pivot": [-3, 1, 0.5],
"cubes": [
{"origin": [-7, 1, 0], "size": [4, 0, 1], "uv": [3, 10]}
]
},
{
"name": "left_leg",
"parent": "root",
"pivot": [3, 1, 0.5],
"cubes": [
{"origin": [3, 1, 0], "size": [4, 0, 1], "uv": [3, 10], "mirror": true}
]
},
{
"name": "right_leg_front",
"parent": "root",
"pivot": [-3, 1, -1.5],
"cubes": [
{"origin": [-7, 1, -2], "size": [4, 0, 1], "uv": [3, 10]}
]
},
{
"name": "left_leg_front",
"parent": "root",
"pivot": [3, 1, -1.5],
"cubes": [
{"origin": [3, 1, -2], "size": [4, 0, 1], "uv": [3, 10], "mirror": true}
]
},
{
"name": "right_leg_back",
"parent": "root",
"pivot": [-3, 1, 2.5],
"cubes": [
{"origin": [-7, 1, 2], "size": [4, 0, 1], "uv": [3, 10]}
]
},
{
"name": "left_leg_back",
"parent": "root",
"pivot": [3, 1, 2.5],
"cubes": [
{"origin": [3, 1, 2], "size": [4, 0, 1], "uv": [3, 10], "mirror": true}
]
},
{
"name": "body",
"parent": "root",
"pivot": [0, 2, 0],
"pivot": [0, 1, 1],
"cubes": [
{"origin": [-3, 0, -5], "size": [6, 4, 10], "uv": [0, 0]}
{"origin": [-3, 1, -2], "size": [6, 4, 6], "uv": [0, 0]},
{"origin": [-3, 1, -2], "size": [6, 4, 6], "inflate": 0.2, "uv": [0, 11]}
]
},
{
"name": "antenna",
"name": "head",
"parent": "body",
"pivot": [0, 4, -4],
"pivot": [0, 2.25, -2],
"cubes": [
{"origin": [-2, 4, -5], "size": [4, 2, 1], "uv": [0, 14]}
{"origin": [-3, 1.25, -6], "size": [6, 2, 4], "uv": [18, 0]}
]
},
{
"name": "frontLeftLeg",
"parent": "body",
"pivot": [-3, 0, -4],
"name": "right_eye",
"parent": "head",
"pivot": [-3, 2.75, -5.5],
"cubes": [
{"origin": [-6, 0, -5], "size": [3, 0, 2], "uv": [10, 14]}
{"origin": [-3, 2.25, -6], "size": [0, 1, 1], "inflate": 0.02, "uv": [12, 9]}
]
},
{
"name": "frontRightLeg",
"parent": "body",
"pivot": [3, 0, -4],
"name": "left_eye",
"parent": "head",
"pivot": [3, 2.75, -5.5],
"cubes": [
{"origin": [3, 0, -5], "size": [3, 0, 2], "uv": [10, 14], "mirror": true}
{"origin": [3, 2.25, -6], "size": [0, 1, 1], "inflate": 0.02, "uv": [12, 9], "mirror": true}
]
},
{
"name": "middleLeftLeg",
"parent": "body",
"pivot": [-3, 0, 0],
"name": "r_antenna",
"parent": "head",
"pivot": [-2, 2.75, -5],
"cubes": [
{"origin": [-6, 0, -1], "size": [3, 0, 2], "uv": [10, 14]}
{"origin": [-2, 2.75, -6], "size": [0, 4, 2], "uv": [18, -2]}
]
},
{
"name": "middleRightLeg",
"parent": "body",
"pivot": [3, 0, 0],
"name": "r_antenna2",
"parent": "r_antenna",
"pivot": [-2, 6.75, -5],
"cubes": [
{"origin": [3, 0, -1], "size": [3, 0, 2], "uv": [10, 14], "mirror": true}
{"origin": [-2, 6.75, -6], "size": [0, 4, 2], "uv": [0, 8]}
]
},
{
"name": "backLeftLeg",
"parent": "body",
"pivot": [-3, 0, 4],
"name": "l_antenna",
"parent": "head",
"pivot": [2, 2.75, -5],
"cubes": [
{"origin": [-6, 0, 3], "size": [3, 0, 2], "uv": [10, 14]}
{"origin": [2, 2.75, -6], "size": [0, 4, 2], "uv": [18, -2], "mirror": true}
]
},
{
"name": "backRightLeg",
"parent": "body",
"pivot": [3, 0, 4],
"name": "l_antenna2",
"parent": "l_antenna",
"pivot": [2, 6.75, -5],
"cubes": [
{"origin": [3, 0, 3], "size": [3, 0, 2], "uv": [10, 14], "mirror": true}
{"origin": [2, 6.75, -6], "size": [0, 4, 2], "uv": [0, 8], "mirror": true}
]
}
]
@@ -0,0 +1,197 @@
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.Termite",
"texture_width": 64,
"texture_height": 64,
"visible_bounds_width": 2,
"visible_bounds_height": 1.5,
"visible_bounds_offset": [0, 0.25, 0]
},
"bones": [
{
"name": "Termite",
"pivot": [0, 1.21429, -1.91667]
},
{
"name": "r_leg",
"parent": "Termite",
"pivot": [-1.5, 1, -3.5],
"cubes": [
{"origin": [-7.5, 1, -3.5], "size": [6, 0, 1], "uv": [-1, 12]}
]
},
{
"name": "r_leg2",
"parent": "r_leg",
"pivot": [-7.5, 1, -3.5],
"cubes": [
{"origin": [-12.5, 1, -3.5], "size": [5, 0, 1], "uv": [-1, 28]}
]
},
{
"name": "l_leg",
"parent": "Termite",
"pivot": [1.5, 1, -3.5],
"cubes": [
{"origin": [1.5, 1, -3.5], "size": [6, 0, 1], "uv": [-1, 14]}
]
},
{
"name": "l_leg2",
"parent": "l_leg",
"pivot": [7.5, 1, -3.5],
"cubes": [
{"origin": [7.5, 1, -3.5], "size": [5, 0, 1], "uv": [-1, 30]}
]
},
{
"name": "r_leg5",
"parent": "Termite",
"pivot": [-1.5, 1, -2.5],
"cubes": [
{"origin": [-7.5, 1, -2.5], "size": [6, 0, 1], "uv": [-1, 16]}
]
},
{
"name": "r_leg6",
"parent": "r_leg5",
"pivot": [-7.5, 1, -2.5],
"cubes": [
{"origin": [-12.5, 1, -2.5], "size": [5, 0, 1], "uv": [-1, 24]}
]
},
{
"name": "l_leg5",
"parent": "Termite",
"pivot": [1.5, 1, -2.5],
"cubes": [
{"origin": [1.5, 1, -2.5], "size": [6, 0, 1], "uv": [-1, 18]}
]
},
{
"name": "l_leg6",
"parent": "l_leg5",
"pivot": [7.5, 1, -2.5],
"cubes": [
{"origin": [7.5, 1, -2.5], "size": [5, 0, 1], "uv": [-1, 34]}
]
},
{
"name": "r_leg3",
"parent": "Termite",
"pivot": [-1.5, 1, -4.5],
"cubes": [
{"origin": [-7.5, 1, -4.5], "size": [6, 0, 1], "uv": [-1, 20]}
]
},
{
"name": "r_leg4",
"parent": "r_leg3",
"pivot": [-7.5, 1, -4.5],
"cubes": [
{"origin": [-12.5, 1, -4.5], "size": [5, 0, 1], "uv": [-1, 32]}
]
},
{
"name": "l_leg3",
"parent": "Termite",
"pivot": [1.5, 1, -4.5],
"cubes": [
{"origin": [1.5, 1, -4.5], "size": [6, 0, 1], "uv": [-1, 22]}
]
},
{
"name": "l_leg4",
"parent": "l_leg3",
"pivot": [7.5, 1, -4.5],
"cubes": [
{"origin": [7.5, 1, -4.5], "size": [5, 0, 1], "uv": [-1, 26]}
]
},
{
"name": "thorax",
"parent": "Termite",
"pivot": [0, 2.5, -4.41667],
"cubes": [
{"origin": [-2, 1, -4.5], "size": [4, 3, 4], "uv": [11, 20]}
]
},
{
"name": "head",
"parent": "thorax",
"pivot": [-0.27778, 1.83333, -4.27778],
"cubes": [
{"origin": [-1.5, 1.25, -4.5], "size": [3, 2, 1], "uv": [12, 13]},
{"origin": [-3, 1, -12.25], "size": [6, 3, 8], "inflate": 0.01, "uv": [20, 4]}
]
},
{
"name": "r_mandibule",
"parent": "head",
"pivot": [-1.33333, 1.5, -11.99167],
"cubes": [
{"origin": [-3.5, 1, -18], "size": [2, 1, 6], "uv": [5, 31]},
{"origin": [-1.5, 1.5, -14.1], "size": [1, 0, 1], "uv": [1, 1]},
{"origin": [-1.5, 1.5, -17.1], "size": [1, 0, 1], "uv": [-1, 0]},
{"origin": [-2.5, 1.5, -19], "size": [1, 0, 1], "uv": [1, 0]}
]
},
{
"name": "l_mandibule",
"parent": "head",
"pivot": [1.33333, 1.5, -11.99167],
"cubes": [
{"origin": [1.5, 1, -18], "size": [2, 1, 6], "uv": [15, 28], "mirror": true},
{"origin": [0.5, 1.5, -14.1], "size": [1, 0, 1], "uv": [1, 1], "mirror": true},
{"origin": [0.5, 1.5, -17.1], "size": [1, 0, 1], "uv": [-1, 0], "mirror": true},
{"origin": [1.5, 1.5, -19], "size": [1, 0, 1], "uv": [1, 0], "mirror": true}
]
},
{
"name": "l_eye",
"parent": "head",
"pivot": [3, 2.75, -8.25],
"cubes": [
{"origin": [3, 1.75, -9.25], "size": [0, 2, 2], "inflate": 0.05, "uv": [15, 15]}
]
},
{
"name": "r_eye",
"parent": "head",
"pivot": [-3, 2.75, -8.25],
"cubes": [
{"origin": [-3, 1.75, -9.25], "size": [0, 2, 2], "inflate": 0.05, "uv": [15, 15], "mirror": true}
]
},
{
"name": "l_antenna",
"parent": "head",
"pivot": [3, 3, -9.25],
"cubes": [
{"origin": [3, 3, -17.25], "size": [1, 0, 8], "inflate": 0.01, "uv": [12, 0]}
]
},
{
"name": "r_antenna",
"parent": "head",
"pivot": [-3, 3, -9.25],
"cubes": [
{"origin": [-4, 3, -17.25], "size": [1, 0, 8], "inflate": 0.01, "uv": [12, 0], "mirror": true}
]
},
{
"name": "abdomen",
"parent": "thorax",
"pivot": [0, 2.5, -2.125],
"cubes": [
{"origin": [-2.5, 1, -1.25], "size": [5, 4, 8], "inflate": 0.05, "uv": [1, 0]},
{"origin": [-1.5, 1.25, -2.25], "size": [3, 2, 1], "uv": [11, 28]}
]
}
]
}
]
}
@@ -6,9 +6,9 @@
"identifier": "geometry.unknown",
"texture_width": 256,
"texture_height": 256,
"visible_bounds_width": 6,
"visible_bounds_height": 5.5,
"visible_bounds_offset": [0, 2.25, 0]
"visible_bounds_width": 8,
"visible_bounds_height": 6.5,
"visible_bounds_offset": [0, 2.75, 0]
},
"bones": [
{
@@ -150,6 +150,7 @@
"entity.antarchy.cloud_shark": "Cloud Shark",
"entity.antarchy.kraken": "The Kraken",
"entity.antarchy.missile_squid": "Missile Squid",
"entity.antarchy.octopus_bomb": "Octopus Bomb",
"entity.antarchy.nightmare": "Nightmare",
"entity.antarchy.bed_bug": "Bed Bug",
"entity.antarchy.stink_bug": "Stink Bug",
@@ -372,6 +373,7 @@
"item.antarchy.cloud_shark_spawn_egg": "Cloud Shark Spawn Egg",
"item.antarchy.kraken_spawn_egg": "Uh, no. Don't.",
"item.antarchy.missile_squid_spawn_egg": "Missile Squid Spawn Egg",
"item.antarchy.octopus_bomb_spawn_egg": "Octopus Bomb Spawn Egg",
"item.antarchy.nightmare_spawn_egg": "Nightmare Spawn Egg",
"item.antarchy.toreterror_spawn_egg": "Toreterror Spawn Egg",
"item.antarchy.creeping_horror_spawn_egg": "Creeping Horror Spawn Egg",
@@ -1,8 +1,12 @@
{
"parent": "minecraft:block/orientable",
"parent": "minecraft:block/cube",
"textures": {
"front": "antarchy:block/termite_nest_front",
"side": "antarchy:block/termite_nest_side",
"top": "antarchy:block/termite_nest_top"
"particle": "antarchy:block/brown_ant_nest/brown_ant_nest",
"down": "minecraft:block/coarse_dirt",
"up": "antarchy:block/brown_ant_nest/brown_ant_nest_top",
"north": "antarchy:block/brown_ant_nest/brown_ant_nest",
"south": "antarchy:block/brown_ant_nest/brown_ant_nest",
"west": "antarchy:block/brown_ant_nest/brown_ant_nest",
"east": "antarchy:block/brown_ant_nest/brown_ant_nest"
}
}
@@ -0,0 +1,3 @@
{
"parent": "minecraft:item/template_spawn_egg"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 674 B

After

Width:  |  Height:  |  Size: 883 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 13 KiB

@@ -7,6 +7,7 @@
"type": "antarchy:elythia_biome_source",
"moleworm_caves_max_y": 30,
"surface_biome_sample_y": 160,
"ocean_max_y": 85,
"biomes": [
{
"biome": "antarchy:moleworm_caves",
@@ -0,0 +1,7 @@
{
"replace": false,
"values": [
"minecraft:vine",
"antarchy:creepvine"
]
}
@@ -1,6 +1,7 @@
{
"replace": false,
"values": [
"antarchy:ultimate_crossbow"
"antarchy:ultimate_crossbow",
"antarchy:squidzooka"
]
}
@@ -74,6 +74,7 @@ import com.craisinlord.antarchy.content.entity.LurkingTerrorEntity;
import com.craisinlord.antarchy.content.item.PrimordialArmorItem;
import com.craisinlord.antarchy.content.item.WaterCannonItem;
import com.craisinlord.antarchy.content.entity.kraken.KrakenEntity;
import com.craisinlord.antarchy.content.entity.OctopusBombEntity;
import com.craisinlord.antarchy.content.entity.MolevoreEntity;
import com.craisinlord.antarchy.content.entity.MolewormEntity;
import com.craisinlord.antarchy.content.entity.BomberEntity;
@@ -84,6 +85,7 @@ import com.craisinlord.antarchy.content.entity.ant.BaseAntEntity;
import com.craisinlord.antarchy.content.entity.ant.BrownAntEntity;
import com.craisinlord.antarchy.content.entity.ant.RainbowAntEntity;
import com.craisinlord.antarchy.content.entity.ant.RedAntEntity;
import com.craisinlord.antarchy.content.entity.ant.TermiteEntity;
import com.craisinlord.antarchy.content.item.BattleAxeItem;
import com.craisinlord.antarchy.content.item.BasiliskDaggerItem;
import com.craisinlord.antarchy.content.item.BigBerthaItem;
@@ -746,6 +748,8 @@ public final class AntarchyFabricContent {
() -> buildAntType(BrownAntEntity::new, MobCategory.CREATURE, "brown_ant"));
public static final DeferredHolder<EntityType<?>, EntityType<RainbowAntEntity>> RAINBOW_ANT = ENTITY_TYPES.register("rainbow_ant",
() -> buildAntType(RainbowAntEntity::new, MobCategory.CREATURE, "rainbow_ant"));
public static final DeferredHolder<EntityType<?>, EntityType<TermiteEntity>> TERMITE = ENTITY_TYPES.register("termite",
() -> buildAntType(TermiteEntity::new, MobCategory.CREATURE, "termite"));
public static final DeferredHolder<EntityType<?>, EntityType<MolewormEntity>> MOLEWORM = ENTITY_TYPES.register("moleworm",
() -> EntityType.Builder.of(MolewormEntity::new, MobCategory.MONSTER)
.sized(0.4F, 0.3F)
@@ -826,6 +830,8 @@ public final class AntarchyFabricContent {
() -> new AntNestBlock(BROWN_ANT, AntarchyFabricContent::antNestBlockEntityType, BlockBehaviour.Properties.ofFullCopy(Blocks.DIRT).noLootTable()));
public static final DeferredBlock<AntNestBlock> RAINBOW_ANT_NEST = BLOCKS.register("rainbow_ant_nest",
() -> new AntNestBlock(RAINBOW_ANT, AntarchyFabricContent::antNestBlockEntityType, BlockBehaviour.Properties.ofFullCopy(Blocks.DIRT).noLootTable()));
public static final DeferredBlock<AntNestBlock> TERMITE_NEST = BLOCKS.register("termite_nest",
() -> new AntNestBlock(TERMITE, AntarchyFabricContent::antNestBlockEntityType, BlockBehaviour.Properties.ofFullCopy(Blocks.DIRT).noLootTable()));
public static final DeferredBlock<Block> URANIUM_ORE = BLOCKS.register("uranium_ore",
() -> createOre(Blocks.EMERALD_ORE, 4, 8));
public static final DeferredBlock<Block> DEEPSLATE_URANIUM_ORE = BLOCKS.register("deepslate_uranium_ore",
@@ -934,7 +940,8 @@ public final class AntarchyFabricContent {
AntNestBlockEntity::new,
RED_ANT_NEST.get(),
BROWN_ANT_NEST.get(),
RAINBOW_ANT_NEST.get()
RAINBOW_ANT_NEST.get(),
TERMITE_NEST.get()
).build(null));
public static final DeferredHolder<BlockEntityType<?>, BlockEntityType<DreamCampfireBlockEntity>> DREAM_CAMPFIRE_BLOCK_ENTITY = BLOCK_ENTITY_TYPES.register("dream_campfire",
() -> BlockEntityType.Builder.of(
@@ -1070,6 +1077,7 @@ public final class AntarchyFabricContent {
public static final DeferredItem<net.minecraft.world.item.BlockItem> RED_ANT_NEST_ITEM = ITEMS.registerSimpleBlockItem(RED_ANT_NEST);
public static final DeferredItem<net.minecraft.world.item.BlockItem> BROWN_ANT_NEST_ITEM = ITEMS.registerSimpleBlockItem(BROWN_ANT_NEST);
public static final DeferredItem<net.minecraft.world.item.BlockItem> RAINBOW_ANT_NEST_ITEM = ITEMS.registerSimpleBlockItem(RAINBOW_ANT_NEST);
public static final DeferredItem<net.minecraft.world.item.BlockItem> TERMITE_NEST_ITEM = ITEMS.registerSimpleBlockItem(TERMITE_NEST);
public static final DeferredItem<net.minecraft.world.item.BlockItem> URANIUM_ORE_ITEM = ITEMS.registerSimpleBlockItem(URANIUM_ORE);
public static final DeferredItem<net.minecraft.world.item.BlockItem> DEEPSLATE_URANIUM_ORE_ITEM = ITEMS.registerSimpleBlockItem(DEEPSLATE_URANIUM_ORE);
public static final DeferredItem<net.minecraft.world.item.BlockItem> TITANIUM_ORE_ITEM = ITEMS.registerSimpleBlockItem(TITANIUM_ORE);
@@ -1527,7 +1535,7 @@ public final class AntarchyFabricContent {
.build("cloud_shark"));
public static final DeferredHolder<EntityType<?>, EntityType<KrakenEntity>> KRAKEN = ENTITY_TYPES.register("kraken",
() -> EntityType.Builder.of(KrakenEntity::new, MobCategory.MONSTER)
.sized(5.2F, 9.8F)
.sized(11.4F, 39.0F)
.clientTrackingRange(12)
.build("kraken"));
public static final DeferredHolder<EntityType<?>, EntityType<MissileSquidEntity>> MISSILE_SQUID = ENTITY_TYPES.register("missile_squid",
@@ -1535,6 +1543,11 @@ public final class AntarchyFabricContent {
.sized(1.62F, 3.18F)
.clientTrackingRange(10)
.build("missile_squid"));
public static final DeferredHolder<EntityType<?>, EntityType<OctopusBombEntity>> OCTOPUS_BOMB = ENTITY_TYPES.register("octopus_bomb",
() -> EntityType.Builder.of(OctopusBombEntity::new, MobCategory.MONSTER)
.sized(2.4F, 2.9F)
.clientTrackingRange(10)
.build("octopus_bomb"));
public static final DeferredHolder<EntityType<?>, EntityType<NightmareEntity>> NIGHTMARE = ENTITY_TYPES.register("nightmare",
() -> EntityType.Builder.of(NightmareEntity::new, MobCategory.MONSTER)
.sized(3.2F, 3.8F)
@@ -1610,6 +1623,8 @@ public final class AntarchyFabricContent {
() -> new DeferredSpawnEggItem(BROWN_ANT, 0x6A4320, 0x26160A, new Item.Properties()));
public static final DeferredItem<DeferredSpawnEggItem> RAINBOW_ANT_SPAWN_EGG = ITEMS.register("rainbow_ant_spawn_egg",
() -> new DeferredSpawnEggItem(RAINBOW_ANT, 0x56D4F0, 0xF66DBB, new Item.Properties()));
public static final DeferredItem<DeferredSpawnEggItem> TERMITE_SPAWN_EGG = ITEMS.register("termite_spawn_egg",
() -> new DeferredSpawnEggItem(TERMITE, 0xE8DFC0, 0x5C3C1A, new Item.Properties()));
public static final DeferredItem<DeferredSpawnEggItem> MOLEWORM_SPAWN_EGG = ITEMS.register("moleworm_spawn_egg",
() -> new DeferredSpawnEggItem(MOLEWORM, 0x7A6150, 0xD2B8A3, new Item.Properties()));
public static final DeferredItem<DeferredSpawnEggItem> MANTIS_SPAWN_EGG = ITEMS.register("mantis_spawn_egg",
@@ -1640,6 +1655,8 @@ public final class AntarchyFabricContent {
() -> new DeferredSpawnEggItem(KRAKEN, 0x163C53, 0x4F8E99, new Item.Properties().rarity(Rarity.EPIC)));
public static final DeferredItem<DeferredSpawnEggItem> MISSILE_SQUID_SPAWN_EGG = ITEMS.register("missile_squid_spawn_egg",
() -> new DeferredSpawnEggItem(MISSILE_SQUID, 0xD88FA7, 0x8D5269, new Item.Properties().rarity(Rarity.UNCOMMON)));
public static final DeferredItem<DeferredSpawnEggItem> OCTOPUS_BOMB_SPAWN_EGG = ITEMS.register("octopus_bomb_spawn_egg",
() -> new DeferredSpawnEggItem(OCTOPUS_BOMB, 0xC882C8, 0x5C1A7A, new Item.Properties().rarity(Rarity.UNCOMMON)));
public static final DeferredItem<DeferredSpawnEggItem> NIGHTMARE_SPAWN_EGG = ITEMS.register("nightmare_spawn_egg",
() -> new DeferredSpawnEggItem(NIGHTMARE, 0x22121C, 0xB51B2D, new Item.Properties().rarity(Rarity.RARE)));
public static final DeferredItem<DeferredSpawnEggItem> BED_BUG_SPAWN_EGG = ITEMS.register("bed_bug_spawn_egg",
@@ -1769,6 +1786,7 @@ public final class AntarchyFabricContent {
FabricDefaultAttributeRegistry.register(CLOUD_SHARK.get(), CloudSharkEntity.createAttributes().build());
FabricDefaultAttributeRegistry.register(KRAKEN.get(), KrakenEntity.createAttributes().build());
FabricDefaultAttributeRegistry.register(MISSILE_SQUID.get(), MissileSquidEntity.createAttributes().build());
FabricDefaultAttributeRegistry.register(OCTOPUS_BOMB.get(), OctopusBombEntity.createAttributes().build());
FabricDefaultAttributeRegistry.register(NIGHTMARE.get(), NightmareEntity.createAttributes().build());
FabricDefaultAttributeRegistry.register(BED_BUG.get(), BedBugEntity.createAttributes().build());
FabricDefaultAttributeRegistry.register(STINK_BUG.get(), StinkBugEntity.createAttributes().build());
@@ -1802,6 +1820,11 @@ public final class AntarchyFabricContent {
).build());
FabricDefaultAttributeRegistry.register(MOLEWORM.get(), MolewormEntity.createAttributes().build());
FabricDefaultAttributeRegistry.register(MOLEVORE.get(), MolevoreEntity.createAttributes().build());
FabricDefaultAttributeRegistry.register(TERMITE.get(), buildAntAttributes(
AntarchySettings.termiteHealth(),
AntarchySettings.termiteMovementSpeed(),
AntarchySettings.termiteAttackDamage()
).build());
}
private static void registerSpawnPlacements() {
@@ -1819,6 +1842,7 @@ public final class AntarchyFabricContent {
SpawnPlacements.register(JUMPY_BUG.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, JumpyBugEntity::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);
SpawnPlacements.register(NIGHTMARE.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, NightmareEntity::canSpawn);
SpawnPlacements.register(MOLEWORM.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, MolewormEntity::canSpawn);
SpawnPlacements.register(MANTIS.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, MantisEntity::canSpawn);
@@ -1830,6 +1854,7 @@ public final class AntarchyFabricContent {
SpawnPlacements.register(BASILISK.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, BasiliskEntity::canSpawn);
SpawnPlacements.register(EMPEROR_SCORPION.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, EmperorScorpionEntity::canSpawn);
SpawnPlacements.register(TORETERROR.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, ToreterrorEntity::canSpawn);
SpawnPlacements.register(TERMITE.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, net.minecraft.world.entity.animal.Animal::checkAnimalSpawnRules);
}
private static void populateCreativeTab(CreativeModeTab.Output output) {
@@ -1918,11 +1943,11 @@ public final class AntarchyFabricContent {
case "dream_torch", "dream_lantern", "dream_campfire", "dream_fire", "dream_fire_ceiling" -> 10;
case "easter_bunny_spawn_egg", "flying_squirrel_spawn_egg", "caterpillar_spawn_egg",
"butterfly_spawn_egg", "reverie_spawn_egg", "brutalfly_spawn_egg",
"red_ant_spawn_egg", "brown_ant_spawn_egg", "rainbow_ant_spawn_egg",
"red_ant_spawn_egg", "brown_ant_spawn_egg", "rainbow_ant_spawn_egg", "termite_spawn_egg",
"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",
"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",
"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;
@@ -2324,6 +2349,7 @@ public final class AntarchyFabricContent {
DUCT_TAPE_USE
);
AntarchyObjects.setOctopusBomb(OCTOPUS_BOMB);
AntarchyObjects.bind(
EASTER_BUNNY,
FLYING_SQUIRREL,
@@ -53,6 +53,7 @@ public final class AntarchyFabricEvents {
ComposterBlock.COMPOSTABLES.put(AntarchyFabricContent.UMBRAL_MOSS_CARPET.get().asItem(), 0.3f);
ComposterBlock.COMPOSTABLES.put(AntarchyFabricContent.AMBER_MOSS_BLOCK.get().asItem(), 0.65f);
ComposterBlock.COMPOSTABLES.put(AntarchyFabricContent.AMBER_MOSS_CARPET.get().asItem(), 0.3f);
ComposterBlock.COMPOSTABLES.put(AntarchyFabricContent.CREEPVINE.get().asItem(), 0.3f);
ComposterBlock.COMPOSTABLES.put(AntarchyFabricContent.HUSHWEED.get().asItem(), 0.65f);
ComposterBlock.COMPOSTABLES.put(AntarchyFabricContent.CORNEA_EAR.get(), 0.65f);
@@ -73,6 +73,7 @@ public final class AntarchyFabricClientBootstrap {
EntityRendererRegistry.register(AntarchyFabricContent.RED_ANT.get(), AntRenderer::new);
EntityRendererRegistry.register(AntarchyFabricContent.BROWN_ANT.get(), AntRenderer::new);
EntityRendererRegistry.register(AntarchyFabricContent.RAINBOW_ANT.get(), AntRenderer::new);
EntityRendererRegistry.register(AntarchyFabricContent.TERMITE.get(), TermiteRenderer::new);
EntityRendererRegistry.register(AntarchyFabricContent.MOLEWORM.get(), MolewormRenderer::new);
EntityRendererRegistry.register(AntarchyFabricContent.MANTIS.get(), MantisRenderer::new);
EntityRendererRegistry.register(AntarchyFabricContent.MOLEVORE.get(), MolevoreRenderer::new);
@@ -87,6 +88,7 @@ public final class AntarchyFabricClientBootstrap {
EntityRendererRegistry.register(AntarchyFabricContent.CLOUD_SHARK.get(), CloudSharkRenderer::new);
EntityRendererRegistry.register(AntarchyFabricContent.KRAKEN.get(), KrakenRenderer::new);
EntityRendererRegistry.register(AntarchyFabricContent.MISSILE_SQUID.get(), MissileSquidRenderer::new);
EntityRendererRegistry.register(AntarchyFabricContent.OCTOPUS_BOMB.get(), OctopusBombRenderer::new);
EntityRendererRegistry.register(AntarchyFabricContent.NIGHTMARE.get(), NightmareRenderer::new);
EntityRendererRegistry.register(AntarchyFabricContent.LUCID.get(), LucidRenderer::new);
EntityRendererRegistry.register(AntarchyFabricContent.BED_BUG.get(), BedBugRenderer::new);
@@ -252,6 +252,7 @@ public class AntarchyNeoforge {
() -> AntarchyNeoforgeMisc.BLOODGLASS_MAX_HEARTS,
() -> AntarchyNeoforgeMisc.BLOODGLASS_WARD
);
AntarchyObjects.setOctopusBomb(AntarchyNeoforgeEntites.OCTOPUS_BOMB);
}
private static boolean isModLoaded(String modId) {
@@ -87,6 +87,7 @@ public final class AntarchyNeoForgeClient {
event.registerEntityRenderer(AntarchyNeoforgeEntites.RED_ANT.get(), context -> withParalyzedGeoLayer(new AntRenderer(context)));
event.registerEntityRenderer(AntarchyNeoforgeEntites.BROWN_ANT.get(), context -> withParalyzedGeoLayer(new AntRenderer(context)));
event.registerEntityRenderer(AntarchyNeoforgeEntites.RAINBOW_ANT.get(), context -> withParalyzedGeoLayer(new AntRenderer(context)));
event.registerEntityRenderer(AntarchyNeoforgeEntites.TERMITE.get(), context -> withParalyzedGeoLayer(new TermiteRenderer(context)));
event.registerEntityRenderer(AntarchyNeoforgeEntites.MOLEWORM.get(), context -> withParalyzedGeoLayer(new MolewormRenderer(context)));
event.registerEntityRenderer(AntarchyNeoforgeEntites.MANTIS.get(), context -> withParalyzedGeoLayer(new MantisRenderer(context)));
event.registerEntityRenderer(AntarchyNeoforgeEntites.MOLEVORE.get(), context -> withParalyzedGeoLayer(new MolevoreRenderer(context)));
@@ -101,6 +102,7 @@ public final class AntarchyNeoForgeClient {
event.registerEntityRenderer(AntarchyNeoforgeEntites.CLOUD_SHARK.get(), context -> withParalyzedGeoLayer(new CloudSharkRenderer(context)));
event.registerEntityRenderer(AntarchyNeoforgeEntites.KRAKEN.get(), context -> withParalyzedGeoLayer(new KrakenRenderer(context)));
event.registerEntityRenderer(AntarchyNeoforgeEntites.MISSILE_SQUID.get(), context -> withParalyzedGeoLayer(new MissileSquidRenderer(context)));
event.registerEntityRenderer(AntarchyNeoforgeEntites.OCTOPUS_BOMB.get(), context -> withParalyzedGeoLayer(new OctopusBombRenderer(context)));
event.registerEntityRenderer(AntarchyNeoforgeEntites.NIGHTMARE.get(), context -> withParalyzedGeoLayer(new NightmareRenderer(context)));
event.registerEntityRenderer(AntarchyNeoforgeEntites.LUCID.get(), context -> withParalyzedGeoLayer(new LucidRenderer(context)));
event.registerEntityRenderer(AntarchyNeoforgeEntites.BED_BUG.get(), context -> withParalyzedGeoLayer(new BedBugRenderer(context)));
@@ -1126,6 +1126,7 @@ public final class AntarchyNeoForgeEvents {
ComposterBlock.COMPOSTABLES.put(AntarchyNeoforgeBlocks.UMBRAL_MOSS_CARPET.get().asItem(), 0.3f);
ComposterBlock.COMPOSTABLES.put(AntarchyNeoforgeBlocks.AMBER_MOSS_BLOCK.get().asItem(), 0.65f);
ComposterBlock.COMPOSTABLES.put(AntarchyNeoforgeBlocks.AMBER_MOSS_CARPET.get().asItem(), 0.3f);
ComposterBlock.COMPOSTABLES.put(AntarchyNeoforgeBlocks.CREEPVINE.get().asItem(), 0.3f);
ComposterBlock.COMPOSTABLES.put(AntarchyNeoforgeBlocks.HUSHWEED.get().asItem(), 0.65f);
ComposterBlock.COMPOSTABLES.put(AntarchyNeoforgeItems.CORNEA_EAR.get(), 0.65f);
});
@@ -240,6 +240,8 @@ public final class AntarchyNeoforgeBlocks {
() -> new AntNestBlock(AntarchyNeoforgeEntites.BROWN_ANT, AntarchyNeoforgeItems::antNestBlockEntityType, BlockBehaviour.Properties.ofFullCopy(Blocks.DIRT).noLootTable()));
public static final DeferredBlock<AntNestBlock> RAINBOW_ANT_NEST = BLOCKS.register("rainbow_ant_nest",
() -> new AntNestBlock(AntarchyNeoforgeEntites.RAINBOW_ANT, AntarchyNeoforgeItems::antNestBlockEntityType, BlockBehaviour.Properties.ofFullCopy(Blocks.DIRT).noLootTable()));
public static final DeferredBlock<AntNestBlock> TERMITE_NEST = BLOCKS.register("termite_nest",
() -> new AntNestBlock(AntarchyNeoforgeEntites.TERMITE, AntarchyNeoforgeItems::antNestBlockEntityType, BlockBehaviour.Properties.ofFullCopy(Blocks.DIRT).noLootTable()));
public static final DeferredBlock<Block> URANIUM_ORE = BLOCKS.register("uranium_ore",
() -> createOre(Blocks.EMERALD_ORE, 4, 8));
public static final DeferredBlock<Block> DEEPSLATE_URANIUM_ORE = BLOCKS.register("deepslate_uranium_ore",
@@ -350,7 +352,8 @@ public final class AntarchyNeoforgeBlocks {
AntNestBlockEntity::new,
RED_ANT_NEST.get(),
BROWN_ANT_NEST.get(),
RAINBOW_ANT_NEST.get()
RAINBOW_ANT_NEST.get(),
TERMITE_NEST.get()
).build(null));
public static final DeferredHolder<BlockEntityType<?>, BlockEntityType<DreamCampfireBlockEntity>> DREAM_CAMPFIRE_BLOCK_ENTITY = BLOCK_ENTITY_TYPES.register("dream_campfire",
() -> BlockEntityType.Builder.of(
@@ -57,6 +57,7 @@ public class AntarchyNeoforgeCreativeModeTabs {
event.accept(AntarchyNeoforgeItems.RED_ANT_SPAWN_EGG.get());
event.accept(AntarchyNeoforgeItems.BROWN_ANT_SPAWN_EGG.get());
event.accept(AntarchyNeoforgeItems.RAINBOW_ANT_SPAWN_EGG.get());
event.accept(AntarchyNeoforgeItems.TERMITE_SPAWN_EGG.get());
event.accept(AntarchyNeoforgeItems.MOLEWORM_SPAWN_EGG.get());
event.accept(AntarchyNeoforgeItems.MANTIS_SPAWN_EGG.get());
event.accept(AntarchyNeoforgeItems.MOLEVORE_SPAWN_EGG.get());
@@ -72,6 +73,7 @@ public class AntarchyNeoforgeCreativeModeTabs {
event.accept(AntarchyNeoforgeItems.CLOUD_SHARK_SPAWN_EGG.get());
event.accept(AntarchyNeoforgeItems.KRAKEN_SPAWN_EGG.get());
event.accept(AntarchyNeoforgeItems.MISSILE_SQUID_SPAWN_EGG.get());
event.accept(AntarchyNeoforgeItems.OCTOPUS_BOMB_SPAWN_EGG.get());
event.accept(AntarchyNeoforgeItems.NIGHTMARE_SPAWN_EGG.get());
event.accept(AntarchyNeoforgeItems.BED_BUG_SPAWN_EGG.get());
event.accept(AntarchyNeoforgeItems.LUCID_SPAWN_EGG.get());
@@ -104,6 +106,7 @@ public class AntarchyNeoforgeCreativeModeTabs {
event.accept(AntarchyNeoforgeItems.RED_ANT_NEST_ITEM.get());
event.accept(AntarchyNeoforgeItems.BROWN_ANT_NEST_ITEM.get());
event.accept(AntarchyNeoforgeItems.RAINBOW_ANT_NEST_ITEM.get());
event.accept(AntarchyNeoforgeItems.TERMITE_NEST_ITEM.get());
event.accept(AntarchyNeoforgeItems.URANIUM_ORE_ITEM.get());
event.accept(AntarchyNeoforgeItems.DEEPSLATE_URANIUM_ORE_ITEM.get());
event.accept(AntarchyNeoforgeItems.TITANIUM_ORE_ITEM.get());
@@ -385,7 +388,7 @@ public class AntarchyNeoforgeCreativeModeTabs {
// 11 - Plants and flowers
case "orange_milkweed", "pink_milkweed", "torchflower_bush", "hushweed", "amber_lichen", "creepvine",
"triffid_goo_block", "wasp_nest",
"red_ant_nest", "brown_ant_nest", "rainbow_ant_nest" -> 11;
"red_ant_nest", "brown_ant_nest", "rainbow_ant_nest", "termite_nest" -> 11;
// 12 - Dream lighting
case "dream_torch", "dream_lantern", "dream_campfire" -> 12;
@@ -18,6 +18,7 @@ import com.craisinlord.antarchy.content.entity.HushProjectileEntity;
import com.craisinlord.antarchy.content.entity.JumpyBugEntity;
import com.craisinlord.antarchy.content.entity.MantisEntity;
import com.craisinlord.antarchy.content.entity.MissileSquidEntity;
import com.craisinlord.antarchy.content.entity.OctopusBombEntity;
import com.craisinlord.antarchy.content.entity.MolevoreEntity;
import com.craisinlord.antarchy.content.entity.MolewormEntity;
import com.craisinlord.antarchy.content.entity.OuranwoodBoatEntity;
@@ -33,6 +34,7 @@ import com.craisinlord.antarchy.content.entity.ant.BaseAntEntity;
import com.craisinlord.antarchy.content.entity.ant.BrownAntEntity;
import com.craisinlord.antarchy.content.entity.ant.RainbowAntEntity;
import com.craisinlord.antarchy.content.entity.ant.RedAntEntity;
import com.craisinlord.antarchy.content.entity.ant.TermiteEntity;
import com.craisinlord.antarchy.content.entity.basilisk.BasiliskEntity;
import com.craisinlord.antarchy.content.entity.brutalfly.BrutalflyEntity;
import com.craisinlord.antarchy.content.entity.brutalfly.BrutalflyOrbEntity;
@@ -74,6 +76,8 @@ public final class AntarchyNeoforgeEntites {
() -> buildAntType(BrownAntEntity::new, MobCategory.CREATURE, "brown_ant"));
public static final DeferredHolder<EntityType<?>, EntityType<RainbowAntEntity>> RAINBOW_ANT = ENTITY_TYPES.register("rainbow_ant",
() -> buildAntType(RainbowAntEntity::new, MobCategory.CREATURE, "rainbow_ant"));
public static final DeferredHolder<EntityType<?>, EntityType<TermiteEntity>> TERMITE = ENTITY_TYPES.register("termite",
() -> buildAntType(TermiteEntity::new, MobCategory.CREATURE, "termite"));
public static final DeferredHolder<EntityType<?>, EntityType<MolewormEntity>> MOLEWORM = ENTITY_TYPES.register("moleworm",
() -> EntityType.Builder.of(MolewormEntity::new, MobCategory.MONSTER)
.sized(0.4F, 0.3F)
@@ -199,7 +203,7 @@ public final class AntarchyNeoforgeEntites {
.build("cloud_shark"));
public static final DeferredHolder<EntityType<?>, EntityType<KrakenEntity>> KRAKEN = ENTITY_TYPES.register("kraken",
() -> EntityType.Builder.of(KrakenEntity::new, MobCategory.MONSTER)
.sized(5.2F, 9.8F)
.sized(11.4F, 39.0F)
.clientTrackingRange(12)
.build("kraken"));
public static final DeferredHolder<EntityType<?>, EntityType<MissileSquidEntity>> MISSILE_SQUID = ENTITY_TYPES.register("missile_squid",
@@ -207,6 +211,11 @@ public final class AntarchyNeoforgeEntites {
.sized(1.62F, 3.18F)
.clientTrackingRange(10)
.build("missile_squid"));
public static final DeferredHolder<EntityType<?>, EntityType<OctopusBombEntity>> OCTOPUS_BOMB = ENTITY_TYPES.register("octopus_bomb",
() -> EntityType.Builder.of(OctopusBombEntity::new, MobCategory.MONSTER)
.sized(2.4F, 2.9F)
.clientTrackingRange(10)
.build("octopus_bomb"));
public static final DeferredHolder<EntityType<?>, EntityType<NightmareEntity>> NIGHTMARE = ENTITY_TYPES.register("nightmare",
() -> EntityType.Builder.of(NightmareEntity::new, MobCategory.MONSTER)
.sized(3.2F, 3.8F)
@@ -44,6 +44,7 @@ public class AntarchyNeoforgeEntityAttributes {
event.put(AntarchyNeoforgeEntites.CLOUD_SHARK.get(), CloudSharkEntity.createAttributes().build());
event.put(AntarchyNeoforgeEntites.KRAKEN.get(), KrakenEntity.createAttributes().build());
event.put(AntarchyNeoforgeEntites.MISSILE_SQUID.get(), MissileSquidEntity.createAttributes().build());
event.put(AntarchyNeoforgeEntites.OCTOPUS_BOMB.get(), OctopusBombEntity.createAttributes().build());
event.put(AntarchyNeoforgeEntites.NIGHTMARE.get(), NightmareEntity.createAttributes().build());
event.put(AntarchyNeoforgeEntites.BED_BUG.get(), BedBugEntity.createAttributes().build());
event.put(AntarchyNeoforgeEntites.STINK_BUG.get(), StinkBugEntity.createAttributes().build());
@@ -67,6 +68,7 @@ public class AntarchyNeoforgeEntityAttributes {
event.put(AntarchyNeoforgeEntites.RED_ANT.get(), redAntAttributes);
event.put(AntarchyNeoforgeEntites.BROWN_ANT.get(), brownAntAttributes);
event.put(AntarchyNeoforgeEntites.RAINBOW_ANT.get(), rainbowAntAttributes);
event.put(AntarchyNeoforgeEntites.TERMITE.get(), termiteAttributes);
event.put(AntarchyNeoforgeEntites.MOLEWORM.get(), MolewormEntity.createAttributes().build());
event.put(AntarchyNeoforgeEntites.MOLEVORE.get(), MolevoreEntity.createAttributes().build());
}
@@ -173,6 +173,7 @@ public final class AntarchyNeoforgeItems {
public static final DeferredItem<net.minecraft.world.item.BlockItem> RED_ANT_NEST_ITEM = ITEMS.registerSimpleBlockItem(AntarchyNeoforgeBlocks.RED_ANT_NEST);
public static final DeferredItem<net.minecraft.world.item.BlockItem> BROWN_ANT_NEST_ITEM = ITEMS.registerSimpleBlockItem(AntarchyNeoforgeBlocks.BROWN_ANT_NEST);
public static final DeferredItem<net.minecraft.world.item.BlockItem> RAINBOW_ANT_NEST_ITEM = ITEMS.registerSimpleBlockItem(AntarchyNeoforgeBlocks.RAINBOW_ANT_NEST);
public static final DeferredItem<net.minecraft.world.item.BlockItem> TERMITE_NEST_ITEM = ITEMS.registerSimpleBlockItem(AntarchyNeoforgeBlocks.TERMITE_NEST);
public static final DeferredItem<net.minecraft.world.item.BlockItem> URANIUM_ORE_ITEM = ITEMS.registerSimpleBlockItem(AntarchyNeoforgeBlocks.URANIUM_ORE);
public static final DeferredItem<net.minecraft.world.item.BlockItem> DEEPSLATE_URANIUM_ORE_ITEM = ITEMS.registerSimpleBlockItem(AntarchyNeoforgeBlocks.DEEPSLATE_URANIUM_ORE);
public static final DeferredItem<net.minecraft.world.item.BlockItem> TITANIUM_ORE_ITEM = ITEMS.registerSimpleBlockItem(AntarchyNeoforgeBlocks.TITANIUM_ORE);
@@ -501,6 +502,8 @@ public final class AntarchyNeoforgeItems {
() -> new DeferredSpawnEggItem(AntarchyNeoforgeEntites.BROWN_ANT, 0x6A4320, 0x26160A, new Item.Properties()));
public static final DeferredItem<DeferredSpawnEggItem> RAINBOW_ANT_SPAWN_EGG = ITEMS.register("rainbow_ant_spawn_egg",
() -> new DeferredSpawnEggItem(AntarchyNeoforgeEntites.RAINBOW_ANT, 0x56D4F0, 0xF66DBB, new Item.Properties()));
public static final DeferredItem<DeferredSpawnEggItem> TERMITE_SPAWN_EGG = ITEMS.register("termite_spawn_egg",
() -> new DeferredSpawnEggItem(AntarchyNeoforgeEntites.TERMITE, 0xE8DFC0, 0x5C3C1A, new Item.Properties()));
public static final DeferredItem<DeferredSpawnEggItem> MOLEWORM_SPAWN_EGG = ITEMS.register("moleworm_spawn_egg",
() -> new DeferredSpawnEggItem(AntarchyNeoforgeEntites.MOLEWORM, 0x7A6150, 0xD2B8A3, new Item.Properties()));
public static final DeferredItem<DeferredSpawnEggItem> MANTIS_SPAWN_EGG = ITEMS.register("mantis_spawn_egg",
@@ -531,6 +534,8 @@ public final class AntarchyNeoforgeItems {
() -> new DeferredSpawnEggItem(AntarchyNeoforgeEntites.KRAKEN, 0x163C53, 0x4F8E99, new Item.Properties().rarity(Rarity.EPIC)));
public static final DeferredItem<DeferredSpawnEggItem> MISSILE_SQUID_SPAWN_EGG = ITEMS.register("missile_squid_spawn_egg",
() -> new DeferredSpawnEggItem(AntarchyNeoforgeEntites.MISSILE_SQUID, 0xD88FA7, 0x8D5269, new Item.Properties().rarity(Rarity.UNCOMMON)));
public static final DeferredItem<DeferredSpawnEggItem> OCTOPUS_BOMB_SPAWN_EGG = ITEMS.register("octopus_bomb_spawn_egg",
() -> new DeferredSpawnEggItem(AntarchyNeoforgeEntites.OCTOPUS_BOMB, 0xC882C8, 0x5C1A7A, new Item.Properties().rarity(Rarity.UNCOMMON)));
public static final DeferredItem<DeferredSpawnEggItem> NIGHTMARE_SPAWN_EGG = ITEMS.register("nightmare_spawn_egg",
() -> new DeferredSpawnEggItem(AntarchyNeoforgeEntites.NIGHTMARE, 0x22121C, 0xB51B2D, new Item.Properties().rarity(Rarity.RARE)));
public static final DeferredItem<DeferredSpawnEggItem> BED_BUG_SPAWN_EGG = ITEMS.register("bed_bug_spawn_egg",
@@ -36,6 +36,7 @@ public class AntarchyNeoforgeSpawnPlacements {
event.register(AntarchyNeoforgeEntites.JUMPY_BUG.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, JumpyBugEntity::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);
event.register(AntarchyNeoforgeEntites.NIGHTMARE.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, NightmareEntity::canSpawn, RegisterSpawnPlacementsEvent.Operation.OR);
event.register(AntarchyNeoforgeEntites.MOLEWORM.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, MolewormEntity::canSpawn, RegisterSpawnPlacementsEvent.Operation.OR);
event.register(AntarchyNeoforgeEntites.MANTIS.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, MantisEntity::canSpawn, RegisterSpawnPlacementsEvent.Operation.OR);
@@ -46,5 +47,6 @@ public class AntarchyNeoforgeSpawnPlacements {
event.register(AntarchyNeoforgeEntites.SCORPION.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, ScorpionEntity::canSpawn, RegisterSpawnPlacementsEvent.Operation.OR);
event.register(AntarchyNeoforgeEntites.BASILISK.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, BasiliskEntity::canSpawn, RegisterSpawnPlacementsEvent.Operation.OR);
event.register(AntarchyNeoforgeEntites.EMPEROR_SCORPION.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, EmperorScorpionEntity::canSpawn, RegisterSpawnPlacementsEvent.Operation.OR);
event.register(AntarchyNeoforgeEntites.TERMITE.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, net.minecraft.world.entity.animal.Animal::checkAnimalSpawnRules, RegisterSpawnPlacementsEvent.Operation.OR);
}
}