1.1.1 release

New Structures
Temple of Technoblade
Basilisk lair

Small Changes
Added Nightmare fire flame bite particle
Overhauled Size Ray Sounds

Bug Fixes
Made Lucid nearby entity scans more performant
Fixed duct tape stickiness causes TPS problems even when not placed (oopsies)
Fixed Ruined Prison and Stampy’s house having broken trial spawners
Fixed gravity gun duping doors
Fixed permanent portals sometimes generating one-way returns
Fixed full Nightmare set wither/dread immunity
Fixed shoulder-perched Flying Squirrels pushing players around
Fixed permanent portals failing to activate when frame corners were filled
Fixed Jumpy Bug never hanging from ceiling
This commit is contained in:
craisinlord committed 2026-08-09 22:47:44 -05:00
1 parent de529b54c2
commit 6f47e59ff0
107 files changed
+3192 -288

No files matched your search

+1 -1
View File
@@ -1 +1 @@
ALL RIGHTS RESERVD UNLESS EXPLICITY STATED
ALL RIGHTS RESERVED UNLESS OTHERWISE STATED
-3
View File
@@ -1,6 +1,3 @@
https://www.curseforge.com/minecraft/mc-mods/antarchy
ANTS! ANTS! ANTS!
also I have no clue why Claude is listed as a contributor, this mod was not created by AI. I can't figure out how to get rid of it lol
@@ -290,7 +290,7 @@ public final class AntarchySettings {
private static int emperorScorpionMaxSummonedScorpions = 4;
private static int emperorScorpionMaxNearbyScorpions = 4;
private static int emperorScorpionHardenCooldownTicks = 2400;
private static double emperorScorpionDamageRange = 80.0D;
private static double emperorScorpionDamageRange = 25.0D;
private static int emperorScorpionMinDespawnTicks = 6000;
private static double scorpionHealth = 30.0D;
private static double scorpionAttackDamage = 5.0D;
@@ -322,11 +322,11 @@ public final class AntarchySettings {
private static double krakenProjectileDamageTakenMultiplier = 0.5D;
private static double krakenBossBarRange = 40.0D;
private static double krakenFollowRange = 96.0D;
private static double krakenDamageRange = 96.0D;
private static double herculesBeetleDamageRange = 48.0D;
private static double toreterrorDamageRange = 48.0D;
private static double brutalflyDamageRange = 48.0D;
private static double alphaMantisDamageRange = 48.0D;
private static double krakenDamageRange = 35.0D;
private static double herculesBeetleDamageRange = 25.0D;
private static double toreterrorDamageRange = 25.0D;
private static double brutalflyDamageRange = 25.0D;
private static double alphaMantisDamageRange = 25.0D;
private static float krakenLightningDamagePhaseOne = 6.0F;
private static double lucidHealth = 30.0D;
private static double lucidAttackDamage = 4.0D;
@@ -331,6 +331,8 @@ public final class AntarchyObjects {
@SuppressWarnings("unchecked")
public static Supplier<SimpleParticleType> STINKY_GAS = (Supplier<SimpleParticleType>) UNBOUND;
@SuppressWarnings("unchecked")
public static Supplier<SimpleParticleType> NIGHTMARE_FIRE_FLAME = (Supplier<SimpleParticleType>) UNBOUND;
@SuppressWarnings("unchecked")
public static Supplier<SimpleParticleType> STINKY_FLY = (Supplier<SimpleParticleType>) UNBOUND;
@SuppressWarnings("unchecked")
public static Supplier<SimpleParticleType> PEACH_LEAVES_PARTICLE = (Supplier<SimpleParticleType>) UNBOUND;
@@ -707,6 +709,10 @@ public final class AntarchyObjects {
LOTUS_POLLEN = supplier;
}
public static void setNightmareFireFlame(Supplier<SimpleParticleType> supplier) {
NIGHTMARE_FIRE_FLAME = supplier;
}
public static void setLucidBoltImpactSmall(Supplier<SimpleParticleType> supplier) {
LUCID_BOLT_IMPACT_SMALL = supplier;
}
@@ -10,9 +10,13 @@ public final class AntarchySoundEvents {
};
public static Supplier<SoundEvent> SQUIDZOOKA_FIRE = (Supplier<SoundEvent>) UNBOUND;
public static Supplier<SoundEvent> SHRINK_RAY_SOUND = (Supplier<SoundEvent>) UNBOUND;
public static Supplier<SoundEvent> GROWTH_RAY_SOUND = (Supplier<SoundEvent>) UNBOUND;
public static Supplier<SoundEvent> SIZE_RAY_CHARGE = (Supplier<SoundEvent>) UNBOUND;
public static Supplier<SoundEvent> SHRINK_RAY_CHARGE = (Supplier<SoundEvent>) UNBOUND;
public static Supplier<SoundEvent> SHRINK_RAY_LOOP = (Supplier<SoundEvent>) UNBOUND;
public static Supplier<SoundEvent> GROWTH_RAY_CHARGE = (Supplier<SoundEvent>) UNBOUND;
public static Supplier<SoundEvent> GROWTH_RAY_LOOP = (Supplier<SoundEvent>) UNBOUND;
public static Supplier<SoundEvent> SIZE_RAY_WEAKSHOT = (Supplier<SoundEvent>) UNBOUND;
public static Supplier<SoundEvent> SIZE_RAY_MEDIUMSHOT = (Supplier<SoundEvent>) UNBOUND;
public static Supplier<SoundEvent> SIZE_RAY_CRITSHOT = (Supplier<SoundEvent>) UNBOUND;
public static Supplier<SoundEvent> ANT_AMBIENT = (Supplier<SoundEvent>) UNBOUND;
public static Supplier<SoundEvent> ANT_IDLE = (Supplier<SoundEvent>) UNBOUND;
public static Supplier<SoundEvent> ANT_HURT = (Supplier<SoundEvent>) UNBOUND;
@@ -175,9 +179,13 @@ public final class AntarchySoundEvents {
public static void bind(
Supplier<SoundEvent> squidzookaFire,
Supplier<SoundEvent> shrinkRaySound,
Supplier<SoundEvent> growthRaySound,
Supplier<SoundEvent> sizeRayCharge,
Supplier<SoundEvent> shrinkRayCharge,
Supplier<SoundEvent> shrinkRayLoop,
Supplier<SoundEvent> growthRayCharge,
Supplier<SoundEvent> growthRayLoop,
Supplier<SoundEvent> sizeRayWeakshot,
Supplier<SoundEvent> sizeRayMediumshot,
Supplier<SoundEvent> sizeRayCritshot,
Supplier<SoundEvent> antAmbient,
Supplier<SoundEvent> antIdle,
Supplier<SoundEvent> antHurt,
@@ -336,9 +344,13 @@ public final class AntarchySoundEvents {
Supplier<SoundEvent> jerryAdultAttack
) {
SQUIDZOOKA_FIRE = squidzookaFire;
SHRINK_RAY_SOUND = shrinkRaySound;
GROWTH_RAY_SOUND = growthRaySound;
SIZE_RAY_CHARGE = sizeRayCharge;
SHRINK_RAY_CHARGE = shrinkRayCharge;
SHRINK_RAY_LOOP = shrinkRayLoop;
GROWTH_RAY_CHARGE = growthRayCharge;
GROWTH_RAY_LOOP = growthRayLoop;
SIZE_RAY_WEAKSHOT = sizeRayWeakshot;
SIZE_RAY_MEDIUMSHOT = sizeRayMediumshot;
SIZE_RAY_CRITSHOT = sizeRayCritshot;
ANT_AMBIENT = antAmbient;
ANT_IDLE = antIdle;
ANT_HURT = antHurt;
@@ -63,6 +63,10 @@ public class DuctTapeBlock extends Block {
private static final double WALL_SIDE_PAD = 0.08D;
private static final double WALL_INNER_INSET = 0.03D;
private static final double TRIGGER_INFLATE_DEFAULT = 0.15D;
private static final int SEARCH_INTERVAL_TICKS = 4;
private static final double SEARCH_MOTION_THRESHOLD_SQR = 1.0E-8D;
private static final double SEARCH_PAD_XZ = Math.max(WALL_TRIGGER_DEPTH, TRIGGER_PAD);
private static final double SEARCH_PAD_Y = FLOOR_TRIGGER_HEIGHT;
private static final Map<UUID, Long> STICK_SOUND_TIMES = new HashMap<>();
private static final Map<UUID, String> STICK_CONTACT_KEYS = new HashMap<>();
@@ -306,6 +310,10 @@ public class DuctTapeBlock extends Block {
releaseEntity(entity);
}
if (!shouldSearchForTape(entity)) {
return;
}
TapeHit hit = findTouchedTape(entity.level(), entity);
if (hit == null) {
if (entity.isNoGravity()) {
@@ -342,6 +350,23 @@ public class DuctTapeBlock extends Block {
return findTouchedTape(level, entity) != null;
}
public static boolean shouldTickStuckEntity(Entity entity) {
if (entity == null || entity.level().isClientSide() || isStickyBlacklist(entity)) {
return false;
}
if (!entity.isAlive() || entity.isRemoved()) {
return true;
}
StuckContact contact = STUCK_ENTITIES.get(entity.getUUID());
if (contact != null) {
return true;
}
return shouldSearchForTape(entity);
}
private static boolean isStickyBlacklist(Entity entity) {
return entity != null && entity.getType().is(AntarchyTags.Entities.DUCT_TAPE_STICK_BLACKLIST);
}
@@ -418,16 +443,31 @@ public class DuctTapeBlock extends Block {
&& tapeKey(level, pos).equals(contact.tapeKey());
}
private static boolean shouldSearchForTape(Entity entity) {
Vec3 velocity = entity.getDeltaMovement();
if (velocity.lengthSqr() < SEARCH_MOTION_THRESHOLD_SQR) {
return false;
}
return (entity.tickCount + entity.getId()) % SEARCH_INTERVAL_TICKS == 0;
}
private static TapeHit findTouchedTape(Level level, Entity entity) {
AABB box = entity.getBoundingBox().inflate(0.30D);
AABB box = entity.getBoundingBox().inflate(SEARCH_PAD_XZ, SEARCH_PAD_Y, SEARCH_PAD_XZ);
BlockPos min = BlockPos.containing(box.minX, box.minY, box.minZ);
BlockPos max = BlockPos.containing(box.maxX, box.maxY, box.maxZ);
if (!level.hasChunksAt(min, max)) {
return null;
}
BlockPos.MutableBlockPos cursor = new BlockPos.MutableBlockPos();
for (int x = min.getX(); x <= max.getX(); x++) {
for (int y = min.getY(); y <= max.getY(); y++) {
for (int z = min.getZ(); z <= max.getZ(); z++) {
cursor.set(x, y, z);
BlockState state = level.getBlockState(cursor);
if (state.isAir()) {
continue;
}
if (state.getBlock() instanceof DuctTapeBlock && touchesTape(level, entity, cursor, state)) {
return new TapeHit(cursor.immutable(), state);
}
@@ -6,6 +6,7 @@ import com.craisinlord.antarchy.content.AntarchyTags;
import com.craisinlord.antarchy.content.boss.BossCombatUtil;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerBossEvent;
import net.minecraft.server.level.ServerLevel;
@@ -21,20 +22,37 @@ import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.MobSpawnType;
import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.ai.goal.MeleeAttackGoal;
import net.minecraft.world.entity.monster.Monster;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.ServerLevelAccessor;
import net.minecraft.world.level.block.LeavesBlock;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.Nullable;
public class AlphaMantisEntity extends MantisEntity {
private static final double ALPHA_ATTACK_START_RANGE = 6.0D;
private static final double ALPHA_ATTACK_HIT_REACH = 7.25D;
private static final double ALPHA_ATTACK_HALF_WIDTH = 3.5D;
private static final double ALPHA_ATTACK_VERTICAL_TOLERANCE = 4.25D;
private static final int PHASE_TRANSITION_TICKS = 35;
private static final double ENCOUNTER_HOME_RADIUS = 72.0D;
private static final double ENCOUNTER_LEASH_RADIUS = 96.0D;
private static final double FORCED_RETURN_RADIUS = 144.0D;
private static final int RESET_DELAY_TICKS = 300;
private static final double HOME_RETURN_SPEED = 1.05D;
private final ServerBossEvent bossEvent =
new com.craisinlord.antarchy.content.boss.EntityLinkedServerBossEvent(this.getUUID(), Component.translatable("entity.antarchy.alpha_mantis"), BossEvent.BossBarColor.GREEN, BossEvent.BossBarOverlay.PROGRESS);
private int summonCooldownTicks;
private int phaseTransitionTicks;
private int disengageTicks;
private boolean halfHealthTransitionComplete;
@Nullable
private BlockPos encounterHome;
public AlphaMantisEntity(EntityType<? extends AlphaMantisEntity> entityType, Level level) {
super(entityType, level);
@@ -55,7 +73,7 @@ public class AlphaMantisEntity extends MantisEntity {
@Override
public boolean isInvulnerableTo(DamageSource source) {
if (super.isInvulnerableTo(source)) {
if (this.phaseTransitionTicks > 0 || super.isInvulnerableTo(source)) {
return true;
}
return BossCombatUtil.isOutOfDamageRange(this, AntarchySettings.alphaMantisDamageRange());
@@ -66,7 +84,7 @@ public class AlphaMantisEntity extends MantisEntity {
float preHealth = this.getHealth();
boolean hurt = super.hurt(source, amount);
if (hurt) {
BossCombatUtil.clampHalfHealthCrossing(this, preHealth);
this.handleHalfHealthGate(preHealth);
}
return hurt;
}
@@ -114,13 +132,33 @@ public class AlphaMantisEntity extends MantisEntity {
}
@Override
protected MeleeAttackGoal createCombatGoal() {
return new MeleeAttackGoal(this, this.getCombatSpeed(), true);
protected double getCombatSpeed() {
return 1.05D;
}
@Override
protected double getCombatSpeed() {
return 1.05D;
protected double getAttackStartRange() {
return ALPHA_ATTACK_START_RANGE;
}
@Override
protected double getAttackHitReach() {
return ALPHA_ATTACK_HIT_REACH;
}
@Override
protected double getAttackHalfWidth() {
return ALPHA_ATTACK_HALF_WIDTH;
}
@Override
protected double getAttackVerticalTolerance() {
return ALPHA_ATTACK_VERTICAL_TOLERANCE;
}
@Override
protected boolean canBeginCommittedAttack(LivingEntity target) {
return this.phaseTransitionTicks <= 0 && super.canBeginCommittedAttack(target);
}
@Override
@@ -155,11 +193,18 @@ public class AlphaMantisEntity extends MantisEntity {
return;
}
this.tickEncounterState();
this.tickPhaseTransition();
this.bossEvent.setProgress(this.getHealth() / this.getMaxHealth());
this.bossEvent.setVisible(this.shouldShowBossBar());
this.tickMinionSummon();
}
private void tickMinionSummon() {
if (this.phaseTransitionTicks > 0) {
return;
}
LivingEntity target = this.getTarget();
if (target == null || !target.isAlive()) {
return;
@@ -244,4 +289,177 @@ public class AlphaMantisEntity extends MantisEntity {
super.setCustomName(name);
this.bossEvent.setName(this.getDisplayName());
}
@Override
public void addAdditionalSaveData(CompoundTag tag) {
super.addAdditionalSaveData(tag);
tag.putInt("SummonCooldownTicks", this.summonCooldownTicks);
tag.putBoolean("HalfHealthTransitionComplete", this.halfHealthTransitionComplete);
if (this.encounterHome != null) {
tag.putInt("EncounterHomeX", this.encounterHome.getX());
tag.putInt("EncounterHomeY", this.encounterHome.getY());
tag.putInt("EncounterHomeZ", this.encounterHome.getZ());
}
}
@Override
public void readAdditionalSaveData(CompoundTag tag) {
super.readAdditionalSaveData(tag);
if (tag.contains("SummonCooldownTicks")) {
this.summonCooldownTicks = Math.max(0, tag.getInt("SummonCooldownTicks"));
}
if (tag.contains("HalfHealthTransitionComplete")) {
this.halfHealthTransitionComplete = tag.getBoolean("HalfHealthTransitionComplete");
}
if (tag.contains("EncounterHomeX") && tag.contains("EncounterHomeY") && tag.contains("EncounterHomeZ")) {
this.encounterHome = new BlockPos(tag.getInt("EncounterHomeX"), tag.getInt("EncounterHomeY"), tag.getInt("EncounterHomeZ"));
}
this.phaseTransitionTicks = 0;
this.disengageTicks = 0;
this.finishCommittedAttack();
this.stopFlightBurst();
}
@Override
public void remove(RemovalReason reason) {
super.remove(reason);
this.bossEvent.removeAllPlayers();
}
private void handleHalfHealthGate(float preHitHealth) {
float halfHealth = this.getMaxHealth() * 0.5F;
if (!this.halfHealthTransitionComplete && preHitHealth > halfHealth && this.getHealth() < halfHealth) {
this.setHealth(halfHealth);
this.beginHalfHealthTransition();
}
}
private void beginHalfHealthTransition() {
this.halfHealthTransitionComplete = true;
this.phaseTransitionTicks = PHASE_TRANSITION_TICKS;
this.finishCommittedAttack();
this.stopFlightBurst();
this.getNavigation().stop();
this.setDeltaMovement(0.0D, this.getDeltaMovement().y, 0.0D);
this.setAggressive(false);
this.summonCooldownTicks = Math.min(this.summonCooldownTicks, AntarchySettings.alphaMantisSummonIntervalTicks() / 2);
}
private void tickPhaseTransition() {
if (this.phaseTransitionTicks <= 0) {
return;
}
this.phaseTransitionTicks--;
this.getNavigation().stop();
this.setDeltaMovement(0.0D, this.getDeltaMovement().y, 0.0D);
if (this.phaseTransitionTicks <= 0 && this.getTarget() != null) {
this.setAggressive(true);
}
}
private void tickEncounterState() {
if (this.encounterHome == null) {
this.encounterHome = this.blockPosition();
}
LivingEntity target = this.getTarget();
if (!this.isValidEncounterTarget(target)) {
if (target != null) {
this.setTarget(null);
}
target = null;
}
if (target != null) {
this.disengageTicks = 0;
if (this.isOutsideLeashRadius()) {
this.resetEncounter(true);
}
return;
}
if (this.isAttackLocked() || this.phaseTransitionTicks > 0) {
return;
}
if (!this.isAtEncounterHome()) {
this.disengageTicks++;
if (this.disengageTicks >= RESET_DELAY_TICKS) {
this.resetEncounter(true);
} else {
this.navigateHome();
}
return;
}
this.disengageTicks = 0;
}
private boolean isValidEncounterTarget(@Nullable LivingEntity target) {
if (target == null || !target.isAlive() || !target.level().equals(this.level())) {
return false;
}
if (target instanceof Player player && (player.isCreative() || player.isSpectator())) {
return false;
}
if (this.encounterHome == null) {
return true;
}
return target.distanceToSqr(Vec3.atCenterOf(this.encounterHome)) <= ENCOUNTER_LEASH_RADIUS * ENCOUNTER_LEASH_RADIUS;
}
private boolean shouldShowBossBar() {
return this.getTarget() != null
|| this.isAttackLocked()
|| this.phaseTransitionTicks > 0
|| !this.isAtEncounterHome();
}
private boolean isAtEncounterHome() {
if (this.encounterHome == null) {
return true;
}
return this.distanceToSqr(Vec3.atCenterOf(this.encounterHome)) <= ENCOUNTER_HOME_RADIUS;
}
private boolean isOutsideLeashRadius() {
if (this.encounterHome == null) {
return false;
}
return this.distanceToSqr(Vec3.atCenterOf(this.encounterHome)) > ENCOUNTER_LEASH_RADIUS * ENCOUNTER_LEASH_RADIUS;
}
private void navigateHome() {
if (this.encounterHome == null) {
return;
}
Vec3 homeCenter = Vec3.atCenterOf(this.encounterHome);
if (this.distanceToSqr(homeCenter) > FORCED_RETURN_RADIUS * FORCED_RETURN_RADIUS) {
this.moveTo(homeCenter.x, this.encounterHome.getY(), homeCenter.z, this.getYRot(), this.getXRot());
this.setDeltaMovement(Vec3.ZERO);
this.hasImpulse = true;
return;
}
this.getNavigation().moveTo(homeCenter.x, this.encounterHome.getY(), homeCenter.z, HOME_RETURN_SPEED);
}
private void resetEncounter(boolean restoreHealth) {
this.finishCommittedAttack();
this.stopFlightBurst();
this.getNavigation().stop();
this.setTarget(null);
this.setAggressive(false);
this.phaseTransitionTicks = 0;
this.disengageTicks = 0;
this.summonCooldownTicks = Math.max(1, AntarchySettings.alphaMantisSummonIntervalTicks() / 2);
this.halfHealthTransitionComplete = false;
if (restoreHealth) {
this.setHealth(this.getMaxHealth());
}
if (this.encounterHome != null) {
Vec3 homeCenter = Vec3.atCenterOf(this.encounterHome);
this.moveTo(homeCenter.x, this.encounterHome.getY(), homeCenter.z, this.getYRot(), this.getXRot());
this.setDeltaMovement(Vec3.ZERO);
}
}
}
@@ -146,7 +146,8 @@ public class BedBugEntity extends Animal implements GeoEntity {
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
controllers.add(new AnimationController<>(this, "main_controller", 2, this::mainAnimController));
controllers.add(new AnimationController<>(this, "main_controller", 2, this::mainAnimController)
.triggerableAnim("bite", BITE_ANIM));
}
@Override
@@ -336,8 +337,12 @@ public class BedBugEntity extends Animal implements GeoEntity {
}
private void startBiteAnimation() {
boolean wasIdle = this.biteAnimationTicks <= 0;
this.biteAnimationTicks = BITE_ANIM_TICKS;
this.level().broadcastEntityEvent(this, BITE_ANIM_EVENT);
if (wasIdle) {
this.triggerAnim("main_controller", "bite");
}
}
private void beginAttack(LivingEntity target) {
@@ -201,7 +201,8 @@ public class BomberEntity extends Monster implements GeoEntity {
controllers.add(new AnimationController<>(this, "movement_controller", 0, this::movementAnimController)
.setSoundKeyframeHandler(new AutoPlayingSoundKeyframeHandler<>()));
controllers.add(new AnimationController<>(this, "explode_controller", 0, this::explodeAnimController)
.setSoundKeyframeHandler(new AutoPlayingSoundKeyframeHandler<>()));
.setSoundKeyframeHandler(new AutoPlayingSoundKeyframeHandler<>())
.triggerableAnim("explode", EXPLODE_ANIM));
}
@Override
@@ -222,6 +223,9 @@ public class BomberEntity extends Monster implements GeoEntity {
if (this.fuseTicks > 0) {
this.fuseTicks--;
this.entityData.set(FUSE_TICKS_DATA, this.fuseTicks);
if (this.fuseTicks == EXPLODE_ANIM_START_TICKS) {
this.triggerAnim("explode_controller", "explode");
}
}
if (this.fuseTicks <= 0) {
@@ -205,7 +205,9 @@ public class ButterflyEntity extends Animal implements FlyingAnimal, GeoEntity {
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
controllers.add(new AnimationController<>(this, "main_controller", 2, this::mainAnimController));
controllers.add(new AnimationController<>(this, "main_controller", 2, this::mainAnimController)
.triggerableAnim("emerge", EMERGE_ANIM)
.triggerableAnim("pollinate", POLLINATE_ANIM));
}
private PlayState mainAnimController(AnimationState<ButterflyEntity> state) {
@@ -436,7 +438,21 @@ public class ButterflyEntity extends Animal implements FlyingAnimal, GeoEntity {
}
private void setActivityState(ActivityState state) {
this.entityData.set(ACTIVITY_STATE, state.ordinal());
ActivityState previous = this.getActivityState();
if (previous != state) {
this.entityData.set(ACTIVITY_STATE, state.ordinal());
String trigger = switch (state) {
case EMERGING -> "emerge";
case POLLINATING -> "pollinate";
default -> null;
};
if (trigger != null) {
this.triggerAnim("main_controller", trigger);
}
if (previous == ActivityState.POLLINATING) {
this.stopTriggeredAnim("main_controller", "pollinate");
}
}
}
private ActivityState getActivityState() {
@@ -181,7 +181,10 @@ public class CaterpillarEntity extends Animal implements GeoEntity {
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
controllers.add(new AnimationController<>(this, "main_controller", 2, this::mainAnimController)
.setSoundKeyframeHandler(new AutoPlayingSoundKeyframeHandler<>()));
.setSoundKeyframeHandler(new AutoPlayingSoundKeyframeHandler<>())
.triggerableAnim("eat", EAT_ANIM)
.triggerableAnim("pupate", PUPATION_ANIM)
.triggerableAnim("chrysalis", CHRYSALIS_ANIM));
}
private PlayState mainAnimController(AnimationState<CaterpillarEntity> state) {
@@ -537,11 +540,30 @@ public class CaterpillarEntity extends Animal implements GeoEntity {
}
private void setEatAnimationTicks(int ticks) {
this.entityData.set(EAT_ANIMATION_TICKS, Math.max(0, ticks));
int clamped = Math.max(0, ticks);
boolean wasIdle = this.getEatAnimationTicks() <= 0;
this.entityData.set(EAT_ANIMATION_TICKS, clamped);
if (wasIdle && clamped > 0) {
this.triggerAnim("main_controller", "eat");
}
}
private void setLifeStage(LifeStage stage) {
this.entityData.set(LIFE_STAGE, stage.ordinal());
LifeStage previous = this.getLifeStage();
if (previous != stage) {
this.entityData.set(LIFE_STAGE, stage.ordinal());
String trigger = switch (stage) {
case PUPATING -> "pupate";
case CHRYSALIS -> "chrysalis";
default -> null;
};
if (trigger != null) {
this.triggerAnim("main_controller", trigger);
}
if (previous == LifeStage.CHRYSALIS) {
this.stopTriggeredAnim("main_controller", "chrysalis");
}
}
}
private LifeStage getLifeStage() {
@@ -120,7 +120,8 @@ public class CreepingHorrorEntity extends Monster implements GeoEntity {
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
controllers.add(new AnimationController<>(this, "main_controller", 3, this::mainAnimController));
controllers.add(new AnimationController<>(this, "main_controller", 3, this::mainAnimController)
.triggerableAnim("attack", ATTACK_ANIM));
}
private PlayState mainAnimController(AnimationState<CreepingHorrorEntity> state) {
@@ -143,12 +144,21 @@ public class CreepingHorrorEntity extends Monster implements GeoEntity {
boolean result = super.doHurtTarget(target);
if (result) {
this.playSound(AntarchySoundEvents.CREEPING_HORROR_BITE.get(), 1.0F, 0.95F + this.random.nextFloat() * 0.1F);
attackAnimTicks = 20;
this.setAttackAnimTicks(20);
this.level().broadcastEntityEvent(this, ATTACK_ANIM_EVENT);
}
return result;
}
private void setAttackAnimTicks(int ticks) {
int clamped = Math.max(0, ticks);
boolean wasIdle = attackAnimTicks <= 0;
attackAnimTicks = clamped;
if (wasIdle && clamped > 0) {
this.triggerAnim("main_controller", "attack");
}
}
@Override
protected SoundEvent getAmbientSound() {
return AntarchySoundEvents.CREEPING_HORROR_GROWL.get();
@@ -178,7 +188,12 @@ public class CreepingHorrorEntity extends Monster implements GeoEntity {
CavarynBurrowingMobBehavior.moveOutOfBlocks(this);
super.tick();
CavarynBurrowingMobBehavior.moveOutOfBlocks(this);
if (attackAnimTicks > 0) attackAnimTicks--;
if (attackAnimTicks > 0) {
attackAnimTicks--;
if (attackAnimTicks <= 0 && !this.level().isClientSide()) {
this.stopTriggeredAnim("main_controller", "attack");
}
}
if (this.level().isClientSide()) return;
boolean climbing = this.horizontalCollision;
@@ -199,7 +199,11 @@ public class DorrieEntity extends Animal implements GeoEntity {
}
private void setQuirkTicks(int ticks) {
boolean wasIdle = this.getQuirkTicks() <= 0;
this.entityData.set(QUIRK_TICKS, ticks);
if (wasIdle && ticks > 0) {
this.triggerAnim("main_controller", "quirk");
}
}
@Override
@@ -371,6 +375,9 @@ public class DorrieEntity extends Animal implements GeoEntity {
if (wasInAir && !inAirNow && isLeaping) {
isLeaping = false;
landAnimTicks = 12;
if (!this.level().isClientSide) {
this.triggerAnim("main_controller", "land");
}
if (this.isInWater()) {
this.playSound(SoundEvents.DOLPHIN_SPLASH, 1.0F, 0.8F + this.random.nextFloat() * 0.4F);
}
@@ -471,6 +478,7 @@ public class DorrieEntity extends Animal implements GeoEntity {
);
this.hasImpulse = true;
isLeaping = true;
this.triggerAnim("main_controller", "jump_start");
}
isCharging = false;
chargeTicks = 0;
@@ -565,7 +573,10 @@ public class DorrieEntity extends Animal implements GeoEntity {
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
controllers.add(new AnimationController<>(this, "main_controller", 2, this::mainAnimController));
controllers.add(new AnimationController<>(this, "main_controller", 2, this::mainAnimController)
.triggerableAnim("land", JUMP_LAND_ANIM)
.triggerableAnim("jump_start", JUMP_START_ANIM)
.triggerableAnim("quirk", QUIRK_ANIM));
}
private PlayState mainAnimController(AnimationState<DorrieEntity> state) {
@@ -516,7 +516,12 @@ public class EmperorScorpionEntity extends Monster implements GeoEntity {
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
controllers.add(new AnimationController<>(this, "main", 3, this::mainController));
controllers.add(new AnimationController<>(this, "main", 3, this::mainController)
.triggerableAnim("snap", CLAW_ATTACK_ANIM)
.triggerableAnim("sting", STING_ATTACK_ANIM)
.triggerableAnim("harden", HARDEN_START_ANIM)
.triggerableAnim("harden_state", HARDEN_ACTIVE_ANIM)
.triggerableAnim("end_of_harden_state", HARDEN_END_ANIM));
}
private PlayState mainController(AnimationState<EmperorScorpionEntity> state) {
@@ -547,7 +552,20 @@ public class EmperorScorpionEntity extends Monster implements GeoEntity {
}
private void setAnimationState(int animationState) {
this.entityData.set(ANIMATION_STATE, animationState);
if (this.entityData.get(ANIMATION_STATE) != animationState) {
this.entityData.set(ANIMATION_STATE, animationState);
String trigger = switch (animationState) {
case ANIM_CLAW_ATTACK -> "snap";
case ANIM_STING_ATTACK -> "sting";
case ANIM_HARDEN_START -> "harden";
case ANIM_HARDEN_ACTIVE -> "harden_state";
case ANIM_HARDEN_END -> "end_of_harden_state";
default -> null;
};
if (trigger != null) {
this.triggerAnim("main", trigger);
}
}
}
private void setHardenPhase(HardenPhase phase) {
@@ -269,7 +269,10 @@ public class HerculesBeetleEntity extends TamableAnimal implements GeoEntity, Fl
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
controllers.add(new AnimationController<>(this, "main_controller", 0, this::mainAnimController));
controllers.add(new AnimationController<>(this, "main_controller", 0, this::mainAnimController)
.triggerableAnim("cry", CRY_ANIM)
.triggerableAnim("attack", ATTACK_ANIM)
.triggerableAnim("charge_start", CHARGE_START_ANIM));
controllers.add(new AnimationController<>(this, "flying_charge_controller", 0, this::flyingChargeAnimController));
}
@@ -773,7 +776,18 @@ public class HerculesBeetleEntity extends TamableAnimal implements GeoEntity, Fl
}
private void setAnimationState(int animationState) {
this.entityData.set(ANIMATION_STATE, animationState);
if (this.entityData.get(ANIMATION_STATE) != animationState) {
this.entityData.set(ANIMATION_STATE, animationState);
String trigger = switch (animationState) {
case ANIM_CRY -> "cry";
case ANIM_ATTACK -> "attack";
case ANIM_CHARGE_START -> "charge_start";
default -> null;
};
if (trigger != null) {
this.triggerAnim("main_controller", trigger);
}
}
}
private boolean isInBusyAnimation() {
@@ -142,7 +142,7 @@ public class JerryEntity extends Monster implements GeoEntity {
int attackTicks = this.entityData.get(ATTACK_ANIM_TICKS);
if (attackTicks > 0) {
this.entityData.set(ATTACK_ANIM_TICKS, attackTicks - 1);
this.setAttackAnimTicks(attackTicks - 1);
}
if (this.level().isClientSide) {
@@ -264,7 +264,7 @@ public class JerryEntity extends Monster implements GeoEntity {
if (targetDistance < 2.3D && this.attackCooldownTicks <= 0) {
this.faceTarget(target);
this.attackCooldownTicks = 24;
this.entityData.set(ATTACK_ANIM_TICKS, ATTACK_ANIM_DURATION);
this.setAttackAnimTicks(ATTACK_ANIM_DURATION);
this.playSound(this.attackSoundForCurrentStage(), 1.0F, this.voicePitch());
target.hurt(this.damageSources().mobAttack(this), (float) stage.attackDamage());
}
@@ -294,7 +294,7 @@ public class JerryEntity extends Monster implements GeoEntity {
@Override
public boolean doHurtTarget(Entity target) {
this.entityData.set(ATTACK_ANIM_TICKS, ATTACK_ANIM_DURATION);
this.setAttackAnimTicks(ATTACK_ANIM_DURATION);
if (target instanceof LivingEntity living) {
this.faceTarget(living);
}
@@ -359,8 +359,10 @@ public class JerryEntity extends Monster implements GeoEntity {
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
controllers.add(new AnimationController<>(this, "main_controller", 3, this::mainAnimController));
controllers.add(new AnimationController<>(this, "attack_controller", 0, this::attackAnimController));
controllers.add(new AnimationController<>(this, "main_controller", 3, this::mainAnimController)
.triggerableAnim("attack", ATTACK_ANIM));
controllers.add(new AnimationController<>(this, "attack_controller", 0, this::attackAnimController)
.triggerableAnim("attack", ATTACK_ANIM));
}
private PlayState mainAnimController(AnimationState<JerryEntity> state) {
@@ -445,6 +447,16 @@ public class JerryEntity extends Monster implements GeoEntity {
}
}
private void setAttackAnimTicks(int ticks) {
int clamped = Math.max(0, ticks);
int previous = this.entityData.get(ATTACK_ANIM_TICKS);
this.entityData.set(ATTACK_ANIM_TICKS, clamped);
if (previous <= 0 && clamped > 0) {
this.triggerAnim("main_controller", "attack");
this.triggerAnim("attack_controller", "attack");
}
}
private void applyStageAttributes(Stage stage, boolean fillIfNew) {
double oldMaxHealth = this.getMaxHealth();
float healthRatio = oldMaxHealth > 0.0D ? this.getHealth() / (float) oldMaxHealth : 1.0F;
@@ -5,6 +5,7 @@ import com.craisinlord.antarchy.content.AntarchySoundEvents;
import com.craisinlord.antarchy.content.damage.AntarchyDamageSources;
import com.mojang.serialization.Codec;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
@@ -42,6 +43,7 @@ import net.minecraft.world.level.Level;
import net.minecraft.world.level.ServerLevelAccessor;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.Nullable;
import software.bernie.geckolib.animatable.GeoEntity;
@@ -79,13 +81,22 @@ public class JumpyBugEntity extends Monster implements GeoEntity {
private static final int CHASE_JUMP_COOLDOWN = 25;
private static final double POUNCE_HORIZONTAL_SPEED = 0.92D;
private static final double POUNCE_UPWARD_SPEED = 0.75D;
private static final double CEILING_DROP_HORIZONTAL_SPEED = 1.08D;
private static final double CEILING_DROP_UPWARD_SPEED = 0.18D;
private static final double CHASE_LEAP_HORIZONTAL = 1.5D;
private static final double CHASE_LEAP_VERTICAL = 0.55D;
private static final double QUICK_MOVE_SQR = 0.14D * 0.14D;
private static final double POUNCE_LAND_DAMAGE_RANGE = 5.0D;
private static final int MAX_POUNCE_TICKS = 60;
private static final int CEILING_SEARCH_RANGE = 30;
private static final int CEILING_HORIZONTAL_SEARCH_RANGE = 6;
private static final int CEILING_EXTRA_SEARCH_HEIGHT = 8;
private static final int CEILING_DIRECT_EXTRA_HEIGHT = 2;
private static final int CEILING_SEARCH_COOLDOWN = 35;
private static final int CAMOUFLAGE_WARMUP_TICKS = 16;
private static final double CAMOUFLAGE_PLAYER_RANGE = 24.0D;
private static final double CEILING_ALIGN_DISTANCE_SQR = 1.35D * 1.35D;
private static final double CEILING_AMBUSH_RANGE_SQR = 7.0D * 7.0D;
private static final double CEILING_TRIGGER_RANGE_SQR = 5.0D * 5.0D;
private static final RawAnimation IDLE_ANIM = RawAnimation.begin().thenLoop("idle");
private static final RawAnimation WALK_ANIM = RawAnimation.begin().thenLoop("walk");
@@ -101,6 +112,8 @@ public class JumpyBugEntity extends Monster implements GeoEntity {
private int pounceTicks;
private int leapingTicks;
private int chaseJumpCooldownTicks;
private int ceilingSearchCooldownTicks;
private int camouflageWarmupTicks;
private boolean preferPounceThisWindow = true;
private float visualAlpha = 1.0F;
private float previousVisualAlpha = 1.0F;
@@ -150,7 +163,10 @@ public class JumpyBugEntity extends Monster implements GeoEntity {
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
controllers.add(new AnimationController<>(this, "main_controller", 2, this::mainAnimController));
controllers.add(new AnimationController<>(this, "main_controller", 2, this::mainAnimController)
.triggerableAnim("hanging", HANGING_ANIM)
.triggerableAnim("jump", JUMP_ANIM)
.triggerableAnim("jump_end", JUMP_END_ANIM));
}
@Override
@@ -215,6 +231,9 @@ public class JumpyBugEntity extends Monster implements GeoEntity {
if (this.chaseJumpCooldownTicks > 0) {
this.chaseJumpCooldownTicks--;
}
if (this.ceilingSearchCooldownTicks > 0) {
this.ceilingSearchCooldownTicks--;
}
if (this.isClingingToCeiling()) {
this.tickClinging();
@@ -333,7 +352,29 @@ public class JumpyBugEntity extends Monster implements GeoEntity {
}
private void setAttackState(AttackState state) {
AttackState previous = this.getAttackState();
if (previous == state) {
return;
}
this.entityData.set(ATTACK_STATE, state.id());
String trigger = switch (state) {
case CLINGING -> "hanging";
case POUNCING, LEAPING_TO_CEILING -> "jump";
case RECOVERING -> "jump_end";
default -> null;
};
if (trigger != null) {
this.triggerAnim("main_controller", trigger);
}
if (previous == AttackState.CLINGING) {
this.stopTriggeredAnim("main_controller", "hanging");
}
if ((previous == AttackState.POUNCING || previous == AttackState.LEAPING_TO_CEILING)
&& state != AttackState.POUNCING && state != AttackState.LEAPING_TO_CEILING) {
this.stopTriggeredAnim("main_controller", "jump");
}
}
private float getTargetVisualAlpha() {
@@ -355,7 +396,7 @@ public class JumpyBugEntity extends Monster implements GeoEntity {
}
private void tickClinging() {
BlockPos clingPos = this.findCeilingWithinRange(2);
BlockPos clingPos = this.findCeilingWithinRange(this.directCeilingSearchHeight());
if (clingPos == null) {
this.stopClinging();
return;
@@ -396,7 +437,7 @@ public class JumpyBugEntity extends Monster implements GeoEntity {
return;
}
this.getNavigation().stop();
BlockPos ceiling = this.findCeilingWithinRange(2);
BlockPos ceiling = this.findCeilingWithinRange(this.directCeilingSearchHeight());
if (ceiling != null) {
this.leapingTicks = 0;
this.beginClinging();
@@ -406,23 +447,33 @@ public class JumpyBugEntity extends Monster implements GeoEntity {
private void updateCamouflage() {
if (this.isPouncing() || this.isLeapingToCeiling()) {
this.setCamouflaged(false);
this.camouflageWarmupTicks = 0;
return;
}
if (this.isClingingToCeiling()) {
this.setCamouflaged(true);
this.camouflageWarmupTicks = CAMOUFLAGE_WARMUP_TICKS;
return;
}
boolean playerNearby = this.level().getNearestPlayer(this, CAMOUFLAGE_PLAYER_RANGE) != null;
if (!playerNearby) {
boolean idle = this.getTarget() == null
&& this.recoveryTicks <= 0
&& this.getDeltaMovement().horizontalDistanceSqr() < 0.003D
&& this.onGround();
boolean movingQuickly = this.getDeltaMovement().lengthSqr() > QUICK_MOVE_SQR;
boolean inAmbushCover = this.findCeilingWithinRange(this.directCeilingSearchHeight()) != null;
if (!playerNearby || !idle || movingQuickly || !inAmbushCover) {
this.setCamouflaged(false);
this.camouflageWarmupTicks = 0;
return;
}
boolean idle = this.getTarget() == null && this.getDeltaMovement().horizontalDistanceSqr() < 0.003D;
boolean movingQuickly = this.getDeltaMovement().lengthSqr() > QUICK_MOVE_SQR;
this.setCamouflaged(!movingQuickly && idle);
if (this.camouflageWarmupTicks < CAMOUFLAGE_WARMUP_TICKS) {
this.camouflageWarmupTicks++;
}
this.setCamouflaged(this.camouflageWarmupTicks >= CAMOUFLAGE_WARMUP_TICKS);
}
@Nullable
@@ -430,7 +481,7 @@ public class JumpyBugEntity extends Monster implements GeoEntity {
BlockPos origin = this.blockPosition();
for (int dy = 1; dy <= maxBlocks; dy++) {
BlockPos candidate = origin.above(dy);
if (isCeilingBlock(candidate)) {
if (this.isUsableCeiling(candidate)) {
return candidate;
}
}
@@ -439,11 +490,81 @@ public class JumpyBugEntity extends Monster implements GeoEntity {
@Nullable
private BlockPos findCeilingForLeap() {
return findCeilingWithinRange(CEILING_SEARCH_RANGE);
BlockPos origin = this.blockPosition();
BlockPos best = null;
double bestScore = Double.MAX_VALUE;
LivingEntity target = this.getTarget();
int minHeight = this.minimumCeilingHeight();
int maxHeight = minHeight + CEILING_EXTRA_SEARCH_HEIGHT;
for (int dx = -CEILING_HORIZONTAL_SEARCH_RANGE; dx <= CEILING_HORIZONTAL_SEARCH_RANGE; dx++) {
for (int dz = -CEILING_HORIZONTAL_SEARCH_RANGE; dz <= CEILING_HORIZONTAL_SEARCH_RANGE; dz++) {
int horizontalDistance = Math.abs(dx) + Math.abs(dz);
if (horizontalDistance > CEILING_HORIZONTAL_SEARCH_RANGE) {
continue;
}
for (int dy = minHeight; dy <= maxHeight; dy++) {
BlockPos candidate = origin.offset(dx, dy, dz);
if (!this.isUsableCeiling(candidate)) {
continue;
}
double score = horizontalDistance * 1.4D + dy * 0.25D;
if (target != null) {
score += candidate.distSqr(target.blockPosition()) * 0.04D;
}
if (score < bestScore) {
bestScore = score;
best = candidate.immutable();
}
}
}
}
return best;
}
private boolean isCeilingBlock(BlockPos pos) {
return this.level().getBlockState(pos).isFaceSturdy(this.level(), pos, net.minecraft.core.Direction.DOWN);
return this.level().getBlockState(pos).isFaceSturdy(this.level(), pos, Direction.DOWN);
}
private int minimumCeilingHeight() {
return Math.max(2, Mth.ceil(this.getBbHeight()) + 1);
}
private int directCeilingSearchHeight() {
return this.minimumCeilingHeight() + CEILING_DIRECT_EXTRA_HEIGHT;
}
private boolean isUsableCeiling(BlockPos pos) {
if (!this.isCeilingBlock(pos)) {
return false;
}
double x = pos.getX() + 0.5D;
double y = pos.getY() - this.getBbHeight() - 0.01D;
double z = pos.getZ() + 0.5D;
return this.canOccupy(x, y, z);
}
private boolean canOccupy(double x, double y, double z) {
double halfWidth = this.getBbWidth() * 0.5D;
AABB box = new AABB(
x - halfWidth,
y,
z - halfWidth,
x + halfWidth,
y + this.getBbHeight(),
z + halfWidth
);
return this.level().noCollision(this, box);
}
private boolean isAlignedBelowCeiling(BlockPos ceilingPos) {
double x = ceilingPos.getX() + 0.5D;
double z = ceilingPos.getZ() + 0.5D;
double dx = this.getX() - x;
double dz = this.getZ() - z;
return dx * dx + dz * dz <= CEILING_ALIGN_DISTANCE_SQR;
}
private void beginClinging() {
@@ -465,12 +586,15 @@ public class JumpyBugEntity extends Monster implements GeoEntity {
private void beginLeapToCeiling(BlockPos ceilingPos) {
this.setAttackState(AttackState.LEAPING_TO_CEILING);
this.setCamouflaged(false);
this.camouflageWarmupTicks = 0;
this.leapingTicks = 0;
this.getNavigation().stop();
double dy = ceilingPos.getY() - this.getY();
double upwardSpeed = Math.min(2.5D, Math.sqrt(0.16D * Math.max(dy, 1.0D)) + 0.4D);
this.setDeltaMovement(0.0D, upwardSpeed, 0.0D);
double dx = ceilingPos.getX() + 0.5D - this.getX();
double dz = ceilingPos.getZ() + 0.5D - this.getZ();
this.setDeltaMovement(Mth.clamp(dx * 0.18D, -0.35D, 0.35D), upwardSpeed, Mth.clamp(dz * 0.18D, -0.35D, 0.35D));
this.hasImpulse = true;
this.playSound(AntarchySoundEvents.JUMPY_BUG_JUMP.get(), 1.0F, 0.95F + this.random.nextFloat() * 0.1F);
}
@@ -478,6 +602,8 @@ public class JumpyBugEntity extends Monster implements GeoEntity {
private void cancelLeap() {
this.leapingTicks = 0;
this.setAttackState(AttackState.GROUND);
this.setNoGravity(false);
this.noPhysics = false;
}
private void beginPounce(LivingEntity target) {
@@ -499,6 +625,24 @@ public class JumpyBugEntity extends Monster implements GeoEntity {
this.playSound(AntarchySoundEvents.JUMPY_BUG_JUMP.get(), 1.0F, 0.95F + this.random.nextFloat() * 0.1F);
}
private void beginCeilingDrop(LivingEntity target) {
this.stopClinging();
this.setTarget(target);
this.setAttackState(AttackState.POUNCING);
this.setCamouflaged(false);
this.camouflageWarmupTicks = 0;
this.getNavigation().stop();
this.pounceCooldownTicks = DEFAULT_POUNCE_COOLDOWN;
this.pounceTicks = 0;
Vec3 to = target.position().add(0.0D, target.getBbHeight() * 0.35D, 0.0D).subtract(this.position());
Vec3 horizontal = new Vec3(to.x, 0.0D, to.z);
Vec3 direction = horizontal.lengthSqr() > 1.0E-4D ? horizontal.normalize() : target.getLookAngle();
this.setDeltaMovement(direction.x * CEILING_DROP_HORIZONTAL_SPEED, CEILING_DROP_UPWARD_SPEED, direction.z * CEILING_DROP_HORIZONTAL_SPEED);
this.hasImpulse = true;
this.playSound(AntarchySoundEvents.JUMPY_BUG_JUMP.get(), 1.0F, 0.9F + this.random.nextFloat() * 0.1F);
}
private void finishPounce(boolean keepMomentum) {
this.pounceTicks = 0;
if (!keepMomentum) {
@@ -641,6 +785,9 @@ public class JumpyBugEntity extends Monster implements GeoEntity {
if (!JumpyBugEntity.this.canUseAmbush() || JumpyBugEntity.this.isClingingToCeiling()) {
return false;
}
if (JumpyBugEntity.this.ceilingSearchCooldownTicks > 0) {
return false;
}
LivingEntity target = JumpyBugEntity.this.getTarget();
boolean targetFarAway = target != null
&& JumpyBugEntity.this.distanceToSqr(target) > 12.0D * 12.0D;
@@ -648,27 +795,32 @@ public class JumpyBugEntity extends Monster implements GeoEntity {
if (!noTarget && !targetFarAway) {
return false;
}
if (JumpyBugEntity.this.random.nextInt(25) != 0) {
if (JumpyBugEntity.this.random.nextInt(noTarget ? 8 : 14) != 0) {
return false;
}
this.targetCeiling = JumpyBugEntity.this.findCeilingForLeap();
JumpyBugEntity.this.ceilingSearchCooldownTicks = CEILING_SEARCH_COOLDOWN;
return this.targetCeiling != null;
}
@Override
public boolean canContinueToUse() {
return JumpyBugEntity.this.isClingingToCeiling() || JumpyBugEntity.this.isLeapingToCeiling();
if (JumpyBugEntity.this.isClingingToCeiling() || JumpyBugEntity.this.isLeapingToCeiling()) {
return true;
}
LivingEntity target = JumpyBugEntity.this.getTarget();
boolean allowedTarget = target == null || JumpyBugEntity.this.distanceToSqr(target) > CEILING_AMBUSH_RANGE_SQR;
return this.targetCeiling != null
&& allowedTarget
&& JumpyBugEntity.this.canUseAmbush();
}
@Override
public void start() {
if (this.targetCeiling != null) {
BlockPos ceil = this.targetCeiling;
// If we're already adjacent to the ceiling, just cling directly
if (ceil.getY() - JumpyBugEntity.this.getY() <= 2) {
BlockPos ceiling = this.targetCeiling;
if (JumpyBugEntity.this.isAlignedBelowCeiling(ceiling) && ceiling.getY() - JumpyBugEntity.this.getY() <= JumpyBugEntity.this.directCeilingSearchHeight()) {
JumpyBugEntity.this.beginClinging();
} else {
JumpyBugEntity.this.beginLeapToCeiling(ceil);
}
}
}
@@ -690,11 +842,31 @@ public class JumpyBugEntity extends Monster implements GeoEntity {
if (target != null) {
JumpyBugEntity.this.getLookControl().setLookAt(target, 30.0F, 30.0F);
if (JumpyBugEntity.this.pounceCooldownTicks <= 0
&& (JumpyBugEntity.this.hasLineOfSight(target) || JumpyBugEntity.this.distanceToSqr(target) <= 4.0D)) {
JumpyBugEntity.this.stopClinging();
JumpyBugEntity.this.beginPounce(target);
&& JumpyBugEntity.this.distanceToSqr(target) <= CEILING_TRIGGER_RANGE_SQR
&& JumpyBugEntity.this.hasLineOfSight(target)) {
JumpyBugEntity.this.beginCeilingDrop(target);
}
}
return;
}
if (JumpyBugEntity.this.isLeapingToCeiling() || this.targetCeiling == null) {
return;
}
BlockPos ceiling = this.targetCeiling;
JumpyBugEntity.this.getLookControl().setLookAt(ceiling.getX() + 0.5D, ceiling.getY() - 1.0D, ceiling.getZ() + 0.5D, 20.0F, 20.0F);
if (!JumpyBugEntity.this.isUsableCeiling(ceiling)) {
this.targetCeiling = null;
return;
}
if (JumpyBugEntity.this.isAlignedBelowCeiling(ceiling)) {
if (JumpyBugEntity.this.onGround()) {
JumpyBugEntity.this.beginLeapToCeiling(ceiling);
}
} else {
JumpyBugEntity.this.getNavigation().moveTo(ceiling.getX() + 0.5D, JumpyBugEntity.this.getY(), ceiling.getZ() + 0.5D, 1.05D);
}
}
}
@@ -109,7 +109,9 @@ public class LurkingTerrorEntity extends Monster implements GeoEntity {
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
controllers.add(new AnimationController<>(this, "main_controller", 3, this::mainAnimController));
controllers.add(new AnimationController<>(this, "main_controller", 3, this::mainAnimController)
.triggerableAnim("attackland", ATTACK_LAND_ANIM)
.triggerableAnim("attackair", ATTACK_AIR_ANIM));
}
private PlayState mainAnimController(AnimationState<LurkingTerrorEntity> state) {
@@ -138,7 +140,7 @@ public class LurkingTerrorEntity extends Monster implements GeoEntity {
boolean result = super.doHurtTarget(target);
if (result) {
this.playSound(AntarchySoundEvents.LURKING_TERROR_BITE.get(), 1.0F, 0.95F + this.random.nextFloat() * 0.1F);
attackAnimTicks = 20;
this.setAttackAnimTicks(20);
this.level().broadcastEntityEvent(this, ATTACK_ANIM_EVENT);
}
return result;
@@ -162,7 +164,7 @@ public class LurkingTerrorEntity extends Monster implements GeoEntity {
@Override
public void handleEntityEvent(byte id) {
if (id == ATTACK_ANIM_EVENT) {
attackAnimTicks = 20;
this.setAttackAnimTicks(20);
return;
}
super.handleEntityEvent(id);
@@ -176,7 +178,18 @@ public class LurkingTerrorEntity extends Monster implements GeoEntity {
if (!this.level().isClientSide() && !this.onGround() && this.tickCount % 80 == 0) {
this.playSound(AntarchySoundEvents.LURKING_TERROR_FLY_LOOP.get(), 0.45F, 0.95F + this.random.nextFloat() * 0.1F);
}
if (!this.level().isClientSide() && attackAnimTicks > 0) attackAnimTicks--;
if (!this.level().isClientSide() && attackAnimTicks > 0) this.setAttackAnimTicks(attackAnimTicks - 1);
}
private void setAttackAnimTicks(int ticks) {
int clamped = Math.max(0, ticks);
if (this.attackAnimTicks <= 0 && clamped > 0) {
this.triggerAnim("main_controller", this.onGround() ? "attackland" : "attackair");
} else if (this.attackAnimTicks > 0 && clamped <= 0) {
this.stopTriggeredAnim("main_controller", "attackland");
this.stopTriggeredAnim("main_controller", "attackair");
}
this.attackAnimTicks = clamped;
}
@Override
@@ -7,6 +7,7 @@ import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.entity.Entity;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.util.Mth;
import net.minecraft.util.RandomSource;
import net.minecraft.world.Difficulty;
import net.minecraft.world.damagesource.DamageSource;
@@ -18,7 +19,7 @@ import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
import net.minecraft.world.entity.ai.attributes.AttributeInstance;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.ai.goal.FloatGoal;
import net.minecraft.world.entity.ai.goal.MeleeAttackGoal;
import net.minecraft.world.entity.ai.goal.Goal;
import net.minecraft.world.entity.ai.goal.WaterAvoidingRandomStrollGoal;
import net.minecraft.world.entity.ai.goal.target.HurtByTargetGoal;
import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal;
@@ -46,6 +47,8 @@ import software.bernie.geckolib.animation.PlayState;
import software.bernie.geckolib.animation.RawAnimation;
import software.bernie.geckolib.util.GeckoLibUtil;
import java.util.EnumSet;
public class MantisEntity extends Monster implements GeoEntity {
private static final Logger LOGGER = LoggerFactory.getLogger(MantisEntity.class);
private static final RawAnimation IDLE_ANIM = RawAnimation.begin().thenLoop("idle");
@@ -61,14 +64,29 @@ public class MantisEntity extends Monster implements GeoEntity {
private static final int ANIM_FLY_ATTACK = 4;
private static final double WANDER_SPEED = 0.48D;
private static final double COMBAT_SPEED = 0.75D;
private static final int ATTACK_ANIM_TICKS = 20;
private static final int ATTACK_COMMIT_REMAINING_TICKS = 14;
private static final int ATTACK_HIT_REMAINING_TICKS = 10;
private static final int ATTACK_COOLDOWN_TICKS = 8;
private static final double ATTACK_START_RANGE = 4.25D;
private static final double ATTACK_HIT_REACH = 5.25D;
private static final double ATTACK_HALF_WIDTH = 2.6D;
private static final double ATTACK_VERTICAL_TOLERANCE = 3.0D;
private static final float WINDUP_TURN_RATE = 18.0F;
private static final net.minecraft.network.syncher.EntityDataAccessor<Integer> ANIMATION_STATE =
net.minecraft.network.syncher.SynchedEntityData.defineId(MantisEntity.class, net.minecraft.network.syncher.EntityDataSerializers.INT);
private final AnimatableInstanceCache geoCache = GeckoLibUtil.createInstanceCache(this);
protected int attackAnimationTicks;
protected int attackCooldownTicks;
protected int flyBurstTicks;
protected int flyCooldownTicks;
@Nullable
protected LivingEntity committedAttackTarget;
protected float committedAttackYaw;
protected boolean attackDamageApplied;
protected boolean attackStartedInFlight;
private int debugLogTicks = 0;
private int configSyncTicks;
@@ -169,8 +187,8 @@ public class MantisEntity extends Monster implements GeoEntity {
this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, 5, true, false, null));
}
protected MeleeAttackGoal createCombatGoal() {
return new MeleeAttackGoal(this, this.getCombatSpeed(), true);
protected Goal createCombatGoal() {
return new MantisCombatGoal();
}
protected WaterAvoidingRandomStrollGoal createIdleStrollGoal() {
@@ -188,7 +206,9 @@ public class MantisEntity extends Monster implements GeoEntity {
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
controllers.add(new AnimationController<>(this, "main_controller", 0, this::mainAnimController));
controllers.add(new AnimationController<>(this, "main_controller", 0, this::mainAnimController)
.triggerableAnim("attack", ATTACK_ANIM)
.triggerableAnim("flyattack", FLY_ATTACK_ANIM));
}
private PlayState mainAnimController(AnimationState<MantisEntity> state) {
@@ -216,7 +236,17 @@ public class MantisEntity extends Monster implements GeoEntity {
}
if (this.attackAnimationTicks > 0) {
this.attackAnimationTicks--;
this.tickCommittedAttack();
if (this.attackAnimationTicks > 0) {
this.attackAnimationTicks--;
if (this.attackAnimationTicks <= 0) {
this.finishCommittedAttack();
}
}
}
if (this.attackCooldownTicks > 0) {
this.attackCooldownTicks--;
}
if (this.flyBurstTicks > 0) {
@@ -248,12 +278,11 @@ public class MantisEntity extends Monster implements GeoEntity {
@Override
public boolean doHurtTarget(net.minecraft.world.entity.Entity target) {
boolean hurt = super.doHurtTarget(target);
if (hurt) {
this.attackAnimationTicks = 10;
this.playSound(AntarchySoundEvents.MANTIS_ATTACK.get(), 1.0F, 0.95F + this.random.nextFloat() * 0.1F);
if (target instanceof LivingEntity livingTarget && this.canBeginCommittedAttack(livingTarget)) {
this.beginCommittedAttack(livingTarget);
return true;
}
return hurt;
return false;
}
@Override
@@ -325,6 +354,110 @@ public class MantisEntity extends Monster implements GeoEntity {
this.setNoGravity(false);
}
protected boolean isAttackLocked() {
return this.attackAnimationTicks > 0;
}
protected boolean canBeginCommittedAttack(LivingEntity target) {
return !this.isAttackLocked()
&& this.attackCooldownTicks <= 0
&& target.isAlive()
&& this.distanceToSqr(target) <= this.getAttackStartRange() * this.getAttackStartRange()
&& this.hasLineOfSight(target);
}
protected void beginCommittedAttack(LivingEntity target) {
this.committedAttackTarget = target;
this.committedAttackYaw = this.yBodyRot;
this.attackAnimationTicks = ATTACK_ANIM_TICKS;
this.attackCooldownTicks = ATTACK_COOLDOWN_TICKS;
this.attackDamageApplied = false;
this.attackStartedInFlight = this.isFlyingNow();
this.getNavigation().stop();
this.setAggressive(true);
this.playSound(AntarchySoundEvents.MANTIS_ATTACK.get(), 1.0F, 0.95F + this.random.nextFloat() * 0.1F);
}
protected void tickCommittedAttack() {
this.getNavigation().stop();
LivingEntity target = this.committedAttackTarget;
if (target == null || !target.isAlive() || !target.level().equals(this.level())) {
this.finishCommittedAttack();
return;
}
if (this.attackAnimationTicks > ATTACK_COMMIT_REMAINING_TICKS) {
this.faceTargetForAttack(target, WINDUP_TURN_RATE);
this.committedAttackYaw = this.yBodyRot;
} else {
this.lockAttackYaw();
}
if (!this.attackDamageApplied && this.attackAnimationTicks == ATTACK_HIT_REMAINING_TICKS) {
this.attackDamageApplied = true;
if (this.canHitCommittedAttackTarget(target)) {
this.applyCommittedAttackDamage(target);
}
}
}
protected void finishCommittedAttack() {
this.attackAnimationTicks = 0;
this.attackDamageApplied = false;
this.attackStartedInFlight = false;
this.committedAttackTarget = null;
}
protected boolean canHitCommittedAttackTarget(LivingEntity target) {
if (!target.isAlive() || !this.hasLineOfSight(target)) {
return false;
}
Vec3 forward = Vec3.directionFromRotation(0.0F, this.committedAttackYaw).normalize();
Vec3 toTarget = target.position().subtract(this.position());
double forwardDistance = toTarget.x * forward.x + toTarget.z * forward.z;
if (forwardDistance < 0.0D || forwardDistance > this.getAttackHitReach()) {
return false;
}
double sideDistance = Math.abs(toTarget.x * forward.z - toTarget.z * forward.x);
if (sideDistance > this.getAttackHalfWidth()) {
return false;
}
double verticalDistance = Math.abs((target.getY() + target.getBbHeight() * 0.5D) - (this.getY() + this.getBbHeight() * 0.5D));
return verticalDistance <= this.getAttackVerticalTolerance();
}
protected boolean applyCommittedAttackDamage(LivingEntity target) {
return super.doHurtTarget(target);
}
protected void faceTargetForAttack(LivingEntity target, float maxTurnDegrees) {
double dx = target.getX() - this.getX();
double dz = target.getZ() - this.getZ();
if (dx * dx + dz * dz < 1.0E-4D) {
return;
}
float targetYaw = (float) (Mth.atan2(dz, dx) * (180.0D / Math.PI)) - 90.0F;
float yaw = this.approachYaw(this.getYRot(), targetYaw, maxTurnDegrees);
this.setYRot(yaw);
this.setYHeadRot(yaw);
this.yBodyRot = yaw;
}
protected float approachYaw(float currentYaw, float targetYaw, float maxTurnDegrees) {
float delta = Mth.wrapDegrees(targetYaw - currentYaw);
delta = Math.max(-maxTurnDegrees, Math.min(maxTurnDegrees, delta));
return currentYaw + delta;
}
protected void lockAttackYaw() {
this.setYRot(this.committedAttackYaw);
this.setYHeadRot(this.committedAttackYaw);
this.yBodyRot = this.committedAttackYaw;
}
private void startFlightBurst() {
this.flyBurstTicks = 40 + this.random.nextInt(30);
this.flyCooldownTicks = 160 + this.random.nextInt(80);
@@ -339,12 +472,22 @@ public class MantisEntity extends Monster implements GeoEntity {
}
private void setAnimationState(int animationState) {
this.entityData.set(ANIMATION_STATE, animationState);
if (this.entityData.get(ANIMATION_STATE) != animationState) {
this.entityData.set(ANIMATION_STATE, animationState);
String trigger = switch (animationState) {
case ANIM_ATTACK -> "attack";
case ANIM_FLY_ATTACK -> "flyattack";
default -> null;
};
if (trigger != null) {
this.triggerAnim("main_controller", trigger);
}
}
}
private void updateAnimationState() {
if (this.attackAnimationTicks > 0) {
this.setAnimationState(this.isFlyingNow() ? ANIM_FLY_ATTACK : ANIM_ATTACK);
this.setAnimationState(this.attackStartedInFlight || this.isFlyingNow() ? ANIM_FLY_ATTACK : ANIM_ATTACK);
return;
}
@@ -380,6 +523,22 @@ public class MantisEntity extends Monster implements GeoEntity {
return this.flyBurstTicks > 0;
}
protected double getAttackStartRange() {
return ATTACK_START_RANGE;
}
protected double getAttackHitReach() {
return ATTACK_HIT_REACH;
}
protected double getAttackHalfWidth() {
return ATTACK_HALF_WIDTH;
}
protected double getAttackVerticalTolerance() {
return ATTACK_VERTICAL_TOLERANCE;
}
private void syncConfiguredAttributes(boolean rescaleCurrentHealth) {
syncAttribute(this.getAttribute(Attributes.MAX_HEALTH), this.configuredMaxHealth(), rescaleCurrentHealth);
syncAttribute(this.getAttribute(Attributes.ATTACK_DAMAGE), this.configuredAttackDamage(), false);
@@ -431,6 +590,63 @@ public class MantisEntity extends Monster implements GeoEntity {
);
}
private final class MantisCombatGoal extends Goal {
private int repathTicks;
private MantisCombatGoal() {
this.setFlags(EnumSet.of(Goal.Flag.MOVE, Goal.Flag.LOOK));
}
@Override
public boolean canUse() {
LivingEntity target = MantisEntity.this.getTarget();
return target != null && target.isAlive();
}
@Override
public boolean canContinueToUse() {
LivingEntity target = MantisEntity.this.getTarget();
return MantisEntity.this.isAttackLocked() || (target != null && target.isAlive());
}
@Override
public void start() {
MantisEntity.this.setAggressive(true);
this.repathTicks = 0;
}
@Override
public void stop() {
if (!MantisEntity.this.isAttackLocked()) {
MantisEntity.this.setAggressive(false);
MantisEntity.this.getNavigation().stop();
}
}
@Override
public void tick() {
if (MantisEntity.this.isAttackLocked()) {
return;
}
LivingEntity target = MantisEntity.this.getTarget();
if (target == null || !target.isAlive()) {
return;
}
if (MantisEntity.this.canBeginCommittedAttack(target)) {
MantisEntity.this.beginCommittedAttack(target);
return;
}
MantisEntity.this.getLookControl().setLookAt(target, 30.0F, 30.0F);
if (--this.repathTicks <= 0) {
this.repathTicks = 4 + MantisEntity.this.random.nextInt(5);
MantisEntity.this.getNavigation().moveTo(target, MantisEntity.this.getCombatSpeed());
}
}
}
@@ -143,7 +143,8 @@ public class MissileSquidEntity extends Monster implements GeoEntity {
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
controllers.add(new AnimationController<>(this, "main_controller", 0, this::mainAnimController));
controllers.add(new AnimationController<>(this, "main_controller", 0, this::mainAnimController)
.triggerableAnim("attack", ATTACK_ANIM));
}
private PlayState mainAnimController(AnimationState<MissileSquidEntity> state) {
@@ -691,7 +692,12 @@ public class MissileSquidEntity extends Monster implements GeoEntity {
}
private void setAnimationState(int animationState) {
this.entityData.set(ANIMATION_STATE, animationState);
if (this.entityData.get(ANIMATION_STATE) != animationState) {
this.entityData.set(ANIMATION_STATE, animationState);
if (animationState == ANIM_ATTACK) {
this.triggerAnim("main_controller", "attack");
}
}
}
private void playActionAnimation(int animationState, int ticks) {
@@ -160,7 +160,11 @@ public class MolevoreEntity extends Monster implements GeoEntity {
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
controllers.add(new AnimationController<>(this, "main_controller", 0, this::mainAnimController));
controllers.add(new AnimationController<>(this, "main_controller", 0, this::mainAnimController)
.triggerableAnim("dig_up", DIG_UP_ANIM)
.triggerableAnim("claw_swipe", CLAW_SWIPE_ANIM)
.triggerableAnim("spin_charge", SPINNING_ANIM)
.triggerableAnim("hurt", HURT_ANIM));
}
private PlayState mainAnimController(AnimationState<MolevoreEntity> state) {
@@ -677,7 +681,19 @@ public class MolevoreEntity extends Monster implements GeoEntity {
}
private void setActionState(int actionState) {
this.entityData.set(ACTION_STATE, actionState);
if (this.entityData.get(ACTION_STATE) != actionState) {
this.entityData.set(ACTION_STATE, actionState);
String trigger = switch (actionState) {
case ACTION_DIG_UP -> "dig_up";
case ACTION_CLAW_SWIPE, ACTION_IDLE_DIG -> "claw_swipe";
case ACTION_SPIN_CHARGE -> "spin_charge";
case ACTION_HURT -> "hurt";
default -> null;
};
if (trigger != null) {
this.triggerAnim("main_controller", trigger);
}
}
}
private boolean canBreakBlocks() {
@@ -112,7 +112,8 @@ public class MolewormEntity extends Monster implements GeoEntity {
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
controllers.add(new AnimationController<>(this, "main_controller", 0, this::mainAnimController));
controllers.add(new AnimationController<>(this, "main_controller", 0, this::mainAnimController)
.triggerableAnim("dig", DIG_ANIM));
}
private PlayState mainAnimController(AnimationState<MolewormEntity> state) {
@@ -224,7 +225,12 @@ public class MolewormEntity extends Monster implements GeoEntity {
}
private void setAnimationState(int animationState) {
this.entityData.set(ANIMATION_STATE, animationState);
if (this.entityData.get(ANIMATION_STATE) != animationState) {
this.entityData.set(ANIMATION_STATE, animationState);
if (animationState == ANIM_DIG) {
this.triggerAnim("main_controller", "dig");
}
}
}
private void startMerge(BlockPos targetPos) {
@@ -165,7 +165,10 @@ public class OctopusBombEntity extends Monster implements GeoEntity {
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
controllers.add(new AnimationController<>(this, "main_controller", 0, this::mainAnimController)
.setSoundKeyframeHandler(new AutoPlayingSoundKeyframeHandler<>()));
.setSoundKeyframeHandler(new AutoPlayingSoundKeyframeHandler<>())
.triggerableAnim("Grab", GRAB_ANIM)
.triggerableAnim("Swipe", SWIPE_ANIM)
.triggerableAnim("Death", DEATH_ANIM));
}
private PlayState mainAnimController(AnimationState<OctopusBombEntity> state) {
@@ -335,7 +338,18 @@ public class OctopusBombEntity extends Monster implements GeoEntity {
}
private void setAnimationState(int state) {
this.entityData.set(ANIMATION_STATE, state);
if (this.entityData.get(ANIMATION_STATE) != state) {
this.entityData.set(ANIMATION_STATE, state);
String trigger = switch (state) {
case ANIM_GRAB -> "Grab";
case ANIM_SWIPE -> "Swipe";
case ANIM_DEATH -> "Death";
default -> null;
};
if (trigger != null) {
this.triggerAnim("main_controller", trigger);
}
}
}
public void launchAsProjectile(net.minecraft.world.entity.Entity owner, Vec3 velocity) {
@@ -366,7 +366,17 @@ public class RollyPollyEntity extends TamableAnimal implements GeoEntity {
}
private void setAnimationState(int state) {
this.entityData.set(ANIMATION_STATE, state);
if (this.entityData.get(ANIMATION_STATE) != state) {
this.entityData.set(ANIMATION_STATE, state);
String trigger = switch (state) {
case ANIM_ROLL_UP -> "wheel_mode";
case ANIM_UNROLL -> "normal_mode";
default -> null;
};
if (trigger != null) {
this.triggerAnim("main_controller", trigger);
}
}
}
@Override
@@ -400,7 +410,9 @@ public class RollyPollyEntity extends TamableAnimal implements GeoEntity {
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
controllers.add(new AnimationController<>(this, "main_controller", 2, this::mainAnimController));
controllers.add(new AnimationController<>(this, "main_controller", 2, this::mainAnimController)
.triggerableAnim("wheel_mode", ROLL_UP_ANIM)
.triggerableAnim("normal_mode", UNROLL_ANIM));
}
private PlayState mainAnimController(AnimationState<RollyPollyEntity> state) {
@@ -160,6 +160,7 @@ public class ScorpionEntity extends Monster implements GeoEntity {
this.attackDamageApplied = false;
this.getNavigation().stop();
this.level().broadcastEntityEvent(this, ATTACK_ANIM_EVENT);
this.triggerAnim("main", "attack");
this.commitLunge(target, 0.48D, 0.12D);
}
@@ -220,7 +221,8 @@ public class ScorpionEntity extends Monster implements GeoEntity {
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
controllers.add(new AnimationController<>(this, "main", 3, this::mainController));
controllers.add(new AnimationController<>(this, "main", 3, this::mainController)
.triggerableAnim("attack", ATTACK_ANIM));
}
private PlayState mainController(AnimationState<ScorpionEntity> state) {
@@ -115,7 +115,8 @@ public class SpitBugEntity extends Monster implements GeoEntity {
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
controllers.add(new AnimationController<>(this, "main_controller", 2, this::mainAnimController));
controllers.add(new AnimationController<>(this, "main_controller", 2, this::mainAnimController)
.triggerableAnim("spit", SPIT_ANIM));
}
@Override
@@ -201,6 +202,7 @@ public class SpitBugEntity extends Monster implements GeoEntity {
this.spitAnimationTicks = SPIT_ANIMATION_TICKS;
this.spitReleaseTicks = SPIT_RELEASE_TICKS;
this.entityData.set(SPIT_ANIM_TICKS, this.spitAnimationTicks);
this.triggerAnim("main_controller", "spit");
}
@SuppressWarnings("unchecked")
@@ -190,7 +190,11 @@ public class ToreterrorEntity extends Monster implements GeoEntity {
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
controllers.add(new AnimationController<>(this, "main_controller", 0, this::mainAnimController));
controllers.add(new AnimationController<>(this, "main_controller", 0, this::mainAnimController)
.triggerableAnim("jump_attack", JUMP_ANIM)
.triggerableAnim("spin_attack_start", SPIN_START_ANIM)
.triggerableAnim("spin_attack", SPIN_LOOP_ANIM)
.triggerableAnim("spin_attack_end", SPIN_END_ANIM));
}
private PlayState mainAnimController(AnimationState<ToreterrorEntity> state) {
@@ -397,6 +401,16 @@ public class ToreterrorEntity extends Monster implements GeoEntity {
private void setAnimationState(int state) {
if (this.entityData.get(ANIMATION_STATE) != state) {
this.entityData.set(ANIMATION_STATE, state);
String trigger = switch (state) {
case ANIM_JUMP_ATTACK -> "jump_attack";
case ANIM_SPIN_START -> "spin_attack_start";
case ANIM_SPIN_LOOP -> "spin_attack";
case ANIM_SPIN_END -> "spin_attack_end";
default -> null;
};
if (trigger != null) {
this.triggerAnim("main_controller", trigger);
}
}
}
@@ -157,7 +157,10 @@ public class TriffidEntity extends Monster implements GeoEntity {
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
controllers.add(new AnimationController<>(this, "main_controller", 0, this::mainAnimController));
controllers.add(new AnimationController<>(this, "main_controller", 0, this::mainAnimController)
.triggerableAnim("attack", SWEEP_ANIM)
.triggerableAnim("grab", GRAB_ANIM)
.triggerableAnim("death", DEATH_ANIM));
}
private PlayState mainAnimController(AnimationState<TriffidEntity> state) {
@@ -528,7 +531,18 @@ public class TriffidEntity extends Monster implements GeoEntity {
}
private void setActionState(int state) {
this.entityData.set(ACTION_STATE, state);
if (this.entityData.get(ACTION_STATE) != state) {
this.entityData.set(ACTION_STATE, state);
String trigger = switch (state) {
case ACTION_SWEEP -> "attack";
case ACTION_GRAB -> "grab";
case ACTION_DEATH -> "death";
default -> null;
};
if (trigger != null) {
this.triggerAnim("main_controller", trigger);
}
}
}
private boolean isAwake() {
@@ -235,6 +235,7 @@ public class WaspEntity extends Monster implements GeoEntity, FlyingAnimal {
this.swing(InteractionHand.MAIN_HAND);
if (!this.level().isClientSide) {
this.level().broadcastEntityEvent(this, ATTACK_ANIM_EVENT);
this.triggerAnim("main_controller", "attack");
}
}
@@ -275,7 +276,8 @@ public class WaspEntity extends Monster implements GeoEntity, FlyingAnimal {
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
controllers.add(new AnimationController<>(this, "main_controller", 0, this::mainAnimController));
controllers.add(new AnimationController<>(this, "main_controller", 0, this::mainAnimController)
.triggerableAnim("attack", ATTACK_ANIM));
}
@Override
@@ -175,7 +175,9 @@ public abstract class BaseAntEntity extends Animal implements GeoEntity {
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
controllers.add(new AnimationController<>(this, "main_controller", 2, this::mainAnimController));
controllers.add(new AnimationController<>(this, "main_controller", 2, this::mainAnimController)
.triggerableAnim("dance", DANCE_ANIM)
.triggerableAnim("attack", ATTACK_ANIM));
}
@Override
@@ -1144,7 +1146,14 @@ public abstract class BaseAntEntity extends Animal implements GeoEntity {
}
private void setDancing(boolean dancing) {
this.entityData.set(DANCING, dancing);
if (this.isDancing() != dancing) {
this.entityData.set(DANCING, dancing);
if (dancing) {
this.triggerAnim("main_controller", "dance");
} else {
this.stopTriggeredAnim("main_controller", "dance");
}
}
}
private void tickJukeboxDanceState() {
@@ -1256,7 +1265,14 @@ public abstract class BaseAntEntity extends Animal implements GeoEntity {
}
private void setBiteAnimationTicks(int ticks) {
this.entityData.set(BITE_ANIM_TICKS, Math.max(0, ticks));
int clamped = Math.max(0, ticks);
int previous = this.getBiteAnimationTicks();
this.entityData.set(BITE_ANIM_TICKS, clamped);
if (previous <= 0 && clamped > 0) {
this.triggerAnim("main_controller", "attack");
} else if (previous > 0 && clamped <= 0) {
this.stopTriggeredAnim("main_controller", "attack");
}
}
protected final void triggerBiteAnimation(int ticks) {
@@ -445,7 +445,8 @@ public class BasiliskEntity extends Monster implements GeoEntity {
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
controllers.add(new AnimationController<>(this, "main", 3, this::mainController)
.setSoundKeyframeHandler(new AutoPlayingSoundKeyframeHandler<>()));
.setSoundKeyframeHandler(new AutoPlayingSoundKeyframeHandler<>())
.triggerableAnim("attack", ATTACK_ANIM));
}
private PlayState mainController(AnimationState<BasiliskEntity> state) {
@@ -544,7 +545,12 @@ public class BasiliskEntity extends Monster implements GeoEntity {
}
private void setAnimationState(int state) {
this.entityData.set(ANIMATION_STATE, state);
if (this.entityData.get(ANIMATION_STATE) != state) {
this.entityData.set(ANIMATION_STATE, state);
if (state == ANIM_ATTACK) {
this.triggerAnim("main", "attack");
}
}
}
@Override
@@ -197,7 +197,14 @@ public class BrutalflyEntity extends Monster implements GeoEntity {
case ANIM_COCOON_IDLE -> state.setAndContinue(COOCON_IDLE_ANIM);
case ANIM_COCOON_HATCH -> state.setAndContinue(COOCON_HATCH_ANIM);
default -> state.setAndContinue(IDLE_ANIM);
}));
})
.triggerableAnim("spit", SPIT_ANIM)
.triggerableAnim("swipe", SWIPE_ANIM)
.triggerableAnim("death", DEATH_ANIM)
.triggerableAnim("Coocon", COOCON_ANIM)
.triggerableAnim("Coocon_hit", COOCON_HIT_ANIM)
.triggerableAnim("Coocon_idle", COOCON_IDLE_ANIM)
.triggerableAnim("Coocon_hatch", COOCON_HATCH_ANIM));
}
@Override
@@ -618,7 +625,26 @@ public class BrutalflyEntity extends Monster implements GeoEntity {
}
private void setAnimationState(int animationState) {
this.entityData.set(ANIMATION_STATE, animationState);
int previous = this.entityData.get(ANIMATION_STATE);
if (previous != animationState) {
this.entityData.set(ANIMATION_STATE, animationState);
String trigger = switch (animationState) {
case ANIM_SPIT -> "spit";
case ANIM_SWIPE -> "swipe";
case ANIM_DEATH -> "death";
case ANIM_COCOON -> "Coocon";
case ANIM_COCOON_HIT -> "Coocon_hit";
case ANIM_COCOON_IDLE -> "Coocon_idle";
case ANIM_COCOON_HATCH -> "Coocon_hatch";
default -> null;
};
if (trigger != null) {
this.triggerAnim("main_controller", trigger);
}
if (previous == ANIM_COCOON_IDLE && animationState != ANIM_COCOON_IDLE) {
this.stopTriggeredAnim("main_controller", "Coocon_idle");
}
}
}
private void updateBaseAnimationState() {
@@ -353,7 +353,8 @@ public class CloudSharkEntity extends Monster implements GeoEntity {
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
controllers.add(new AnimationController<>(this, "main_controller", 0, this::mainAnimController));
controllers.add(new AnimationController<>(this, "main_controller", 0, this::mainAnimController)
.triggerableAnim("attack", ATTACK_ANIM));
}
@Override
@@ -550,7 +551,12 @@ public class CloudSharkEntity extends Monster implements GeoEntity {
}
private void setAnimationState(int animationState) {
this.entityData.set(ANIMATION_STATE, animationState);
if (this.entityData.get(ANIMATION_STATE) != animationState) {
this.entityData.set(ANIMATION_STATE, animationState);
if (animationState == ANIM_ATTACK) {
this.triggerAnim("main_controller", "attack");
}
}
}
private void updateAnimationState() {
@@ -2507,4 +2507,16 @@ public class FlyingSquirrelEntity extends TamableAnimal implements GeoEntity {
}
}
}
@Override
public boolean isPushable() {
return !this.isOnShoulder() && super.isPushable();
}
@Override
public void push(Entity entity) {
if (!this.isOnShoulder()) {
super.push(entity);
}
}
}
@@ -207,7 +207,12 @@ public class KrakenEntity extends Monster implements GeoEntity, MultipartEntityO
return PlayState.CONTINUE;
}).setSoundKeyframeHandler(new AutoPlayingSoundKeyframeHandler<>()));
controllers.add(new AnimationController<>(this, "action_controller", 0, this::actionAnimController)
.setSoundKeyframeHandler(new AutoPlayingSoundKeyframeHandler<>()));
.setSoundKeyframeHandler(new AutoPlayingSoundKeyframeHandler<>())
.triggerableAnim("cry", CRY_ANIM)
.triggerableAnim("grab", GRAB_ANIM)
.triggerableAnim("swing_left", SWING_LEFT_ANIM)
.triggerableAnim("swing_right", SWING_RIGHT_ANIM)
.triggerableAnim("attack", SLAM_ANIM));
}
private PlayState actionAnimController(AnimationState<KrakenEntity> state) {
@@ -508,7 +513,20 @@ public class KrakenEntity extends Monster implements GeoEntity, MultipartEntityO
}
private void setAnimationState(int animationState) {
this.entityData.set(ANIMATION_STATE, animationState);
if (this.entityData.get(ANIMATION_STATE) != animationState) {
this.entityData.set(ANIMATION_STATE, animationState);
String trigger = switch (animationState) {
case ANIM_CRY -> "cry";
case ANIM_GRAB -> "grab";
case ANIM_SWING_LEFT -> "swing_left";
case ANIM_SWING_RIGHT -> "swing_right";
case ANIM_SLAM -> "attack";
default -> null;
};
if (trigger != null) {
this.triggerAnim("action_controller", trigger);
}
}
}
private void startAggroRoar() {
@@ -154,7 +154,9 @@ public class LucidEntity extends Monster implements GeoEntity {
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
controllers.add(new AnimationController<>(this, "main_controller", 0, this::mainAnimController));
controllers.add(new AnimationController<>(this, "main_controller", 0, this::mainAnimController)
.triggerableAnim("attack", ATTACK_ANIM)
.triggerableAnim("death", DEATH_ANIM));
}
private PlayState mainAnimController(AnimationState<LucidEntity> state) {
@@ -434,7 +436,17 @@ public class LucidEntity extends Monster implements GeoEntity {
}
private void setAnimationState(int state) {
this.entityData.set(ANIMATION_STATE, state);
if (this.entityData.get(ANIMATION_STATE) != state) {
this.entityData.set(ANIMATION_STATE, state);
String trigger = switch (state) {
case ANIM_ATTACK -> "attack";
case ANIM_DEATH -> "death";
default -> null;
};
if (trigger != null) {
this.triggerAnim("main_controller", trigger);
}
}
}
private void updateAnimationState() {
@@ -1077,7 +1077,7 @@ public class NightmareEntity extends Monster implements GeoEntity {
}
target.addEffect(new MobEffectInstance(MobEffects.WEAKNESS, WEAKNESS_TICKS, 0));
if (this.level() instanceof ServerLevel serverLevel) {
serverLevel.sendParticles(ParticleTypes.SOUL_FIRE_FLAME, target.getX(), target.getY(0.8D), target.getZ(), 10, 0.28D, 0.22D, 0.28D, 0.01D);
serverLevel.sendParticles(AntarchyObjects.NIGHTMARE_FIRE_FLAME.get(), target.getX(), target.getY(0.8D), target.getZ(), 10, 0.28D, 0.22D, 0.28D, 0.01D);
serverLevel.sendParticles(ParticleTypes.SMOKE, target.getX(), target.getY(0.8D), target.getZ(), 6, 0.22D, 0.16D, 0.22D, 0.02D);
}
}
@@ -39,9 +39,9 @@ import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.item.UseAnim;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.DoublePlantBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.DoubleBlockHalf;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec2;
@@ -449,17 +449,16 @@ public class GravityGunItem extends Item implements GeoItem {
return false;
}
if (state.getBlock() instanceof DoublePlantBlock) {
if (!state.hasProperty(net.minecraft.world.level.block.state.properties.BlockStateProperties.DOUBLE_BLOCK_HALF)
|| state.getValue(net.minecraft.world.level.block.state.properties.BlockStateProperties.DOUBLE_BLOCK_HALF) != DoubleBlockHalf.LOWER) {
if (state.hasProperty(BlockStateProperties.DOUBLE_BLOCK_HALF)) {
if (state.getValue(BlockStateProperties.DOUBLE_BLOCK_HALF) != DoubleBlockHalf.LOWER) {
return false;
}
BlockPos upperPos = pos.above();
BlockState upperState = level.getBlockState(upperPos);
if (!upperState.is(state.getBlock())
|| !upperState.hasProperty(net.minecraft.world.level.block.state.properties.BlockStateProperties.DOUBLE_BLOCK_HALF)
|| upperState.getValue(net.minecraft.world.level.block.state.properties.BlockStateProperties.DOUBLE_BLOCK_HALF) != DoubleBlockHalf.UPPER) {
|| !upperState.hasProperty(BlockStateProperties.DOUBLE_BLOCK_HALF)
|| upperState.getValue(BlockStateProperties.DOUBLE_BLOCK_HALF) != DoubleBlockHalf.UPPER) {
return false;
}
}
@@ -469,23 +468,21 @@ public class GravityGunItem extends Item implements GeoItem {
private CarriedBlockCapture resolveCarriedBlockCapture(Level level, BlockPos clickedPos) {
BlockState clickedState = level.getBlockState(clickedPos);
if (!(clickedState.getBlock() instanceof DoublePlantBlock)
|| !clickedState.hasProperty(net.minecraft.world.level.block.state.properties.BlockStateProperties.DOUBLE_BLOCK_HALF)) {
if (!clickedState.hasProperty(BlockStateProperties.DOUBLE_BLOCK_HALF)) {
return new CarriedBlockCapture(clickedPos, clickedState, null);
}
DoubleBlockHalf half = clickedState.getValue(net.minecraft.world.level.block.state.properties.BlockStateProperties.DOUBLE_BLOCK_HALF);
DoubleBlockHalf half = clickedState.getValue(BlockStateProperties.DOUBLE_BLOCK_HALF);
BlockPos basePos = half == DoubleBlockHalf.UPPER ? clickedPos.below() : clickedPos;
BlockPos upperPos = basePos.above();
BlockState baseState = level.getBlockState(basePos);
BlockState upperState = level.getBlockState(upperPos);
if (!(baseState.getBlock() instanceof DoublePlantBlock)
|| !baseState.is(clickedState.getBlock())
|| !baseState.hasProperty(net.minecraft.world.level.block.state.properties.BlockStateProperties.DOUBLE_BLOCK_HALF)
|| baseState.getValue(net.minecraft.world.level.block.state.properties.BlockStateProperties.DOUBLE_BLOCK_HALF) != DoubleBlockHalf.LOWER
if (!baseState.is(clickedState.getBlock())
|| !baseState.hasProperty(BlockStateProperties.DOUBLE_BLOCK_HALF)
|| baseState.getValue(BlockStateProperties.DOUBLE_BLOCK_HALF) != DoubleBlockHalf.LOWER
|| !upperState.is(clickedState.getBlock())
|| !upperState.hasProperty(net.minecraft.world.level.block.state.properties.BlockStateProperties.DOUBLE_BLOCK_HALF)
|| upperState.getValue(net.minecraft.world.level.block.state.properties.BlockStateProperties.DOUBLE_BLOCK_HALF) != DoubleBlockHalf.UPPER) {
|| !upperState.hasProperty(BlockStateProperties.DOUBLE_BLOCK_HALF)
|| upperState.getValue(BlockStateProperties.DOUBLE_BLOCK_HALF) != DoubleBlockHalf.UPPER) {
return null;
}
@@ -8,15 +8,19 @@ import net.minecraft.ChatFormatting;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.EquipmentSlotGroup;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.attributes.Attribute;
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ArmorItem;
import net.minecraft.world.item.ArmorMaterial;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.item.component.ItemAttributeModifiers;
import net.minecraft.world.level.Level;
public class NightmareArmorItem extends ArmorItem {
private static final int BASE_DURABILITY_MULTIPLIER = 33;
@@ -113,6 +117,21 @@ public class NightmareArmorItem extends ArmorItem {
return stack.getCount() == 1;
}
@Override
public void inventoryTick(ItemStack stack, Level level, Entity entity, int slotId, boolean isSelected) {
super.inventoryTick(stack, level, entity, slotId, isSelected);
if (level.isClientSide || !(entity instanceof LivingEntity livingEntity)) {
return;
}
if (livingEntity.getItemBySlot(this.armorType.getSlot()) != stack || !isWearingFullSet(livingEntity)) {
return;
}
livingEntity.removeEffect(MobEffects.WITHER);
livingEntity.removeEffect(AntarchyObjects.DREAD.get());
}
@Override
public void appendHoverText(ItemStack stack, Item.TooltipContext context, List<Component> tooltipComponents, TooltipFlag tooltipFlag) {
int pct = (int) Math.round(getDoubleDamageChance() * 100);
@@ -121,6 +140,15 @@ public class NightmareArmorItem extends ArmorItem {
super.appendHoverText(stack, context, tooltipComponents, tooltipFlag);
}
public static boolean isWearingFullSet(LivingEntity livingEntity) {
for (ItemStack armorStack : livingEntity.getArmorSlots()) {
if (!(armorStack.getItem() instanceof NightmareArmorItem)) {
return false;
}
}
return true;
}
private static int resolveDurability(Type armorType) {
return switch (armorType) {
case HELMET -> Type.HELMET.getDurability(BASE_DURABILITY_MULTIPLIER);
@@ -44,7 +44,7 @@ import java.util.function.Consumer;
public class SizeRayItem extends ProjectileWeaponItem implements GeoItem {
private static final String FIRE_CONTROLLER = "fire_controller";
private static final int CHARGE_TICKS_PER_LEVEL = 5;
private static final int CHARGE_SOUND_INTERVAL_TICKS = 12;
public static final int LOOP_SOUND_START_TICKS = 140;
private static final int MAX_USE_DURATION = 72000;
private static final Predicate<ItemStack> NO_PROJECTILES = stack -> false;
private final Supplier<? extends EntityType<? extends SizeRayProjectileEntity>> projectileType;
@@ -114,10 +114,10 @@ public class SizeRayItem extends ProjectileWeaponItem implements GeoItem {
player.getX(),
player.getY(),
player.getZ(),
this.getFireSound(),
getFireSound(chargeLevel),
SoundSource.PLAYERS,
1.0F,
0.95F + 0.12F * (chargeLevel - 1) + 1.0F / (level.getRandom().nextFloat() * 0.4F + 1.2F)
0.96F + 0.04F * (chargeLevel - 1) + level.getRandom().nextFloat() * 0.08F
);
player.awardStat(Stats.ITEM_USED.get(this));
double cooldownSeconds = AntarchySettings.sizeRayCooldownSeconds();
@@ -127,28 +127,6 @@ public class SizeRayItem extends ProjectileWeaponItem implements GeoItem {
}
}
@Override
public void onUseTick(Level level, LivingEntity livingEntity, ItemStack stack, int remainingUseDuration) {
super.onUseTick(level, livingEntity, stack, remainingUseDuration);
if (level.isClientSide() || !AntarchySettings.sizeChangingRaysEnabled()) {
return;
}
int useTicks = this.getUseDuration(stack, livingEntity) - remainingUseDuration;
if (useTicks == 1 || useTicks % CHARGE_SOUND_INTERVAL_TICKS == 0) {
level.playSound(
null,
livingEntity.getX(),
livingEntity.getY(),
livingEntity.getZ(),
AntarchySoundEvents.SIZE_RAY_CHARGE.get(),
SoundSource.PLAYERS,
0.15F,
0.95F + level.getRandom().nextFloat() * 0.08F
);
}
}
@Override
public UseAnim getUseAnimation(ItemStack stack) {
return UseAnim.NONE;
@@ -237,13 +215,29 @@ public class SizeRayItem extends ProjectileWeaponItem implements GeoItem {
triggerAnim(livingEntity, animatableId, FIRE_CONTROLLER, this.fireAnimationName);
}
private SoundEvent getFireSound() {
public SoundEvent getChargeSound() {
return this.rayType == SizeRayProjectileEntity.SizeRayType.SHRINK
? AntarchySoundEvents.SHRINK_RAY_SOUND.get()
: AntarchySoundEvents.GROWTH_RAY_SOUND.get();
? AntarchySoundEvents.SHRINK_RAY_CHARGE.get()
: AntarchySoundEvents.GROWTH_RAY_CHARGE.get();
}
private static int getChargeLevel(int useTicks) {
public SoundEvent getLoopSound() {
return this.rayType == SizeRayProjectileEntity.SizeRayType.SHRINK
? AntarchySoundEvents.SHRINK_RAY_LOOP.get()
: AntarchySoundEvents.GROWTH_RAY_LOOP.get();
}
public static int getChargeLevel(int useTicks) {
return Math.max(1, 1 + useTicks / CHARGE_TICKS_PER_LEVEL);
}
private static SoundEvent getFireSound(int chargeLevel) {
if (chargeLevel >= 3) {
return AntarchySoundEvents.SIZE_RAY_CRITSHOT.get();
}
if (chargeLevel == 2) {
return AntarchySoundEvents.SIZE_RAY_MEDIUMSHOT.get();
}
return AntarchySoundEvents.SIZE_RAY_WEAKSHOT.get();
}
}
@@ -174,11 +174,6 @@ public final class PermanentPortalShape {
BlockPos rightFrameBase = bottomLeft.relative(widthDirection, width);
for (int height = 0; height < MAX_SIZE; height++) {
if (!level.getBlockState(leftFrameBase.above(height)).is(frameTag)
|| !level.getBlockState(rightFrameBase.above(height)).is(frameTag)) {
return 0;
}
for (int x = 0; x < width; x++) {
BlockPos interiorPos = bottomLeft.relative(widthDirection, x).above(height);
if (!interiorPredicate.test(level.getBlockState(interiorPos))) {
@@ -188,6 +183,11 @@ public final class PermanentPortalShape {
return hasTopFrame(level, bottomLeft, widthDirection, width, height, frameTag) ? height : 0;
}
}
if (!level.getBlockState(leftFrameBase.above(height)).is(frameTag)
|| !level.getBlockState(rightFrameBase.above(height)).is(frameTag)) {
return 0;
}
}
return hasTopFrame(level, bottomLeft, widthDirection, width, MAX_SIZE, frameTag) ? MAX_SIZE : 0;
@@ -255,7 +255,7 @@ public final class PermanentPortalShape {
continue;
}
if (frameSpot) {
if (!state.isAir() && !state.is(frameBlock) && !state.canBeReplaced()) {
if (y != -1 && !state.isAir() && !state.is(frameBlock) && !state.canBeReplaced()) {
return false;
}
} else if (!state.isAir() && !state.canBeReplaced() && !state.is(Blocks.AIR)) {
@@ -74,10 +74,10 @@ public final class PermanentPortalTeleporter {
if (created != null) {
return created.center();
}
return safe;
return createFallbackPortal(destination, BlockPos.containing(safe), type);
}
return createFallbackPlatform(destination, preferredPos, type.platformBlock().defaultBlockState());
return createFallbackPortal(destination, preferredPos, type);
}
@Nullable
@@ -199,19 +199,31 @@ public final class PermanentPortalTeleporter {
return null;
}
private static Vec3 createFallbackPlatform(ServerLevel destination, BlockPos preferredPos, BlockState platformState) {
private static Vec3 createFallbackPortal(ServerLevel destination, BlockPos preferredPos, PermanentPortalType type) {
int minY = destination.getMinBuildHeight() + 2;
int maxY = destination.getMaxBuildHeight() - 4;
BlockPos center = new BlockPos(preferredPos.getX(), Mth.clamp(preferredPos.getY(), minY, maxY), preferredPos.getZ());
BlockState platformState = type.platformBlock().defaultBlockState();
for (int dx = -1; dx <= 1; dx++) {
for (int dz = -1; dz <= 1; dz++) {
for (int dx = -2; dx <= 2; dx++) {
for (int dz = -2; dz <= 2; dz++) {
destination.setBlock(center.offset(dx, -1, dz), platformState, Block.UPDATE_ALL);
destination.removeBlock(center.offset(dx, 0, dz), false);
destination.removeBlock(center.offset(dx, 1, dz), false);
for (int dy = 0; dy <= 4; dy++) {
destination.removeBlock(center.offset(dx, dy, dz), false);
}
}
}
PermanentPortalShape xShape = PermanentPortalShape.create(destination, center, type, Direction.Axis.X);
if (xShape != null) {
return xShape.center();
}
PermanentPortalShape zShape = PermanentPortalShape.create(destination, center, type, Direction.Axis.Z);
if (zShape != null) {
return zShape.center();
}
return Vec3.atBottomCenterOf(center);
}
@@ -19,7 +19,6 @@ import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.DoublePlantBlock;
import net.minecraft.world.level.block.FallingBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
@@ -47,7 +46,7 @@ public abstract class FallingBlockEntityBlockDataMixin {
)
private boolean antarchy$placeDoublePlantCarriedBlock(Level level, BlockPos pos, BlockState state, int flags, Operation<Boolean> original) {
FallingBlockEntity entity = (FallingBlockEntity) (Object) this;
if (!entity.getTags().contains(GravityGunItem.GRAVITY_GUN_CARRIED_BLOCK_TAG) || !this.antarchy$isCarriedDoublePlant(state)) {
if (!entity.getTags().contains(GravityGunItem.GRAVITY_GUN_CARRIED_BLOCK_TAG) || !this.antarchy$isCarriedDoubleBlock(state)) {
return original.call(level, pos, state, flags);
}
@@ -115,7 +114,7 @@ public abstract class FallingBlockEntityBlockDataMixin {
}
BlockState placeState = fallingState;
if (this.antarchy$isCarriedDoublePlant(placeState)) {
if (this.antarchy$isCarriedDoubleBlock(placeState)) {
if (this.antarchy$tryPlaceExact(level, pos, placeState)) {
self.discard();
return true;
@@ -140,7 +139,7 @@ public abstract class FallingBlockEntityBlockDataMixin {
}
private boolean antarchy$canPlaceAt(Level level, BlockPos pos, BlockState fallingState) {
if (this.antarchy$isCarriedDoublePlant(fallingState)) {
if (this.antarchy$isCarriedDoubleBlock(fallingState)) {
BlockState existingLower = level.getBlockState(pos);
BlockState existingUpper = level.getBlockState(pos.above());
boolean canReplaceLower = existingLower.canBeReplaced(
@@ -166,13 +165,20 @@ public abstract class FallingBlockEntityBlockDataMixin {
return false;
}
DoublePlantBlock.placeAt(level, fallingState.setValue(BlockStateProperties.DOUBLE_BLOCK_HALF, DoubleBlockHalf.LOWER), pos, 3);
BlockState lowerState = fallingState.setValue(BlockStateProperties.DOUBLE_BLOCK_HALF, DoubleBlockHalf.LOWER);
BlockState upperState = fallingState.setValue(BlockStateProperties.DOUBLE_BLOCK_HALF, DoubleBlockHalf.UPPER);
if (!level.setBlock(pos, lowerState, 3)) {
return false;
}
if (!level.setBlock(pos.above(), upperState, 3)) {
level.removeBlock(pos, false);
return false;
}
return true;
}
private boolean antarchy$isCarriedDoublePlant(BlockState state) {
return state.getBlock() instanceof DoublePlantBlock
&& state.hasProperty(BlockStateProperties.DOUBLE_BLOCK_HALF)
private boolean antarchy$isCarriedDoubleBlock(BlockState state) {
return state.hasProperty(BlockStateProperties.DOUBLE_BLOCK_HALF)
&& state.getValue(BlockStateProperties.DOUBLE_BLOCK_HALF) == DoubleBlockHalf.LOWER;
}
@@ -33,6 +33,7 @@
"GoopedStepSoundMixin",
"ExperimentalSettingsLevelSummaryMixin",
"NightmareSwordDamageMixin",
"NightmareArmorEffectImmunityMixin",
"PotionBrewingMixin",
"RedStoneWireBlockMixin",
"StinkyCrouchMixin",
@@ -704,9 +704,8 @@
"tooltip.antarchy.lucid_pearl": "Throws an inverted-gravity projectile.",
"tooltip.antarchy.lucid_pearl.detail": "Teleports you to where it lands and applies Inverted.",
"subtitles.antarchy.squidzooka_fire": "Squidzooka fires",
"subtitles.antarchy.shrink_ray": "Shrink Ray fires",
"subtitles.antarchy.growth_ray": "Growth Ray fires",
"subtitles.antarchy.size_ray_charge": "Size Ray charges",
"subtitles.antarchy.size_ray_fire": "Size Ray fires",
"subtitles.antarchy.ant_ambient": "Ants chirp",
"subtitles.antarchy.ant_idle": "Ants idle",
"subtitles.antarchy.ant_hurt": "Ants hurt",
@@ -1,4 +1,22 @@
{
"thoraxis_nightmare_wastes_biome_additions": {
"sounds": [
{ "name": "antarchy:thoraxis_nightmare_wastes_ambient", "type": "event", "weight": 5 },
{ "name": "antarchy:thoraxis_nightmare_wastes_additions", "type": "event" }
]
},
"thoraxis_dream_dunes_biome_additions": {
"sounds": [
{ "name": "antarchy:thoraxis_dream_dunes_ambient", "type": "event", "weight": 5 },
{ "name": "antarchy:thoraxis_dream_dunes_additions", "type": "event" }
]
},
"thoraxis_lucid_pools_biome_additions": {
"sounds": [
{ "name": "antarchy:thoraxis_lucid_pools_ambient", "type": "event", "weight": 5 },
{ "name": "antarchy:thoraxis_lucid_pools_additions", "type": "event" }
]
},
"squidzooka_fire": {
"subtitle": "subtitles.antarchy.squidzooka_fire",
"sounds": [
@@ -16,27 +34,79 @@
}
]
},
"shrink_ray": {
"subtitle": "subtitles.antarchy.shrink_ray",
"sounds": [
{
"name": "antarchy:size_ray/shrink_ray"
}
]
},
"growth_ray": {
"subtitle": "subtitles.antarchy.growth_ray",
"sounds": [
{
"name": "antarchy:size_ray/growth_ray"
}
]
},
"size_ray_charge": {
"shrink_ray_charge": {
"subtitle": "subtitles.antarchy.size_ray_charge",
"sounds": [
{
"name": "antarchy:size_ray/size_ray_charge"
"name": "antarchy:size_ray/shrinkraycharge"
}
]
},
"shrink_ray_loop": {
"subtitle": "subtitles.antarchy.size_ray_charge",
"sounds": [
{
"name": "antarchy:size_ray/shrinkrayloop",
"stream": true
}
]
},
"growth_ray_charge": {
"subtitle": "subtitles.antarchy.size_ray_charge",
"sounds": [
{
"name": "antarchy:size_ray/growraycharge"
}
]
},
"growth_ray_loop": {
"subtitle": "subtitles.antarchy.size_ray_charge",
"sounds": [
{
"name": "antarchy:size_ray/growrayloop",
"stream": true
}
]
},
"size_ray_weakshot": {
"subtitle": "subtitles.antarchy.size_ray_fire",
"sounds": [
{
"name": "antarchy:size_ray/weakshot1"
},
{
"name": "antarchy:size_ray/weakshot2"
},
{
"name": "antarchy:size_ray/weakshot3"
}
]
},
"size_ray_mediumshot": {
"subtitle": "subtitles.antarchy.size_ray_fire",
"sounds": [
{
"name": "antarchy:size_ray/mediumshot1"
},
{
"name": "antarchy:size_ray/mediumshot2"
},
{
"name": "antarchy:size_ray/mediumshot3"
}
]
},
"size_ray_critshot": {
"subtitle": "subtitles.antarchy.size_ray_fire",
"sounds": [
{
"name": "antarchy:size_ray/critshot1"
},
{
"name": "antarchy:size_ray/critshot2"
},
{
"name": "antarchy:size_ray/critshot3"
}
]
},
@@ -0,0 +1,200 @@
{
"type": "minecraft:chest",
"pools": [
{
"entries": [
{
"type": "minecraft:item",
"name": "antarchy:ouranwood_planks",
"weight": 16,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 6.0,
"max": 18.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:ouranwood_acorn",
"weight": 10,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 4.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:bluestone",
"weight": 14,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 3.0,
"max": 10.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:redstone",
"weight": 14,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 4.0,
"max": 12.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:arrow",
"weight": 18,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 10.0,
"max": 28.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:torch",
"weight": 10,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 4.0,
"max": 12.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:iron_pickaxe",
"weight": 6
},
{
"type": "minecraft:item",
"name": "minecraft:iron_axe",
"weight": 6
},
{
"type": "minecraft:item",
"name": "minecraft:bow",
"weight": 6,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 6.0,
"max": 18.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:moss_block",
"weight": 12,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 8.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:vine",
"weight": 8,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 8.0
}
}
]
}
],
"rolls": {
"type": "minecraft:uniform",
"min": 4.0,
"max": 7.0
}
},
{
"entries": [
{
"type": "minecraft:empty",
"weight": 74
},
{
"type": "minecraft:item",
"name": "antarchy:uranium_nugget",
"weight": 5,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 2.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:titanium_nugget",
"weight": 5,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 2.0
}
}
]
}
],
"rolls": 1.0
}
],
"random_sequence": "antarchy:chests/basilisk_lair/generic"
}
@@ -0,0 +1,198 @@
{
"type": "minecraft:chest",
"pools": [
{
"entries": [
{
"type": "minecraft:item",
"name": "antarchy:basilisk_fang",
"weight": 8,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 2.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:basilisk_dagger",
"weight": 3,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 12.0,
"max": 25.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:diamond",
"weight": 8,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 3.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:emerald",
"weight": 12,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 5.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:bluestone",
"weight": 14,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 6.0,
"max": 16.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:redstone",
"weight": 12,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 6.0,
"max": 18.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:crossbow",
"weight": 8,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 10.0,
"max": 24.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:diamond_pickaxe",
"weight": 5,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 12.0,
"max": 24.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:golden_apple",
"weight": 8
},
{
"type": "minecraft:item",
"name": "minecraft:book",
"weight": 8,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 15.0,
"max": 30.0
},
"options": "#minecraft:on_random_loot"
}
]
}
],
"rolls": {
"type": "minecraft:uniform",
"min": 5.0,
"max": 8.0
}
},
{
"entries": [
{
"type": "minecraft:empty",
"weight": 66
},
{
"type": "minecraft:item",
"name": "antarchy:uranium_nugget",
"weight": 7,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 3.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:titanium_nugget",
"weight": 7,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 3.0
}
}
]
}
],
"rolls": 1.0
}
],
"random_sequence": "antarchy:chests/basilisk_lair/treasure"
}
@@ -0,0 +1,210 @@
{
"type": "minecraft:chest",
"pools": [
{
"entries": [
{
"type": "minecraft:item",
"name": "minecraft:potato",
"weight": 20,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 8.0,
"max": 24.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:baked_potato",
"weight": 16,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 4.0,
"max": 12.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:poisonous_potato",
"weight": 4,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 3.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:golden_carrot",
"weight": 8,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 4.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:cooked_porkchop",
"weight": 12,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 8.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:gold_ingot",
"weight": 10,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 5.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:emerald",
"weight": 8,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 3.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:amethyst_shard",
"weight": 8,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 8.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:tigers_eye",
"weight": 5,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 3.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:book",
"weight": 7,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 8.0,
"max": 20.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:golden_apple",
"weight": 4
}
],
"rolls": {
"type": "minecraft:uniform",
"min": 4.0,
"max": 7.0
}
},
{
"entries": [
{
"type": "minecraft:empty",
"weight": 72
},
{
"type": "minecraft:item",
"name": "antarchy:uranium_nugget",
"weight": 6,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 2.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:titanium_nugget",
"weight": 6,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 2.0
}
}
]
}
],
"rolls": 1.0
}
],
"random_sequence": "antarchy:chests/temple_of_technoblade/generic"
}
@@ -0,0 +1,170 @@
{
"type": "minecraft:chest",
"pools": [
{
"entries": [
{
"type": "minecraft:item",
"name": "minecraft:diamond",
"weight": 12,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 4.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:emerald",
"weight": 16,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 7.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:gold_ingot",
"weight": 18,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 4.0,
"max": 12.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:amethyst_shard",
"weight": 14,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 4.0,
"max": 12.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:blood_crystal_shard",
"weight": 9,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 4.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:tigers_eye",
"weight": 10,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 4.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:golden_apple",
"weight": 8
},
{
"type": "minecraft:item",
"name": "minecraft:book",
"weight": 8,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 18.0,
"max": 30.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:fallen_king_crown",
"weight": 2
}
],
"rolls": {
"type": "minecraft:uniform",
"min": 5.0,
"max": 8.0
}
},
{
"entries": [
{
"type": "minecraft:empty",
"weight": 64
},
{
"type": "minecraft:item",
"name": "antarchy:uranium_nugget",
"weight": 7,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 3.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:titanium_nugget",
"weight": 7,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 3.0
}
}
]
}
],
"rolls": 1.0
}
],
"random_sequence": "antarchy:chests/temple_of_technoblade/treasure"
}
@@ -0,0 +1,214 @@
{
"type": "minecraft:chest",
"pools": [
{
"entries": [
{
"type": "minecraft:item",
"name": "antarchy:basilisk_fang",
"weight": 8,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 2.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:basilisk_dagger",
"weight": 3,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 18.0,
"max": 30.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:crossbow",
"weight": 10,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 20.0,
"max": 30.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:diamond_sword",
"weight": 8,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 20.0,
"max": 30.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:diamond_pickaxe",
"weight": 7,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 18.0,
"max": 30.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:arrow",
"weight": 16,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 24.0,
"max": 48.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:bluestone",
"weight": 14,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 8.0,
"max": 20.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:redstone",
"weight": 14,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 8.0,
"max": 20.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:diamond",
"weight": 8,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 3.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:golden_apple",
"weight": 10
},
{
"type": "minecraft:item",
"name": "minecraft:book",
"weight": 10,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 20.0,
"max": 30.0
},
"options": "#minecraft:on_random_loot"
}
]
}
],
"rolls": {
"type": "minecraft:uniform",
"min": 5.0,
"max": 8.0
}
},
{
"entries": [
{
"type": "minecraft:empty",
"weight": 64
},
{
"type": "minecraft:item",
"name": "antarchy:uranium_nugget",
"weight": 7,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 3.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:titanium_nugget",
"weight": 7,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 3.0
}
}
]
}
],
"rolls": 1.0
}
],
"random_sequence": "antarchy:spawners/basilisk_lair/hard"
}
@@ -0,0 +1,187 @@
{
"type": "minecraft:chest",
"pools": [
{
"entries": [
{
"type": "minecraft:item",
"name": "minecraft:arrow",
"weight": 18,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 14.0,
"max": 36.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:bow",
"weight": 12,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 10.0,
"max": 22.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:iron_sword",
"weight": 10,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 10.0,
"max": 22.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:iron_pickaxe",
"weight": 10,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 8.0,
"max": 20.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:bluestone",
"weight": 16,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 5.0,
"max": 14.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:redstone",
"weight": 16,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 5.0,
"max": 14.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:dispenser",
"weight": 7
},
{
"type": "minecraft:item",
"name": "minecraft:tripwire_hook",
"weight": 8,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 4.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:ouranwood_acorn",
"weight": 8,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 4.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:golden_apple",
"weight": 5
}
],
"rolls": {
"type": "minecraft:uniform",
"min": 4.0,
"max": 7.0
}
},
{
"entries": [
{
"type": "minecraft:empty",
"weight": 72
},
{
"type": "minecraft:item",
"name": "antarchy:uranium_nugget",
"weight": 6,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 2.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:titanium_nugget",
"weight": 6,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 2.0
}
}
]
}
],
"rolls": 1.0
}
],
"random_sequence": "antarchy:spawners/basilisk_lair/medium"
}
@@ -0,0 +1,185 @@
{
"type": "minecraft:chest",
"pools": [
{
"entries": [
{
"type": "minecraft:item",
"name": "minecraft:diamond",
"weight": 10,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 4.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:emerald",
"weight": 14,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 7.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:gold_ingot",
"weight": 16,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 4.0,
"max": 12.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:amethyst_shard",
"weight": 12,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 5.0,
"max": 14.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:blood_crystal_shard",
"weight": 10,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 4.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:tigers_eye",
"weight": 10,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 4.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:book",
"weight": 10,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 20.0,
"max": 30.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:experience_bottle",
"weight": 10,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 4.0,
"max": 10.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:golden_apple",
"weight": 10
},
{
"type": "minecraft:item",
"name": "antarchy:fallen_king_crown",
"weight": 3
}
],
"rolls": {
"type": "minecraft:uniform",
"min": 5.0,
"max": 8.0
}
},
{
"entries": [
{
"type": "minecraft:empty",
"weight": 62
},
{
"type": "minecraft:item",
"name": "antarchy:uranium_nugget",
"weight": 7,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 3.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:titanium_nugget",
"weight": 7,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 3.0
}
}
]
}
],
"rolls": 1.0
}
],
"random_sequence": "antarchy:spawners/temple_of_technoblade/hard"
}
@@ -0,0 +1,195 @@
{
"type": "minecraft:chest",
"pools": [
{
"entries": [
{
"type": "minecraft:item",
"name": "minecraft:baked_potato",
"weight": 18,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 4.0,
"max": 12.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:cooked_porkchop",
"weight": 12,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 8.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:golden_carrot",
"weight": 10,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 4.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:gold_ingot",
"weight": 14,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 7.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:emerald",
"weight": 12,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 4.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:amethyst_shard",
"weight": 12,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 3.0,
"max": 9.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:tigers_eye",
"weight": 8,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 3.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:experience_bottle",
"weight": 8,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 6.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:book",
"weight": 8,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 12.0,
"max": 24.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:golden_apple",
"weight": 6
}
],
"rolls": {
"type": "minecraft:uniform",
"min": 4.0,
"max": 7.0
}
},
{
"entries": [
{
"type": "minecraft:empty",
"weight": 70
},
{
"type": "minecraft:item",
"name": "antarchy:uranium_nugget",
"weight": 6,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 2.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:titanium_nugget",
"weight": 6,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 2.0
}
}
]
}
],
"rolls": 1.0
}
],
"random_sequence": "antarchy:spawners/temple_of_technoblade/medium"
}
@@ -0,0 +1,8 @@
{
"replace": false,
"values": [
"antarchy:ouranwood_forest",
"antarchy:sparse_ouranwood_forest",
"antarchy:fungal_ouranwood_forest"
]
}
@@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"antarchy:elythia_meadow"
]
}
@@ -13,10 +13,9 @@
"type": "minecraft:ash"
}
},
"ambient_sound": "antarchy:thoraxis_dream_dunes_ambient",
"additions_sound": {
"sound": "antarchy:thoraxis_dream_dunes_additions",
"tick_chance": 0.002100000
"sound": "antarchy:thoraxis_dream_dunes_biome_additions",
"tick_chance": 0.0005
},
"mood_sound": {
"sound": "antarchy:thoraxis_dream_dunes_mood",
@@ -16,7 +16,10 @@
"type": "minecraft:spore_blossom_air"
}
},
"ambient_sound": "antarchy:ambient.elythia.ouranwood_forest",
"additions_sound": {
"sound": "antarchy:ambient.elythia.ouranwood_forest",
"tick_chance": 0.0005
},
"mood_sound": {
"sound": "minecraft:ambient.crimson_forest.mood",
"tick_delay": 6000,
@@ -13,10 +13,9 @@
"type": "minecraft:crimson_spore"
}
},
"ambient_sound": "antarchy:thoraxis_lucid_pools_ambient",
"additions_sound": {
"sound": "antarchy:thoraxis_lucid_pools_additions",
"tick_chance": 0.000600000
"sound": "antarchy:thoraxis_lucid_pools_biome_additions",
"tick_chance": 0.0005
},
"mood_sound": {
"sound": "antarchy:thoraxis_lucid_pools_mood",
@@ -38,7 +37,7 @@
"spawn_costs": {
"antarchy:lucid": {
"energy_budget": 0.10,
"charge": 15.0
"charge": 17.0
}
},
"features": [
@@ -77,7 +76,7 @@
"monster": [
{
"type": "antarchy:lucid",
"weight": 7,
"weight": 3,
"minCount": 1,
"maxCount": 1
}
@@ -13,10 +13,9 @@
"type": "minecraft:crimson_spore"
}
},
"ambient_sound": "antarchy:thoraxis_nightmare_wastes_ambient",
"additions_sound": {
"sound": "antarchy:thoraxis_nightmare_wastes_additions",
"tick_chance": 0.007777778
"sound": "antarchy:thoraxis_nightmare_wastes_biome_additions",
"tick_chance": 0.0005
},
"mood_sound": {
"sound": "antarchy:thoraxis_nightmare_wastes_mood",
@@ -16,7 +16,10 @@
"type": "minecraft:spore_blossom_air"
}
},
"ambient_sound": "antarchy:ambient.elythia.ouranwood_forest",
"additions_sound": {
"sound": "antarchy:ambient.elythia.ouranwood_forest",
"tick_chance": 0.0005
},
"mood_sound": {
"sound": "minecraft:ambient.crimson_forest.mood",
"tick_delay": 6000,
@@ -16,7 +16,10 @@
"type": "minecraft:spore_blossom_air"
}
},
"ambient_sound": "antarchy:ambient.elythia.ouranwood_forest",
"additions_sound": {
"sound": "antarchy:ambient.elythia.ouranwood_forest",
"tick_chance": 0.0005
},
"mood_sound": {
"sound": "minecraft:ambient.crimson_forest.mood",
"tick_delay": 6000,
@@ -13,10 +13,9 @@
"type": "minecraft:ash"
}
},
"ambient_sound": "antarchy:thoraxis_nightmare_wastes_ambient",
"additions_sound": {
"sound": "antarchy:thoraxis_nightmare_wastes_additions",
"tick_chance": 0.0075
"sound": "antarchy:thoraxis_nightmare_wastes_biome_additions",
"tick_chance": 0.0005
},
"mood_sound": {
"sound": "antarchy:thoraxis_nightmare_wastes_mood",
@@ -0,0 +1,10 @@
{
"processors": [
{
"processor_type": "integrated_api:tick_blocks_processor",
"blocks_to_tick": [
"minecraft:dispenser"
]
}
]
}
@@ -0,0 +1,10 @@
{
"processors": [
{
"processor_type": "integrated_api:tick_blocks_processor",
"blocks_to_tick": [
"minecraft:dispenser"
]
}
]
}
@@ -0,0 +1,22 @@
{
"type": "integrated_api:generic_structure",
"start_pool": "antarchy:basilisk_lair/basilisk_lair",
"size": 3,
"terrain_height_radius_check": 3,
"allowed_terrain_height_range": 10,
"valid_biome_radius_check": 1,
"biomes": "#antarchy:has_structure/basilisk_lair_biomes",
"step": "surface_structures",
"enhanced_terrain_adaptation": {
"type": "integrated_api:none"
},
"project_start_to_heightmap": "WORLD_SURFACE_WG",
"start_height": {
"type": "minecraft:constant",
"value": {
"absolute": 0
}
},
"spawn_overrides": {},
"liquid_settings": "ignore_waterlogging"
}
@@ -0,0 +1,22 @@
{
"type": "integrated_api:generic_structure",
"start_pool": "antarchy:temple_of_technoblade/temple_of_technoblade1",
"size": 4,
"terrain_height_radius_check": 3,
"allowed_terrain_height_range": 10,
"valid_biome_radius_check": 1,
"biomes": "#antarchy:has_structure/temple_of_technoblade_biomes",
"step": "surface_structures",
"enhanced_terrain_adaptation": {
"type": "integrated_api:none"
},
"project_start_to_heightmap": "WORLD_SURFACE_WG",
"start_height": {
"type": "minecraft:constant",
"value": {
"absolute": 0
}
},
"spawn_overrides": {},
"liquid_settings": "ignore_waterlogging"
}
@@ -2,31 +2,39 @@
"structures": [
{
"structure": "antarchy:trayaurus_lab",
"weight": 1
"weight": 2
},
{
"structure": "antarchy:fallen_kingdom_castle",
"weight": 2
},
{
"structure": "antarchy:ruined_prison",
"weight": 2
},
{
"structure": "antarchy:sign",
"weight": 2
},
{
"structure": "antarchy:stampys_house",
"weight": 2
},
{
"structure": "antarchy:ruined_arena",
"weight": 3
},
{
"structure": "antarchy:ruined_prison",
"weight": 3
},
{
"structure": "antarchy:sign",
"weight": 4
},
{
"structure": "antarchy:stampys_house",
"weight": 4
},
{
"structure": "antarchy:temple_of_technoblade",
"weight": 1
},
{
"structure": "antarchy:basilisk_lair",
"weight": 4
},
{
"structure": "antarchy:ruined_arena",
"weight": 4
},
{
"structure": "antarchy:toreterror_arena",
"weight": 5
"weight": 6
}
],
"placement": {
@@ -0,0 +1,22 @@
{
"name": "antarchy:basilisk_lair/basilisk_lair",
"fallback": "minecraft:empty",
"elements": [
{
"weight": 1,
"element": {
"location": "antarchy:basilisk_lair/basilisk_lair",
"processors": "antarchy:basilisk_lair_processor",
"projection": "rigid",
"enhanced_terrain_adaptation": {
"type": "integrated_api:custom",
"carves": true,
"beards": true,
"kernel_size": 35,
"kernel_distance": 35
},
"element_type": "integrated_api:integrated_api_single_pool_element"
}
}
]
}
@@ -0,0 +1,22 @@
{
"name": "antarchy:temple_of_technoblade/temple_of_technoblade1",
"fallback": "minecraft:empty",
"elements": [
{
"weight": 1,
"element": {
"location": "antarchy:temple_of_technoblade/temple_of_technoblade1",
"processors": "antarchy:temple_of_technoblade_processor",
"projection": "rigid",
"enhanced_terrain_adaptation": {
"type": "integrated_api:custom",
"carves": true,
"beards": true,
"kernel_size": 35,
"kernel_distance": 35
},
"element_type": "integrated_api:integrated_api_single_pool_element"
}
}
]
}
@@ -0,0 +1,22 @@
{
"name": "antarchy:temple_of_technoblade/temple_of_technoblade2",
"fallback": "minecraft:empty",
"elements": [
{
"weight": 1,
"element": {
"location": "antarchy:temple_of_technoblade/temple_of_technoblade2",
"processors": "antarchy:temple_of_technoblade_processor",
"projection": "rigid",
"enhanced_terrain_adaptation": {
"type": "integrated_api:custom",
"carves": true,
"beards": true,
"kernel_size": 35,
"kernel_distance": 35
},
"element_type": "integrated_api:integrated_api_single_pool_element"
}
}
]
}
@@ -0,0 +1,22 @@
{
"name": "antarchy:temple_of_technoblade/temple_of_technoblade3",
"fallback": "minecraft:empty",
"elements": [
{
"weight": 1,
"element": {
"location": "antarchy:temple_of_technoblade/temple_of_technoblade3",
"processors": "antarchy:temple_of_technoblade_processor",
"projection": "rigid",
"enhanced_terrain_adaptation": {
"type": "integrated_api:custom",
"carves": true,
"beards": true,
"kernel_size": 35,
"kernel_distance": 35
},
"element_type": "integrated_api:integrated_api_single_pool_element"
}
}
]
}
@@ -309,6 +309,7 @@ public final class AntarchyFabricContent {
AntarchyObjects.setLumenFroglight(() -> AntarchyFabricBlocks.LUMEN_FROGLIGHT.get());
AntarchyObjects.setPeachLeavesParticle(() -> AntarchyFabricMisc.PEACH_LEAVES_PARTICLE.get());
AntarchyObjects.setLotusPollen(() -> AntarchyFabricMisc.LOTUS_POLLEN.get());
AntarchyObjects.setNightmareFireFlame(() -> AntarchyFabricMisc.NIGHTMARE_FIRE_FLAME.get());
AntarchyObjects.setLucidBoltImpactSmall(() -> AntarchyFabricMisc.LUCID_BOLT_IMPACT_SMALL.get());
AntarchyObjects.setLucidBoltImpactLarge(() -> AntarchyFabricMisc.LUCID_BOLT_IMPACT_LARGE.get());
AntarchyObjects.setDorrieInventoryMenu(AntarchyFabricMisc.DORRIE_INVENTORY_MENU);
@@ -250,7 +250,9 @@ public final class AntarchyFabricEvents {
private static void tickDuctTapePlayers(ServerLevel level) {
for (Player player : level.players()) {
DuctTapeBlock.tickStuckEntity(player);
if (DuctTapeBlock.shouldTickStuckEntity(player)) {
DuctTapeBlock.tickStuckEntity(player);
}
}
}
@@ -274,6 +274,7 @@ public final class AntarchyFabricClientBootstrap {
private static void registerParticles() {
ParticleFactoryRegistry registry = ParticleFactoryRegistry.getInstance();
registry.register(AntarchyFabricMisc.DREAM_FIRE_FLAME.get(), DreamFlameParticle.Provider::new);
registry.register(AntarchyFabricMisc.NIGHTMARE_FIRE_FLAME.get(), DreamFlameParticle.Provider::new);
registry.register(AntarchyFabricMisc.STINKY_GAS.get(), HypnoticGasParticle.Provider::new);
registry.register(AntarchyFabricMisc.STINKY_FLY.get(), FireflyParticle.Provider::new);
registry.register(AntarchyFabricMisc.PEACH_LEAVES_PARTICLE.get(), PeachLeavesParticle.Provider::new);
@@ -275,6 +275,8 @@ public final class AntarchyFabricMisc {
public static final DeferredHolder<ParticleType<?>, SimpleParticleType> DREAM_FIRE_FLAME = PARTICLE_TYPES.register("dream_fire_flame",
() -> simpleParticleType());
public static final DeferredHolder<ParticleType<?>, SimpleParticleType> NIGHTMARE_FIRE_FLAME = PARTICLE_TYPES.register("nightmare_fire_flame",
() -> simpleParticleType());
public static final DeferredHolder<ParticleType<?>, SimpleParticleType> STINKY_GAS = PARTICLE_TYPES.register("stinky_gas",
@@ -76,6 +76,9 @@ public final class AntarchyFabricSounds {
public static final DeferredHolder<SoundEvent, SoundEvent> ELYTHIA_FIREFLY_AMBIENT = registerSoundEvent("ambient.elythia.firefly");
public static final DeferredHolder<SoundEvent, SoundEvent> ELYTHIA_OURANWOOD_FOREST_AMBIENT = registerSoundEvent("ambient.elythia.ouranwood_forest");
public static final DeferredHolder<SoundEvent, SoundEvent> MISSILE_SQUID_AMBIENT = registerSoundEvent("missile_squid_ambient");
@@ -136,6 +139,9 @@ public final class AntarchyFabricSounds {
public static final DeferredHolder<SoundEvent, SoundEvent> THORAXIS_NIGHTMARE_WASTES_ADDITIONS = registerSoundEvent("thoraxis_nightmare_wastes_additions");
public static final DeferredHolder<SoundEvent, SoundEvent> THORAXIS_NIGHTMARE_WASTES_BIOME_ADDITIONS = registerSoundEvent("thoraxis_nightmare_wastes_biome_additions");
public static final DeferredHolder<SoundEvent, SoundEvent> THORAXIS_NIGHTMARE_WASTES_MOOD = registerSoundEvent("thoraxis_nightmare_wastes_mood");
@@ -145,6 +151,9 @@ public final class AntarchyFabricSounds {
public static final DeferredHolder<SoundEvent, SoundEvent> THORAXIS_DREAM_DUNES_ADDITIONS = registerSoundEvent("thoraxis_dream_dunes_additions");
public static final DeferredHolder<SoundEvent, SoundEvent> THORAXIS_DREAM_DUNES_BIOME_ADDITIONS = registerSoundEvent("thoraxis_dream_dunes_biome_additions");
public static final DeferredHolder<SoundEvent, SoundEvent> THORAXIS_DREAM_DUNES_MOOD = registerSoundEvent("thoraxis_dream_dunes_mood");
@@ -154,6 +163,9 @@ public final class AntarchyFabricSounds {
public static final DeferredHolder<SoundEvent, SoundEvent> THORAXIS_LUCID_POOLS_ADDITIONS = registerSoundEvent("thoraxis_lucid_pools_additions");
public static final DeferredHolder<SoundEvent, SoundEvent> THORAXIS_LUCID_POOLS_BIOME_ADDITIONS = registerSoundEvent("thoraxis_lucid_pools_biome_additions");
public static final DeferredHolder<SoundEvent, SoundEvent> THORAXIS_LUCID_POOLS_MOOD = registerSoundEvent("thoraxis_lucid_pools_mood");
@@ -130,9 +130,13 @@ public final class AntarchyFabricContent {
AntarchySoundEvents.bind(
AntarchyFabricSounds.SQUIDZOOKA_FIRE,
AntarchyFabricSounds.SHRINK_RAY_SOUND,
AntarchyFabricSounds.GROWTH_RAY_SOUND,
AntarchyFabricSounds.SIZE_RAY_CHARGE,
AntarchyFabricSounds.SHRINK_RAY_CHARGE,
AntarchyFabricSounds.SHRINK_RAY_LOOP,
AntarchyFabricSounds.GROWTH_RAY_CHARGE,
AntarchyFabricSounds.GROWTH_RAY_LOOP,
AntarchyFabricSounds.SIZE_RAY_WEAKSHOT,
AntarchyFabricSounds.SIZE_RAY_MEDIUMSHOT,
AntarchyFabricSounds.SIZE_RAY_CRITSHOT,
AntarchyFabricSounds.ANT_AMBIENT,
AntarchyFabricSounds.ANT_IDLE,
AntarchyFabricSounds.ANT_HURT,
@@ -323,6 +327,7 @@ public final class AntarchyFabricContent {
AntarchyObjects.setLumenFroglight(() -> AntarchyFabricBlocks.LUMEN_FROGLIGHT.get());
AntarchyObjects.setPeachLeavesParticle(() -> AntarchyFabricMisc.PEACH_LEAVES_PARTICLE.get());
AntarchyObjects.setLotusPollen(() -> AntarchyFabricMisc.LOTUS_POLLEN.get());
AntarchyObjects.setNightmareFireFlame(() -> AntarchyFabricMisc.NIGHTMARE_FIRE_FLAME.get());
AntarchyObjects.setLucidBoltImpactSmall(() -> AntarchyFabricMisc.LUCID_BOLT_IMPACT_SMALL.get());
AntarchyObjects.setLucidBoltImpactLarge(() -> AntarchyFabricMisc.LUCID_BOLT_IMPACT_LARGE.get());
AntarchyObjects.setDorrieInventoryMenu(AntarchyFabricMisc.DORRIE_INVENTORY_MENU);
@@ -251,7 +251,9 @@ public final class AntarchyFabricEvents {
private static void tickDuctTapePlayers(ServerLevel level) {
for (Player player : level.players()) {
DuctTapeBlock.tickStuckEntity(player);
if (DuctTapeBlock.shouldTickStuckEntity(player)) {
DuctTapeBlock.tickStuckEntity(player);
}
}
}
@@ -8,6 +8,7 @@ import com.craisinlord.antarchy.Antarchy;
import com.craisinlord.antarchy.content.client.CameraShakeClientState;
import com.craisinlord.antarchy.content.client.HerculesBeetleImpactShakeClientState;
import com.craisinlord.antarchy.content.client.HordeClientState;
import com.craisinlord.antarchy.content.client.SizeRaySoundHandler;
import com.craisinlord.antarchy.content.client.TigerEyeClientHooks;
import com.craisinlord.antarchy.content.client.renderer.*;
import com.craisinlord.antarchy.content.client.particle.*;
@@ -274,6 +275,7 @@ public final class AntarchyFabricClientBootstrap {
private static void registerParticles() {
ParticleFactoryRegistry registry = ParticleFactoryRegistry.getInstance();
registry.register(AntarchyFabricMisc.DREAM_FIRE_FLAME.get(), DreamFlameParticle.Provider::new);
registry.register(AntarchyFabricMisc.NIGHTMARE_FIRE_FLAME.get(), DreamFlameParticle.Provider::new);
registry.register(AntarchyFabricMisc.STINKY_GAS.get(), HypnoticGasParticle.Provider::new);
registry.register(AntarchyFabricMisc.STINKY_FLY.get(), FireflyParticle.Provider::new);
registry.register(AntarchyFabricMisc.PEACH_LEAVES_PARTICLE.get(), PeachLeavesParticle.Provider::new);
@@ -486,6 +488,7 @@ public final class AntarchyFabricClientBootstrap {
ScorpionWhipTetherRenderHandler.tick();
DorrieJumpClientHandler.tick();
HerculesBeetleClientHandler.tick();
SizeRaySoundHandler.tick(client);
});
BigBerthaClientHandler.register();
@@ -21,9 +21,11 @@ import java.util.UUID;
public final class LucidSoundHandler {
private static final double START_SCAN_RADIUS = 96.0D;
private static final int DISCOVERY_SCAN_INTERVAL_TICKS = 10;
private static final int ANIM_ATTACK = 2;
private static final int ANIM_DEATH = 3;
private static final Map<UUID, LucidLoopSet> ACTIVE_LOOPS = new HashMap<>();
private static long nextDiscoveryScanTick;
private LucidSoundHandler() {
}
@@ -42,10 +44,24 @@ public final class LucidSoundHandler {
}
pruneStaleLoops(client);
refreshNearbyLucids(client);
refreshActiveLoops(client);
long gameTime = client.level.getGameTime();
if (gameTime >= nextDiscoveryScanTick) {
nextDiscoveryScanTick = gameTime + DISCOVERY_SCAN_INTERVAL_TICKS;
refreshNearbyLucids(client);
}
});
}
private static void refreshActiveLoops(Minecraft mc) {
for (LucidLoopSet set : ACTIVE_LOOPS.values()) {
if (set.isValid()) {
set.refresh(mc, set.entity);
}
}
}
private static void refreshNearbyLucids(Minecraft mc) {
List<LucidEntity> lucids = mc.level.getEntitiesOfClass(
LucidEntity.class,
@@ -85,6 +101,7 @@ public final class LucidSoundHandler {
set.stop(mc);
}
ACTIVE_LOOPS.clear();
nextDiscoveryScanTick = 0L;
}
private static final class LucidLoopSet {
@@ -288,6 +288,8 @@ public final class AntarchyFabricMisc {
public static final DeferredHolder<ParticleType<?>, SimpleParticleType> DREAM_FIRE_FLAME = PARTICLE_TYPES.register("dream_fire_flame",
() -> simpleParticleType());
public static final DeferredHolder<ParticleType<?>, SimpleParticleType> NIGHTMARE_FIRE_FLAME = PARTICLE_TYPES.register("nightmare_fire_flame",
() -> simpleParticleType());
public static final DeferredHolder<ParticleType<?>, SimpleParticleType> STINKY_GAS = PARTICLE_TYPES.register("stinky_gas",
@@ -13,13 +13,25 @@ public final class AntarchyFabricSounds {
public static final DeferredHolder<SoundEvent, SoundEvent> SQUIDZOOKA_FIRE = registerSoundEvent("squidzooka_fire");
public static final DeferredHolder<SoundEvent, SoundEvent> SHRINK_RAY_SOUND = registerSoundEvent("shrink_ray");
public static final DeferredHolder<SoundEvent, SoundEvent> SHRINK_RAY_CHARGE = registerSoundEvent("shrink_ray_charge");
public static final DeferredHolder<SoundEvent, SoundEvent> GROWTH_RAY_SOUND = registerSoundEvent("growth_ray");
public static final DeferredHolder<SoundEvent, SoundEvent> SHRINK_RAY_LOOP = registerSoundEvent("shrink_ray_loop");
public static final DeferredHolder<SoundEvent, SoundEvent> SIZE_RAY_CHARGE = registerSoundEvent("size_ray_charge");
public static final DeferredHolder<SoundEvent, SoundEvent> GROWTH_RAY_CHARGE = registerSoundEvent("growth_ray_charge");
public static final DeferredHolder<SoundEvent, SoundEvent> GROWTH_RAY_LOOP = registerSoundEvent("growth_ray_loop");
public static final DeferredHolder<SoundEvent, SoundEvent> SIZE_RAY_WEAKSHOT = registerSoundEvent("size_ray_weakshot");
public static final DeferredHolder<SoundEvent, SoundEvent> SIZE_RAY_MEDIUMSHOT = registerSoundEvent("size_ray_mediumshot");
public static final DeferredHolder<SoundEvent, SoundEvent> SIZE_RAY_CRITSHOT = registerSoundEvent("size_ray_critshot");
public static final DeferredHolder<SoundEvent, SoundEvent> ANT_AMBIENT = registerSoundEvent("ant_ambient");
@@ -139,6 +151,9 @@ public final class AntarchyFabricSounds {
public static final DeferredHolder<SoundEvent, SoundEvent> THORAXIS_NIGHTMARE_WASTES_ADDITIONS = registerSoundEvent("thoraxis_nightmare_wastes_additions");
public static final DeferredHolder<SoundEvent, SoundEvent> THORAXIS_NIGHTMARE_WASTES_BIOME_ADDITIONS = registerSoundEvent("thoraxis_nightmare_wastes_biome_additions");
public static final DeferredHolder<SoundEvent, SoundEvent> THORAXIS_NIGHTMARE_WASTES_MOOD = registerSoundEvent("thoraxis_nightmare_wastes_mood");
@@ -148,6 +163,9 @@ public final class AntarchyFabricSounds {
public static final DeferredHolder<SoundEvent, SoundEvent> THORAXIS_DREAM_DUNES_ADDITIONS = registerSoundEvent("thoraxis_dream_dunes_additions");
public static final DeferredHolder<SoundEvent, SoundEvent> THORAXIS_DREAM_DUNES_BIOME_ADDITIONS = registerSoundEvent("thoraxis_dream_dunes_biome_additions");
public static final DeferredHolder<SoundEvent, SoundEvent> THORAXIS_DREAM_DUNES_MOOD = registerSoundEvent("thoraxis_dream_dunes_mood");
@@ -157,6 +175,9 @@ public final class AntarchyFabricSounds {
public static final DeferredHolder<SoundEvent, SoundEvent> THORAXIS_LUCID_POOLS_ADDITIONS = registerSoundEvent("thoraxis_lucid_pools_additions");
public static final DeferredHolder<SoundEvent, SoundEvent> THORAXIS_LUCID_POOLS_BIOME_ADDITIONS = registerSoundEvent("thoraxis_lucid_pools_biome_additions");
public static final DeferredHolder<SoundEvent, SoundEvent> THORAXIS_LUCID_POOLS_MOOD = registerSoundEvent("thoraxis_lucid_pools_mood");
@@ -377,6 +377,7 @@ public class AntarchyForge {
AntarchyObjects.setLumenFroglight(() -> AntarchyForgeBlocks.LUMEN_FROGLIGHT.get());
AntarchyObjects.setPeachLeavesParticle(() -> AntarchyForgeMisc.PEACH_LEAVES_PARTICLE.get());
AntarchyObjects.setLotusPollen(() -> AntarchyForgeMisc.LOTUS_POLLEN.get());
AntarchyObjects.setNightmareFireFlame(() -> AntarchyForgeMisc.NIGHTMARE_FIRE_FLAME.get());
AntarchyObjects.setLucidBoltImpactSmall(() -> AntarchyForgeMisc.LUCID_BOLT_IMPACT_SMALL.get());
AntarchyObjects.setLucidBoltImpactLarge(() -> AntarchyForgeMisc.LUCID_BOLT_IMPACT_LARGE.get());
AntarchyObjects.setDorrieInventoryMenu(AntarchyForgeMisc.DORRIE_INVENTORY_MENU);
@@ -279,6 +279,7 @@ public final class AntarchyForgeClient {
@SubscribeEvent
public static void registerParticleProviders(RegisterParticleProvidersEvent event) {
event.registerSpriteSet(AntarchyForgeMisc.DREAM_FIRE_FLAME.get(), DreamFlameParticle.Provider::new);
event.registerSpriteSet(AntarchyForgeMisc.NIGHTMARE_FIRE_FLAME.get(), DreamFlameParticle.Provider::new);
event.registerSpriteSet(AntarchyForgeMisc.STINKY_GAS.get(), HypnoticGasParticle.Provider::new);
event.registerSpriteSet(AntarchyForgeMisc.STINKY_FLY.get(), FireflyParticle.Provider::new);
event.registerSpriteSet(AntarchyForgeMisc.PEACH_LEAVES_PARTICLE.get(), PeachLeavesParticle.Provider::new);
@@ -386,7 +386,9 @@ public final class AntarchyForgeEvents {
}
static void tickDuctTapeStickiness(LivingEvent.LivingTickEvent event) {
DuctTapeBlock.tickStuckEntity(event.getEntity());
if (DuctTapeBlock.shouldTickStuckEntity(event.getEntity())) {
DuctTapeBlock.tickStuckEntity(event.getEntity());
}
}
static void handleDreadDeath(LivingDeathEvent event) {
@@ -828,13 +830,6 @@ public final class AntarchyForgeEvents {
}
}
private static boolean isWearingFullNightmareArmor(Player player) {
for (ItemStack stack : player.getArmorSlots()) {
if (!(stack.getItem() instanceof NightmareArmorItem)) return false;
}
return true;
}
static void handleAntiwaterDamage(LivingHurtEvent event) {
if (!event.getSource().is(DamageTypes.FALL)) {
return;
@@ -1207,13 +1202,6 @@ public final class AntarchyForgeEvents {
return;
}
if (event.getEntity() instanceof Player player && isWearingFullNightmareArmor(player)
&& (event.getEffectInstance().getEffect() == net.minecraft.world.effect.MobEffects.WITHER
|| event.getEffectInstance().getEffect() == AntarchyForgeMisc.DREAD.get())) {
event.setResult(net.minecraftforge.eventbus.api.Event.Result.DENY);
return;
}
if (event.getEntity().getType().is(AntarchyTags.Entities.INVERTED_IMMUNE)
&& event.getEffectInstance().getEffect() == AntarchyForgeMisc.INVERTED.get()) {
event.setResult(net.minecraftforge.eventbus.api.Event.Result.DENY);
@@ -156,6 +156,8 @@ public final class AntarchyForgeMisc {
// Particle types
public static final RegistryObject<SimpleParticleType> DREAM_FIRE_FLAME = PARTICLE_TYPES.register("dream_fire_flame",
AntarchyForgeMisc::simpleParticleType);
public static final RegistryObject<SimpleParticleType> NIGHTMARE_FIRE_FLAME = PARTICLE_TYPES.register("nightmare_fire_flame",
AntarchyForgeMisc::simpleParticleType);
public static final RegistryObject<SimpleParticleType> STINKY_GAS = PARTICLE_TYPES.register("stinky_gas",
AntarchyForgeMisc::simpleParticleType);
public static final RegistryObject<SimpleParticleType> STINKY_FLY = PARTICLE_TYPES.register("stinky_fly",
@@ -32,6 +32,7 @@ public final class AntarchyForgeSounds {
public static final RegistryObject<SoundEvent> BRUTALFLY_IDLE = registerSoundEvent("brutalfly_idle");
public static final RegistryObject<SoundEvent> BRUTALFLY_DEATH = registerSoundEvent("brutalfly_death");
public static final RegistryObject<SoundEvent> ELYTHIA_FIREFLY_AMBIENT = registerSoundEvent("ambient.elythia.firefly");
public static final RegistryObject<SoundEvent> ELYTHIA_OURANWOOD_FOREST_AMBIENT = registerSoundEvent("ambient.elythia.ouranwood_forest");
public static final RegistryObject<SoundEvent> MISSILE_SQUID_AMBIENT = registerSoundEvent("missile_squid_ambient");
public static final RegistryObject<SoundEvent> MISSILE_SQUID_HURT = registerSoundEvent("missile_squid_hurt");
public static final RegistryObject<SoundEvent> MISSILE_SQUID_DEATH = registerSoundEvent("missile_squid_death");
@@ -52,12 +53,15 @@ public final class AntarchyForgeSounds {
public static final RegistryObject<SoundEvent> BASILISK_DEATH = registerSoundEvent("basilisk_death");
public static final RegistryObject<SoundEvent> THORAXIS_NIGHTMARE_WASTES_AMBIENT = registerSoundEvent("thoraxis_nightmare_wastes_ambient");
public static final RegistryObject<SoundEvent> THORAXIS_NIGHTMARE_WASTES_ADDITIONS = registerSoundEvent("thoraxis_nightmare_wastes_additions");
public static final RegistryObject<SoundEvent> THORAXIS_NIGHTMARE_WASTES_BIOME_ADDITIONS = registerSoundEvent("thoraxis_nightmare_wastes_biome_additions");
public static final RegistryObject<SoundEvent> THORAXIS_NIGHTMARE_WASTES_MOOD = registerSoundEvent("thoraxis_nightmare_wastes_mood");
public static final RegistryObject<SoundEvent> THORAXIS_DREAM_DUNES_AMBIENT = registerSoundEvent("thoraxis_dream_dunes_ambient");
public static final RegistryObject<SoundEvent> THORAXIS_DREAM_DUNES_ADDITIONS = registerSoundEvent("thoraxis_dream_dunes_additions");
public static final RegistryObject<SoundEvent> THORAXIS_DREAM_DUNES_BIOME_ADDITIONS = registerSoundEvent("thoraxis_dream_dunes_biome_additions");
public static final RegistryObject<SoundEvent> THORAXIS_DREAM_DUNES_MOOD = registerSoundEvent("thoraxis_dream_dunes_mood");
public static final RegistryObject<SoundEvent> THORAXIS_LUCID_POOLS_AMBIENT = registerSoundEvent("thoraxis_lucid_pools_ambient");
public static final RegistryObject<SoundEvent> THORAXIS_LUCID_POOLS_ADDITIONS = registerSoundEvent("thoraxis_lucid_pools_additions");
public static final RegistryObject<SoundEvent> THORAXIS_LUCID_POOLS_BIOME_ADDITIONS = registerSoundEvent("thoraxis_lucid_pools_biome_additions");
public static final RegistryObject<SoundEvent> THORAXIS_LUCID_POOLS_MOOD = registerSoundEvent("thoraxis_lucid_pools_mood");
public static final RegistryObject<SoundEvent> LUCID_AMBIENT = registerSoundEvent("lucid_ambient");
public static final RegistryObject<SoundEvent> LUCID_FLYING = registerSoundEvent("lucid_flying");
+1 -1
View File
@@ -6,7 +6,7 @@ org.gradle.configureondemand=true
minecraft_version_1_21_1=1.21.1
modid=antarchy
mod_id=antarchy
mod_version=1.1.0
mod_version=1.1.1
maven_group=com.craisinlord
mixin_version=0.15.4+mixin.0.8.7
Loaded 100 of 107 files, more files were not shown because too many files have changed in this diff. Show more