updated spirit apple texture

fixed tigers eye shrine broken
credit russian lang
fixed queen music handler
fixed permanent portals not placing corners and not finding exisitng portals
fixed keybind conflict sprint conflicts
added back cloud sea
This commit is contained in:
craisinlord committed 2026-09-21 18:47:14 -05:00
1 parent 93e2adbe12
commit 6e12612559
30 files changed
+458 -450

No files matched your search

+6
View File
@@ -1,3 +1,9 @@
https://www.curseforge.com/minecraft/mc-mods/antarchy
ANTS! ANTS! ANTS!
Antarchy requires Architectury API, AntOS, Integrated API, GeckoLib, and Sizeable Folia.
## Credits
Russian localization: suheckii
@@ -285,6 +285,10 @@ public final class AntarchySettings {
private static int queenBlackHoleActiveTicks = 120;
private static double queenBlackHolePullStrength = 0.16D;
private static int queenBlackHoleBlockSuctionCap = 160;
private static double axeBlackHoleRadius = 28.0D;
private static int axeBlackHoleActiveTicks = 120;
private static double axeBlackHolePullStrength = 0.16D;
private static int axeBlackHoleBlockSuctionCap = 160;
private static double kingFireballDamage = 48.0D;
private static double kingFireballRadius = 4.5D;
private static int kingFireballCooldownTicks = 150;
@@ -576,8 +580,8 @@ public final class AntarchySettings {
private static double crawlingBlightAttackDamage = 6.0D;
private static double skulkingFrightHealth = 15.0D;
private static double skulkingFrightAttackDamage = 6.0D;
private static double manticoreHealth = 40.0D;
private static double manticoreAttackDamage = 7.0D;
private static double manticoreHealth = 60.0D;
private static double manticoreAttackDamage = 11.0D;
private static int manticoreStingPoisonTicks = 100;
private static int queenManticoreCap = 15;
private static int queenManticoreSummonCooldownTicks = 800;
@@ -2167,6 +2171,14 @@ public final class AntarchySettings {
public static void setQueenBlackHolePullStrength(double v) { queenBlackHolePullStrength = v; }
public static int queenBlackHoleBlockSuctionCap() { return queenBlackHoleBlockSuctionCap; }
public static void setQueenBlackHoleBlockSuctionCap(int v) { queenBlackHoleBlockSuctionCap = v; }
public static double axeBlackHoleRadius() { return axeBlackHoleRadius; }
public static void setAxeBlackHoleRadius(double v) { axeBlackHoleRadius = v; }
public static int axeBlackHoleActiveTicks() { return axeBlackHoleActiveTicks; }
public static void setAxeBlackHoleActiveTicks(int v) { axeBlackHoleActiveTicks = v; }
public static double axeBlackHolePullStrength() { return axeBlackHolePullStrength; }
public static void setAxeBlackHolePullStrength(double v) { axeBlackHolePullStrength = v; }
public static int axeBlackHoleBlockSuctionCap() { return axeBlackHoleBlockSuctionCap; }
public static void setAxeBlackHoleBlockSuctionCap(int v) { axeBlackHoleBlockSuctionCap = v; }
public static double kingFireballDamage() { return kingFireballDamage; }
public static void setKingFireballDamage(double v) { kingFireballDamage = v; }
public static double kingFireballRadius() { return kingFireballRadius; }
@@ -18,7 +18,6 @@ public final class QueenMusicHandler {
private static final int RESTART_COOLDOWN_TICKS = 100;
private static QueenMusicSound music;
private static int cooldownTicks;
private static boolean wasInEncounter;
private QueenMusicHandler() {
}
@@ -38,21 +37,16 @@ public final class QueenMusicHandler {
QueenEntity queen = minecraft.level.getEntitiesOfClass(
QueenEntity.class,
minecraft.player.getBoundingBox().inflate(STOP_RADIUS),
QueenEntity::shouldPlayQueenMusic
entity -> entity.isQueenMusicActive() || entity.shouldPlayQueenMusic()
).stream()
.min(Comparator.comparingDouble(entity -> entity.distanceToSqr(minecraft.player)))
.orElse(null);
if (queen == null) {
stop(minecraft);
if (wasInEncounter) {
cooldownTicks = Math.max(cooldownTicks, RESTART_COOLDOWN_TICKS);
}
wasInEncounter = false;
return;
}
wasInEncounter = true;
if (music != null && !minecraft.getSoundManager().isActive(music)) {
music = null;
cooldownTicks = Math.max(cooldownTicks, RESTART_COOLDOWN_TICKS);
@@ -82,7 +76,6 @@ public final class QueenMusicHandler {
private static void reset(Minecraft minecraft) {
stop(minecraft);
cooldownTicks = 0;
wasInEncounter = false;
}
private static final class QueenMusicSound extends AbstractTickableSoundInstance {
@@ -650,6 +650,9 @@ public final class CreativeTabContents {
public static boolean populateNeoForgeVanillaTab(ResourceKey<CreativeModeTab> tabKey, HolderLookup.Provider holders,
NeoForgeVanillaTabOutput output) {
if (!ResourceLocation.DEFAULT_NAMESPACE.equals(tabKey.location().getNamespace())) {
return false;
}
String tabPath = tabKey.location().getPath();
boolean matched = false;
for (CatalogEntry entry : CATALOG) {
@@ -59,7 +59,6 @@ import software.bernie.geckolib.util.GeckoLibUtil;
public class ManticoreEntity extends Monster implements GeoEntity {
private static final String SUMMONER_KEY = "QueenSummoner";
private static final String PLAYER_SUMMONER_KEY = "PlayerSummoner";
private static final String PLAYER_SUMMON_LIFETIME_KEY = "PlayerSummonLifetime";
private static final int LOST_SUMMONER_GRACE_TICKS = 200;
private static final int TAKEOFF_COOLDOWN_TICKS = 40;
private static final int STING_COOLDOWN_TICKS = 60;
@@ -81,8 +80,6 @@ public class ManticoreEntity extends Monster implements GeoEntity {
private UUID summonerId;
@Nullable
private UUID playerSummonerId;
private int playerSummonLifetime;
private int playerSummonAge;
private int lostSummonerTicks;
private int takeoffCooldown;
private int stingCooldown;
@@ -102,8 +99,8 @@ public class ManticoreEntity extends Monster implements GeoEntity {
public static AttributeSupplier.Builder createAttributes() {
return Mob.createMobAttributes()
.add(Attributes.MAX_HEALTH, AntarchySettings.manticoreHealth())
.add(Attributes.MOVEMENT_SPEED, 0.45D)
.add(Attributes.FLYING_SPEED, 2.0D)
.add(Attributes.MOVEMENT_SPEED, 0.55D)
.add(Attributes.FLYING_SPEED, 2.6D)
.add(Attributes.ATTACK_DAMAGE, AntarchySettings.manticoreAttackDamage())
.add(Attributes.FOLLOW_RANGE, 28.0D)
.add(Attributes.KNOCKBACK_RESISTANCE, 0.2D);
@@ -161,11 +158,9 @@ public class ManticoreEntity extends Monster implements GeoEntity {
this.setPersistenceRequired();
}
public void markPlayerSummoned(UUID playerId, int lifetimeTicks) {
public void markPlayerSummoned(UUID playerId) {
this.playerSummonerId = playerId;
this.summonerId = null;
this.playerSummonLifetime = lifetimeTicks;
this.playerSummonAge = 0;
this.lostSummonerTicks = 0;
this.setPersistenceRequired();
}
@@ -202,7 +197,7 @@ public class ManticoreEntity extends Monster implements GeoEntity {
@Override
public boolean removeWhenFarAway(double distanceToClosestPlayer) {
return this.summonerId == null && super.removeWhenFarAway(distanceToClosestPlayer);
return this.summonerId == null && this.playerSummonerId == null && super.removeWhenFarAway(distanceToClosestPlayer);
}
@Override
@@ -236,8 +231,9 @@ public class ManticoreEntity extends Monster implements GeoEntity {
}
this.tickQueenSummonCleanup();
this.tickPlayerSummonCleanup();
this.tickPlayerSummon();
this.tickPlayerSummonTarget();
this.tickQueenSummonTarget();
LivingEntity target = this.getTarget();
@@ -252,17 +248,12 @@ public class ManticoreEntity extends Monster implements GeoEntity {
}
}
private void tickPlayerSummon() {
private void tickPlayerSummonTarget() {
if (this.playerSummonerId == null || !(this.level() instanceof ServerLevel serverLevel)) {
return;
}
if (++this.playerSummonAge >= this.playerSummonLifetime) {
this.discard();
return;
}
Entity entity = serverLevel.getEntity(this.playerSummonerId);
if (!(entity instanceof Player player) || !player.isAlive()) {
this.discard();
return;
}
LivingEntity target = player.getLastHurtMob();
@@ -328,6 +319,20 @@ public class ManticoreEntity extends Monster implements GeoEntity {
}
}
private void tickPlayerSummonCleanup() {
if (this.playerSummonerId == null || !(this.level() instanceof ServerLevel serverLevel)) {
return;
}
Entity summoner = serverLevel.getEntity(this.playerSummonerId);
if (summoner instanceof Player player && player.isAlive()) {
this.lostSummonerTicks = 0;
return;
}
if (++this.lostSummonerTicks > LOST_SUMMONER_GRACE_TICKS) {
this.discard();
}
}
private void takeoff() {
this.takeoffCooldown = TAKEOFF_COOLDOWN_TICKS;
this.setDeltaMovement(this.getDeltaMovement().add(0.0D, 0.55D, 0.0D));
@@ -461,7 +466,6 @@ public class ManticoreEntity extends Monster implements GeoEntity {
}
if (this.playerSummonerId != null) {
tag.putUUID(PLAYER_SUMMONER_KEY, this.playerSummonerId);
tag.putInt(PLAYER_SUMMON_LIFETIME_KEY, this.playerSummonLifetime);
}
}
@@ -470,8 +474,6 @@ public class ManticoreEntity extends Monster implements GeoEntity {
super.readAdditionalSaveData(tag);
this.summonerId = tag.hasUUID(SUMMONER_KEY) ? tag.getUUID(SUMMONER_KEY) : null;
this.playerSummonerId = tag.hasUUID(PLAYER_SUMMONER_KEY) ? tag.getUUID(PLAYER_SUMMONER_KEY) : null;
this.playerSummonLifetime = tag.getInt(PLAYER_SUMMON_LIFETIME_KEY);
this.playerSummonAge = 0;
this.lostSummonerTicks = 0;
}
@@ -12,9 +12,6 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.sounds.AbstractTickableSoundInstance;
import net.minecraft.client.sounds.SoundManager;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Holder;
import net.minecraft.core.HolderSet;
@@ -79,8 +76,6 @@ public class DimensionalTearEntity extends Entity implements GeoEntity {
private static final Map<UUID, Set<UUID>> QUEEN_TEAR_IDS = new HashMap<>();
private final AnimatableInstanceCache geoCache = GeckoLibUtil.createInstanceCache(this);
@Nullable
private TearIdleSoundInstance idleSound;
private UUID linkedTearId;
@Nullable
private DimensionalTearEntity linkedTear;
@@ -147,7 +142,6 @@ public class DimensionalTearEntity extends Entity implements GeoEntity {
super.tick();
if (this.level().isClientSide) {
this.tickClientParticles();
this.tickIdleSound();
return;
}
@@ -295,12 +289,12 @@ public class DimensionalTearEntity extends Entity implements GeoEntity {
continue;
}
manticore.finalizeSpawn(level, level.getCurrentDifficultyAt(BlockPos.containing(exit)), MobSpawnType.MOB_SUMMONED, null);
manticore.markPlayerSummoned(player.getUUID(), 20 * 30);
manticore.markPlayerSummoned(player.getUUID());
if (player.getLastHurtMob() != null && player.getLastHurtMob().isAlive()) {
manticore.setTarget(player.getLastHurtMob());
}
manticore.setDeltaMovement(this.getViewVector(1.0F).scale(0.2D).add(0.0D, 0.08D, 0.0D));
manticore.setNoGravity(true);
manticore.setDeltaMovement(this.getViewVector(1.0F).scale(0.7D).add(0.0D, 0.18D, 0.0D));
manticore.setNoGravity(false);
level.addFreshEntity(manticore);
}
}
@@ -439,16 +433,8 @@ public class DimensionalTearEntity extends Entity implements GeoEntity {
this.entityData.set(STATE, state.ordinal());
}
private void tickIdleSound() {
SoundManager soundManager = Minecraft.getInstance().getSoundManager();
if (this.getTearState() == TearState.OPENING) {
return;
}
if (this.idleSound != null && soundManager.isActive(this.idleSound)) {
return;
}
this.idleSound = new TearIdleSoundInstance(this);
soundManager.play(this.idleSound);
public boolean shouldPlayIdleSound() {
return this.getTearState() != TearState.OPENING;
}
private void tickClientParticles() {
@@ -572,36 +558,4 @@ public class DimensionalTearEntity extends Entity implements GeoEntity {
public AnimatableInstanceCache getAnimatableInstanceCache() {
return this.geoCache;
}
private static final class TearIdleSoundInstance extends AbstractTickableSoundInstance {
private final DimensionalTearEntity tear;
private TearIdleSoundInstance(DimensionalTearEntity tear) {
super(AntarchySoundEvents.DIMENSIONAL_TEAR_IDLE.get(), SoundSource.HOSTILE, tear.random);
this.tear = tear;
this.looping = true;
this.delay = 0;
this.volume = 0.6F;
this.pitch = 1.0F;
this.x = tear.getX();
this.y = tear.getY();
this.z = tear.getZ();
}
@Override
public void tick() {
if (this.tear.isRemoved() || this.tear.getTearState() == TearState.COLLAPSING) {
this.stop();
return;
}
this.x = this.tear.getX();
this.y = this.tear.getY();
this.z = this.tear.getZ();
}
@Override
public boolean canStartSilent() {
return true;
}
}
}
@@ -24,6 +24,9 @@ import net.minecraft.core.particles.DustParticleOptions;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
@@ -59,6 +62,8 @@ import net.minecraft.world.entity.player.Player;
import org.jetbrains.annotations.Nullable;
public class QueenEntity extends RoyalBossEntity {
private static final EntityDataAccessor<Boolean> QUEEN_MUSIC_ACTIVE =
SynchedEntityData.defineId(QueenEntity.class, EntityDataSerializers.BOOLEAN);
static final double TIME_FIELD_RADIUS_SCALE = 3.0D;
private static final String SUMMON_COOLDOWN_KEY = "ManticoreSummonCooldownTicks";
private static final int FAILED_SUMMON_RETRY_TICKS = 20;
@@ -196,6 +201,12 @@ public class QueenEntity extends RoyalBossEntity {
super(entityType, level);
}
@Override
protected void defineSynchedData(SynchedEntityData.Builder builder) {
super.defineSynchedData(builder);
builder.define(QUEEN_MUSIC_ACTIVE, false);
}
public static AttributeSupplier.Builder createAttributes() {
return createBaseAttributes(AntarchySettings.queenHealth(), AntarchySettings.queenAttackDamage());
}
@@ -348,6 +359,10 @@ public class QueenEntity extends RoyalBossEntity {
return !this.isDeadOrDying() && target != null && target.isAlive() && this.canAttack(target);
}
public boolean isQueenMusicActive() {
return this.entityData.get(QUEEN_MUSIC_ACTIVE);
}
@Override
protected SoundEvent royalFlyLoopSound() {
return AntarchySoundEvents.QUEEN_FLY_LOOP.get();
@@ -442,6 +457,9 @@ public class QueenEntity extends RoyalBossEntity {
@Override
public void tick() {
super.tick();
if (!this.level().isClientSide) {
this.entityData.set(QUEEN_MUSIC_ACTIVE, this.shouldPlayQueenMusic());
}
if (this.level().isClientSide || this.isDeadOrDying()) {
return;
}
@@ -17,8 +17,8 @@ public final class RoyalAssailantBlackHoleEntity extends RoyalBlackHoleEntity {
public static RoyalAssailantBlackHoleEntity create(ServerLevel level, Vec3 center, @Nullable UUID ownerId) {
RoyalAssailantBlackHoleEntity hole = new RoyalAssailantBlackHoleEntity(
AntarchyObjects.ROYAL_ASSAILANT_BLACK_HOLE.get(), level);
hole.configure(center, AntarchySettings.queenBlackHoleRadius(),
AntarchySettings.queenBlackHoleActiveTicks(), ownerId);
hole.configure(center, AntarchySettings.axeBlackHoleRadius(),
AntarchySettings.axeBlackHoleActiveTicks(), ownerId);
return hole;
}
@@ -54,6 +54,16 @@ public final class RoyalAssailantBlackHoleEntity extends RoyalBlackHoleEntity {
@Override
protected boolean pullsTerrainBlocks() {
return false;
return true;
}
@Override
protected double pullStrength() {
return AntarchySettings.axeBlackHolePullStrength();
}
@Override
protected int blockSuctionCap() {
return AntarchySettings.axeBlackHoleBlockSuctionCap();
}
}
@@ -238,6 +238,14 @@ public class RoyalBlackHoleEntity extends Entity implements GeoEntity {
return this.effectRadius() * QUEEN_PULL_RADIUS_SCALE;
}
protected double pullStrength() {
return AntarchySettings.queenBlackHolePullStrength();
}
protected int blockSuctionCap() {
return AntarchySettings.queenBlackHoleBlockSuctionCap();
}
/** Returns the center of the animated black-hole cube in world coordinates. */
public Vec3 effectCenter() {
double animationSeconds = Math.min(CORE_RISE_END_SECONDS, this.animationAge / 20.0D);
@@ -295,7 +303,7 @@ public class RoyalBlackHoleEntity extends Entity implements GeoEntity {
if (distance > radius) {
continue;
}
double strength = AntarchySettings.queenBlackHolePullStrength() * (1.0D - distance / radius);
double strength = this.pullStrength() * (1.0D - distance / radius);
Vec3 pull = toCenter.scale(strength / distance);
entity.setDeltaMovement(entity.getDeltaMovement().scale(0.86D).add(pull));
entity.hasImpulse = true;
@@ -304,7 +312,7 @@ public class RoyalBlackHoleEntity extends Entity implements GeoEntity {
}
private void pullTerrainBlocks(ServerLevel level) {
int cap = AntarchySettings.queenBlackHoleBlockSuctionCap();
int cap = this.blockSuctionCap();
if (cap <= 0 || this.suckedBlocks >= cap
|| !level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
return;
@@ -19,7 +19,7 @@ public final class PermanentPortalShape {
public static final int MIN_WIDTH = 2;
public static final int MIN_HEIGHT = 3;
public static final int MAX_SIZE = 21;
public static final int ACTIVE_SEARCH_RADIUS = 24;
public static final int ACTIVE_SEARCH_RADIUS = 128;
private final TagKey<Block> frameTag;
private final Block portalBlock;
@@ -227,10 +227,6 @@ public final class PermanentPortalShape {
for (int y = -1; y <= 3; y++) {
for (int x = -1; x <= 2; x++) {
BlockPos pos = bottomLeft.relative(widthDirection, x).above(y);
boolean cornerSpot = (x == -1 || x == 2) && (y == -1 || y == 3);
if (cornerSpot) {
continue;
}
if (x == -1 || x == 2 || y == -1 || y == 3) {
level.setBlock(pos, frameState, Block.UPDATE_ALL);
} else {
@@ -250,10 +246,6 @@ public final class PermanentPortalShape {
BlockPos pos = bottomLeft.relative(widthDirection, x).above(y);
BlockState state = level.getBlockState(pos);
boolean frameSpot = x == -1 || x == 2 || y == -1 || y == 3;
boolean cornerSpot = (x == -1 || x == 2) && (y == -1 || y == 3);
if (cornerSpot) {
continue;
}
if (frameSpot) {
if (y != -1 && !state.isAir() && !state.is(frameBlock) && !state.canBeReplaced()) {
return false;
@@ -12,6 +12,7 @@ import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.vehicle.DismountHelper;
import net.minecraft.world.level.dimension.DimensionType;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
@@ -23,7 +24,7 @@ import org.jetbrains.annotations.Nullable;
public final class PermanentPortalTeleporter {
private static final int SEARCH_RADIUS = 24;
private static final int VERTICAL_SEARCH = 24;
private static final int EXISTING_PORTAL_SEARCH_RADIUS = 48;
private static final int EXISTING_PORTAL_SEARCH_RADIUS = 128;
private PermanentPortalTeleporter() {
}
@@ -46,7 +47,7 @@ public final class PermanentPortalTeleporter {
return new DimensionTransition(sourceLevel, entity, DimensionTransition.DO_NOTHING);
}
Vec3 arrival = findArrivalPosition(entity, destination, portalPos, type);
Vec3 arrival = findArrivalPosition(sourceLevel, entity, destination, portalPos, type);
if (arrival == null) {
if (entity instanceof ServerPlayer player) {
player.displayClientMessage(net.minecraft.network.chat.Component.translatable("message.antarchy.teleport_arrival_failed"), true);
@@ -65,7 +66,9 @@ public final class PermanentPortalTeleporter {
}
@Nullable
private static Vec3 findArrivalPosition(Entity entity, ServerLevel destination, BlockPos preferredPos, PermanentPortalType type) {
private static Vec3 findArrivalPosition(ServerLevel source, Entity entity, ServerLevel destination, BlockPos preferredPos, PermanentPortalType type) {
double scale = DimensionType.getTeleportationScale(source.dimensionType(), destination.dimensionType());
preferredPos = BlockPos.containing(preferredPos.getX() * scale, preferredPos.getY(), preferredPos.getZ() * scale);
PermanentPortalShape active = PermanentPortalShape.findActiveNear(destination, preferredPos, type);
if (active != null) {
Vec3 safePortalPosition = tryFindSafePosition(entity, destination, BlockPos.containing(active.center()));
@@ -16,148 +16,46 @@ import net.minecraft.world.level.biome.BiomeSource;
import net.minecraft.world.level.biome.Climate;
import net.minecraft.world.level.biome.MultiNoiseBiomeSource;
public class ElythiaBiomeSource extends BiomeSource {
private static final ResourceKey<Biome> MOLEWORM_CAVES = ResourceKey.create(
Registries.BIOME,
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "moleworm_caves")
);
private static final ResourceKey<Biome> ELYTHIA_LUSH_CAVES = ResourceKey.create(
Registries.BIOME,
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "elythia_lush_caves")
);
private static final ResourceKey<Biome> ELYTHIA_OCEAN = ResourceKey.create(
Registries.BIOME,
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "elythia_ocean")
);
private static final ResourceKey<Biome> ELYTHIA_CORAL_SPIKES = ResourceKey.create(
Registries.BIOME,
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "elythia_coral_spikes")
);
private static final ResourceKey<Biome> ELYTHIA_BEACH = ResourceKey.create(
Registries.BIOME,
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "elythia_beach")
);
private static final ResourceKey<Biome> OURANWOOD_FOREST = ResourceKey.create(
Registries.BIOME,
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "ouranwood_forest")
);
private static final ResourceKey<Biome> SPARSE_OURANWOOD_FOREST = ResourceKey.create(
Registries.BIOME,
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "sparse_ouranwood_forest")
);
private static final ResourceKey<Biome> PEACH_FOREST = ResourceKey.create(
Registries.BIOME,
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "peach_forest")
);
private static final ResourceKey<Biome> FUNGAL_OURANWOOD_FOREST = ResourceKey.create(
Registries.BIOME,
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "fungal_ouranwood_forest")
);
private static final ResourceKey<Biome> GLIMMERING_POOLS = ResourceKey.create(
Registries.BIOME,
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "glimmering_pools")
);
public final class ElythiaBiomeSource extends BiomeSource {
private static final ResourceKey<Biome> CLOUD_SEA = ResourceKey.create(
Registries.BIOME,
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "cloud_sea")
);
private static final int[] SURFACE_FALLBACK_BLOCK_YS = new int[]{192, 160, 128, 96, 64, 32, 0};
private static final class ColumnBiomeCache {
long key = Long.MIN_VALUE;
Holder<Biome> value;
}
private final ThreadLocal<ColumnBiomeCache> molewormSurfaceFallbackCache = ThreadLocal.withInitial(ColumnBiomeCache::new);
private final ThreadLocal<ColumnBiomeCache> peachForestSurfaceFallbackCache = ThreadLocal.withInitial(ColumnBiomeCache::new);
private final ThreadLocal<ColumnBiomeCache> landFallbackCache = ThreadLocal.withInitial(ColumnBiomeCache::new);
private static long packColumnKey(int x, int z) {
return ((long) x << 32) ^ (z & 0xFFFFFFFFL);
}
public static final MapCodec<ElythiaBiomeSource> CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group(
MultiNoiseBiomeSource.DIRECT_CODEC.forGetter(ElythiaBiomeSource::parameters),
Codec.INT.optionalFieldOf("moleworm_caves_max_y", 72).forGetter(ElythiaBiomeSource::molewormCavesMaxY),
Codec.INT.optionalFieldOf("surface_biome_sample_y", 160).forGetter(ElythiaBiomeSource::surfaceBiomeSampleY),
Codec.INT.optionalFieldOf("ocean_max_y", 85).forGetter(ElythiaBiomeSource::oceanMaxY),
Codec.INT.optionalFieldOf("sea_level", 78).forGetter(ElythiaBiomeSource::seaLevel),
Codec.INT.optionalFieldOf("cloud_sea_min_y", 360).forGetter(ElythiaBiomeSource::cloudSeaMinY)
Codec.INT.optionalFieldOf("cloud_sea_min_y", 250).forGetter(ElythiaBiomeSource::cloudSeaMinY)
).apply(instance, ElythiaBiomeSource::new));
private final Climate.ParameterList<Holder<Biome>> parameters;
private final MultiNoiseBiomeSource delegate;
private final int molewormCavesMaxY;
private final int surfaceBiomeSampleY;
private final int oceanMaxY;
private final int seaLevel;
private final int cloudSeaMinY;
private final int molewormCavesMaxQuartY;
private final int surfaceBiomeSampleQuartY;
private final int oceanMaxQuartY;
private final int seaLevelQuartY;
private final int undergroundGuardMaxQuartY;
private final int cloudSeaMinQuartY;
private final Holder<Biome> oceanHolder;
private final Holder<Biome> defaultLandHolder;
private final Holder<Biome> glimmeringPoolsHolder;
private final Holder<Biome> ouranwoodForestHolder;
private final Holder<Biome> cloudSeaHolder;
private final Holder<Biome> firstConfiguredHolder;
private final Holder<Biome> fallbackHolder;
public ElythiaBiomeSource(Climate.ParameterList<Holder<Biome>> parameters, int molewormCavesMaxY, int surfaceBiomeSampleY, int oceanMaxY, int seaLevel, int cloudSeaMinY) {
public ElythiaBiomeSource(Climate.ParameterList<Holder<Biome>> parameters, int cloudSeaMinY) {
this.parameters = parameters;
this.delegate = MultiNoiseBiomeSource.createFromList(parameters);
this.molewormCavesMaxY = molewormCavesMaxY;
this.surfaceBiomeSampleY = surfaceBiomeSampleY;
this.oceanMaxY = oceanMaxY;
this.seaLevel = seaLevel;
this.cloudSeaMinY = cloudSeaMinY;
this.molewormCavesMaxQuartY = QuartPos.fromBlock(molewormCavesMaxY);
this.surfaceBiomeSampleQuartY = QuartPos.fromBlock(surfaceBiomeSampleY);
this.oceanMaxQuartY = QuartPos.fromBlock(oceanMaxY);
this.seaLevelQuartY = QuartPos.fromBlock(seaLevel);
this.undergroundGuardMaxQuartY = QuartPos.fromBlock(molewormCavesMaxY + 40);
this.cloudSeaMinQuartY = QuartPos.fromBlock(cloudSeaMinY);
this.oceanHolder = parameters.values().stream()
.map(Pair::getSecond)
.filter(h -> h.is(ELYTHIA_OCEAN))
.findFirst()
.orElse(null);
this.glimmeringPoolsHolder = parameters.values().stream()
.map(Pair::getSecond)
.filter(h -> h.is(GLIMMERING_POOLS))
.findFirst()
.orElse(null);
this.ouranwoodForestHolder = parameters.values().stream()
.map(Pair::getSecond)
.filter(h -> h.is(OURANWOOD_FOREST))
.findFirst()
.orElse(null);
this.defaultLandHolder = parameters.values().stream()
.map(Pair::getSecond)
.filter(h -> !isOceanBiome(h) && !h.is(ELYTHIA_BEACH)
&& !h.is(MOLEWORM_CAVES) && !h.is(ELYTHIA_LUSH_CAVES)
&& !h.is(GLIMMERING_POOLS))
.findFirst()
.orElse(null);
this.cloudSeaHolder = parameters.values().stream()
.map(Pair::getSecond)
.filter(h -> h.is(CLOUD_SEA))
.filter(holder -> holder.is(CLOUD_SEA))
.findFirst()
.orElse(null);
this.firstConfiguredHolder = parameters.values().stream()
this.fallbackHolder = parameters.values().stream()
.map(Pair::getSecond)
.filter(holder -> !holder.is(CLOUD_SEA))
.findFirst()
.orElse(null);
}
private Climate.ParameterList<Holder<Biome>> parameters() { return this.parameters; }
private int molewormCavesMaxY() { return this.molewormCavesMaxY; }
private int surfaceBiomeSampleY() { return this.surfaceBiomeSampleY; }
private int oceanMaxY() { return this.oceanMaxY; }
private int seaLevel() { return this.seaLevel; }
private int cloudSeaMinY() { return this.cloudSeaMinY; }
private Climate.ParameterList<Holder<Biome>> parameters() {
return this.parameters;
}
private int cloudSeaMinY() {
return this.cloudSeaMinQuartY * 4;
}
@Override
protected MapCodec<? extends BiomeSource> codec() {
@@ -168,236 +66,17 @@ public class ElythiaBiomeSource extends BiomeSource {
protected Stream<Holder<Biome>> collectPossibleBiomes() {
return this.delegate.possibleBiomes().stream();
}
private static final long OCEAN_CONTINENTALNESS_THRESHOLD = Climate.quantizeCoord(-0.87f);
private static final int CLOUD_SEA_CELL_SIZE = 96;
private static final long CLOUD_SEA_CHANCE_DENOMINATOR = 5L; // 1-in-5 columns == ~20%
@Override
public Holder<Biome> getNoiseBiome(int x, int y, int z, Climate.Sampler sampler) {
// Only some sky columns are the cloud sea — everywhere else, altitude above the cloud
// floor just falls through to whatever biome would normally be there. Decided before
// touching the (expensive) delegate at all, both for correctness (multi-noise has no
// real notion of raw Y to gate a biome on) and as a speed win for the common case.
if (this.cloudSeaHolder != null && y >= this.cloudSeaMinQuartY && isCloudSeaColumn(x, z)) {
if (this.cloudSeaHolder != null && y >= this.cloudSeaMinQuartY) {
return this.cloudSeaHolder;
}
Holder<Biome> biome = this.delegate.getNoiseBiome(x, y, z, sampler);
if (biome == null) {
return resolveConfiguredFallback(x, y, z, sampler);
}
// Defensive: cloud_sea's multi-noise parameter point is reserved far off in "offset"
// so it shouldn't win nearest-neighbor on its own, but if it ever does for a query
// below the cloud floor, treat it like any other biome that has no business at that
// altitude and fall back to a real land biome instead of leaking clouds into terrain.
if (biome.is(CLOUD_SEA)) {
return resolveLandFallback(x, z, sampler);
}
if (biome.is(MOLEWORM_CAVES) && y > this.molewormCavesMaxQuartY) {
return resolveSurfaceFallback(x, z, sampler, this.molewormSurfaceFallbackCache, MOLEWORM_CAVES, GLIMMERING_POOLS, CLOUD_SEA);
}
Climate.TargetPoint target = sampler.sample(x, this.seaLevelQuartY, z);
if (target.continentalness() < OCEAN_CONTINENTALNESS_THRESHOLD && y <= this.oceanMaxQuartY) {
if (biome.is(MOLEWORM_CAVES) || biome.is(ELYTHIA_LUSH_CAVES)) return biome;
Holder<Biome> seaLevelBiome = this.delegate.getNoiseBiome(x, this.seaLevelQuartY, z, sampler);
if (isOceanBiome(seaLevelBiome)) return seaLevelBiome;
return oceanHolder != null ? oceanHolder : nullToConfiguredFallback(seaLevelBiome, x, y, z, sampler);
}
if (y <= this.seaLevelQuartY && oceanHolder != null && !allowedBelowSeaLevel(biome)) {
return oceanHolder;
}
if (isOceanBiome(biome)) {
return resolveLandFallback(x, z, sampler);
}
if (biome.is(SPARSE_OURANWOOD_FOREST) && !isSparseOuranwoodCandidate(target, x, z)) {
biome = this.ouranwoodForestHolder != null ? this.ouranwoodForestHolder : biome;
}
if (isGlimmeringPoolsCandidate(biome, target, x, z)) {
biome = this.glimmeringPoolsHolder != null ? this.glimmeringPoolsHolder : biome;
}
if ((biome.is(PEACH_FOREST) || biome.is(GLIMMERING_POOLS)) && y <= this.undergroundGuardMaxQuartY) {
return resolveSurfaceFallback(x, z, sampler, this.peachForestSurfaceFallbackCache, PEACH_FOREST, GLIMMERING_POOLS, CLOUD_SEA);
}
if (biome != null && !biome.is(CLOUD_SEA)) {
return biome;
}
private static boolean allowedBelowSeaLevel(Holder<Biome> biome) {
return biome != null && (biome.is(MOLEWORM_CAVES) || biome.is(ELYTHIA_LUSH_CAVES)
|| biome.is(ELYTHIA_OCEAN) || biome.is(ELYTHIA_CORAL_SPIKES));
}
private static boolean isOceanBiome(Holder<Biome> biome) {
return biome != null && (biome.is(ELYTHIA_OCEAN) || biome.is(ELYTHIA_CORAL_SPIKES));
}
private static boolean isOuranwoodBiome(Holder<Biome> biome) {
return biome != null && (biome.is(OURANWOOD_FOREST) || biome.is(SPARSE_OURANWOOD_FOREST)
|| biome.is(FUNGAL_OURANWOOD_FOREST));
}
private static boolean isGlimmeringPoolsCandidate(Holder<Biome> biome, Climate.TargetPoint target, int x, int z) {
if (!isOuranwoodBiome(biome)) {
return false;
}
long humidity = target.humidity();
long continentalness = target.continentalness();
long weirdness = target.weirdness();
long depth = target.depth();
if (humidity < Climate.quantizeCoord(0.64F) || humidity > Climate.quantizeCoord(1.0F)) {
return false;
}
if (continentalness < Climate.quantizeCoord(0.29F) || continentalness > Climate.quantizeCoord(0.90F)) {
return false;
}
if (weirdness < Climate.quantizeCoord(-0.88F) || weirdness > Climate.quantizeCoord(0.33F)) {
return false;
}
if (depth < Climate.quantizeCoord(0.0F) || depth > Climate.quantizeCoord(0.80F)) {
return false;
}
long cellX = Math.floorDiv(x, 11);
long cellZ = Math.floorDiv(z, 11);
long gate = Math.floorMod(cellX * 73428767L + cellZ * 912931L, 5L);
return gate <= 3L;
}
private static boolean isCloudSeaColumn(int x, int z) {
long cellX = Math.floorDiv(x, CLOUD_SEA_CELL_SIZE);
long cellZ = Math.floorDiv(z, CLOUD_SEA_CELL_SIZE);
long gate = Math.floorMod(cellX * 668265263L + cellZ * 2246822519L, CLOUD_SEA_CHANCE_DENOMINATOR);
return gate == 0L;
}
private static boolean isSparseOuranwoodCandidate(Climate.TargetPoint target, int x, int z) {
if (target.temperature() > Climate.quantizeCoord(0.24F)) {
return false;
}
if (target.humidity() > Climate.quantizeCoord(0.70F)) {
return false;
}
if (target.continentalness() < Climate.quantizeCoord(0.90F)) {
return false;
}
if (target.erosion() > Climate.quantizeCoord(-0.22F)) {
return false;
}
if (target.weirdness() < Climate.quantizeCoord(0.92F)) {
return false;
}
long cellX = Math.floorDiv(x, 24);
long cellZ = Math.floorDiv(z, 24);
long gate = Math.floorMod(cellX * 1103515245L + cellZ * 2147483647L, 12L);
return gate == 0L;
}
@SafeVarargs
private Holder<Biome> resolveSurfaceFallback(int x, int z, Climate.Sampler sampler, ThreadLocal<ColumnBiomeCache> cacheHolder, ResourceKey<Biome>... excluded) {
ColumnBiomeCache cache = cacheHolder.get();
long key = packColumnKey(x, z);
if (cache.key == key) {
return cache.value;
}
Holder<Biome> result = this.delegate.getNoiseBiome(x, this.surfaceBiomeSampleQuartY, z, sampler);
if (isExcluded(result, excluded)) {
for (int sampleBlockY : SURFACE_FALLBACK_BLOCK_YS) {
Holder<Biome> candidate = this.delegate.getNoiseBiome(x, QuartPos.fromBlock(sampleBlockY), z, sampler);
if (!isExcluded(candidate, excluded)) {
result = candidate;
break;
}
}
}
result = nullToConfiguredFallback(result, x, this.surfaceBiomeSampleQuartY, z, sampler);
if (result != null && result.is(CLOUD_SEA) && this.defaultLandHolder != null) {
result = this.defaultLandHolder;
}
cache.key = key;
cache.value = result;
return result;
}
private Holder<Biome> resolveLandFallback(int x, int z, Climate.Sampler sampler) {
ColumnBiomeCache cache = this.landFallbackCache.get();
long key = packColumnKey(x, z);
if (cache.key == key) {
return cache.value;
}
Holder<Biome> result = this.delegate.getNoiseBiome(x, this.surfaceBiomeSampleQuartY, z, sampler);
if (isOceanOrCave(result)) {
Holder<Biome> resolved = null;
for (int sampleBlockY : SURFACE_FALLBACK_BLOCK_YS) {
Holder<Biome> candidate = this.delegate.getNoiseBiome(x, QuartPos.fromBlock(sampleBlockY), z, sampler);
if (!isOceanOrCave(candidate)) {
resolved = candidate;
break;
}
}
result = resolved != null ? resolved : (defaultLandHolder != null ? defaultLandHolder : result);
}
result = nullToConfiguredFallback(result, x, this.surfaceBiomeSampleQuartY, z, sampler);
cache.key = key;
cache.value = result;
return result;
}
@SafeVarargs
private static boolean isExcluded(Holder<Biome> biome, ResourceKey<Biome>... excluded) {
if (biome == null) {
return true;
}
for (ResourceKey<Biome> key : excluded) {
if (biome.is(key)) return true;
}
return false;
}
private static boolean isOceanOrCave(Holder<Biome> biome) {
return biome == null || isOceanBiome(biome) || biome.is(ELYTHIA_BEACH)
|| biome.is(MOLEWORM_CAVES) || biome.is(ELYTHIA_LUSH_CAVES)
|| biome.is(GLIMMERING_POOLS) || biome.is(CLOUD_SEA);
}
private Holder<Biome> nullToConfiguredFallback(Holder<Biome> biome, int x, int y, int z, Climate.Sampler sampler) {
return biome != null ? biome : resolveConfiguredFallback(x, y, z, sampler);
}
private Holder<Biome> resolveConfiguredFallback(int x, int y, int z, Climate.Sampler sampler) {
if (y <= this.oceanMaxQuartY && this.oceanHolder != null) {
Climate.TargetPoint target = sampler.sample(x, this.seaLevelQuartY, z);
if (target.continentalness() < OCEAN_CONTINENTALNESS_THRESHOLD) {
return this.oceanHolder;
}
}
if (this.defaultLandHolder != null) return this.defaultLandHolder;
if (this.ouranwoodForestHolder != null) return this.ouranwoodForestHolder;
if (this.glimmeringPoolsHolder != null) return this.glimmeringPoolsHolder;
if (this.oceanHolder != null) return this.oceanHolder;
return this.firstConfiguredHolder;
}
@Override
public void addDebugInfo(java.util.List<String> debug, net.minecraft.core.BlockPos pos, Climate.Sampler sampler) {
try {
this.delegate.addDebugInfo(debug, pos, sampler);
} catch (NullPointerException ignored) {
}
debug.add("Elythia mole cave cap: y<=" + this.molewormCavesMaxY);
debug.add("Elythia sea level: " + this.seaLevel);
debug.add("Elythia cloud sea: y>=" + this.cloudSeaMinY + " in ~1/" + CLOUD_SEA_CHANCE_DENOMINATOR + " columns");
return this.fallbackHolder != null ? this.fallbackHolder : biome;
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 348 B

After

Width:  |  Height:  |  Size: 393 B

@@ -4,7 +4,8 @@
"type": "minecraft:noise",
"settings": "antarchy:elythia",
"biome_source": {
"type": "minecraft:multi_noise",
"type": "antarchy:elythia_biome_source",
"cloud_sea_min_y": 250,
"biomes": [
{
"biome": "antarchy:elythia_ocean",
@@ -113,6 +114,18 @@
"depth": [0.0, 0.35],
"offset": 0.0
}
},
{
"biome": "antarchy:cloud_sea",
"parameters": {
"temperature": [-1.0, 1.0],
"humidity": [-1.0, 1.0],
"continentalness": [-1.0, 1.0],
"erosion": [-1.0, 1.0],
"weirdness": [-1.0, 1.0],
"depth": [-1.0, 1.0],
"offset": 1.0
}
}
]
}
@@ -2,8 +2,6 @@
"type": "integrated_api:generic_structure",
"start_pool": "antarchy:tigers_eye_shrine/tigers_eye_shrine",
"size": 1,
"terrain_height_radius_check": 4,
"allowed_terrain_height_range": 14,
"valid_biome_radius_check": 1,
"biomes": "#antarchy:has_structure/tigers_eye_shrine_biomes",
"step": "underground_structures",
+2 -2
View File
@@ -38,8 +38,7 @@ dependencies {
modImplementation "net.fabricmc:fabric-loader:${fabric_loader_version_1_21_1}"
modApi "net.fabricmc.fabric-api:fabric-api:${fabric_api_version_1_21_1}"
modImplementation "software.bernie.geckolib:geckolib-fabric-1.21.1:${geckolib_version}"
// AntOS is developed beside Antarchy as a separate local project.
modImplementation files("$rootDir/../AntOS/fabric-1.21.1/build/libs/antos-fabric-1.21.1-1.0.1.jar")
modImplementation("curse.maven:antos-${antos_curseforge_id}:${antos_curseforge_file_id_fabric}")
modCompileOnly("curse.maven:intapi-${intapi_curseforge_id}:${intapi_curseforge_file_id_fabric}")
modLocalRuntime("curse.maven:intapi-${intapi_curseforge_id}:${intapi_curseforge_file_id_fabric}")
modLocalRuntime("dev.architectury:architectury-fabric:${architectury_api_version}")
@@ -90,6 +89,7 @@ tasks.named('processResources', ProcessResources).configure {
version : project.version,
minecraft_version : "1.21.1",
fabric_loader_version: fabric_loader_version_1_21_1,
architectury_api_version: architectury_api_version,
mod_id : mod_id,
mod_name : mod_name,
mod_description : mod_description,
@@ -111,6 +111,7 @@ public final class AntarchyFabricContent {
AntarchyFabricMisc.ARMOR_MATERIALS.register();
AntarchyFabricMisc.FLUIDS.register();
AntarchyFabricBlocks.BLOCKS.register();
AntarchyFabricBlocks.registerStripping();
AntarchyFabricEntities.ENTITY_TYPES.register();
AntarchyFabricMisc.ATTRIBUTES.register();
AntarchyFabricEntityAttributes.register();
@@ -129,6 +129,8 @@ public final class AntarchyFabricClientBootstrap {
EntityRendererRegistry.register(AntarchyFabricEntities.NADIR_CHEST_BOAT_ENTITY.get(), context -> new PeachBoatRenderer<>(context, ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "textures/entity/chest_boat/nadir.png"), true));
EntityRendererRegistry.register(AntarchyFabricEntities.ROYAL_BOAT_ENTITY.get(), context -> new PeachBoatRenderer<>(context, ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "textures/entity/boat/royal.png"), false));
EntityRendererRegistry.register(AntarchyFabricEntities.ROYAL_CHEST_BOAT_ENTITY.get(), context -> new PeachBoatRenderer<>(context, ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "textures/entity/chest_boat/royal.png"), true));
EntityRendererRegistry.register(AntarchyFabricEntities.TRUFFALO_BOAT_ENTITY.get(), context -> new PeachBoatRenderer<>(context, ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "textures/entity/boat/truffalo.png"), false));
EntityRendererRegistry.register(AntarchyFabricEntities.TRUFFALO_CHEST_BOAT_ENTITY.get(), context -> new PeachBoatRenderer<>(context, ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "textures/entity/chest_boat/truffalo.png"), true));
EntityRendererRegistry.register(AntarchyFabricEntities.APPLE_COW.get(), context -> withTemporalGeoLayer(new AppleCowRenderer(context)));
EntityRendererRegistry.register(AntarchyFabricEntities.GOLDEN_APPLE_COW.get(), context -> withTemporalGeoLayer(new AppleCowRenderer(context)));
EntityRendererRegistry.register(AntarchyFabricEntities.ENCHANTED_GOLDEN_APPLE_COW.get(), context -> withTemporalGeoLayer(new AppleCowRenderer(context)));
@@ -590,6 +592,7 @@ public final class AntarchyFabricClientBootstrap {
ElythiaFireflyManager.register();
LucidSoundHandler.register();
TearIdleSoundHandler.register();
MogglesClientRenderer.register();
StinkySoundHandler.register();
ReverieTrailHandler.register();
@@ -9,13 +9,14 @@ import net.minecraft.client.KeyMapping;
public final class KeybindingConflictFixStore {
private static final String ANTARCHY_KEY_PREFIX = "key.antarchy.";
private static final String SPRINT_KEY = "key.sprint";
private static final Map<InputConstants.Key, List<KeyMapping>> MAPPINGS = new HashMap<>();
private KeybindingConflictFixStore() {
}
public static void add(InputConstants.Key key, KeyMapping mapping) {
if (!mapping.getName().startsWith(ANTARCHY_KEY_PREFIX)) {
if (!isTracked(mapping)) {
return;
}
List<KeyMapping> mappings = MAPPINGS.computeIfAbsent(key, ignored -> new ArrayList<>());
@@ -41,4 +42,12 @@ public final class KeybindingConflictFixStore {
}
return others;
}
public static boolean isSprint(KeyMapping mapping) {
return SPRINT_KEY.equals(mapping.getName());
}
private static boolean isTracked(KeyMapping mapping) {
return mapping.getName().startsWith(ANTARCHY_KEY_PREFIX) || isSprint(mapping);
}
}
@@ -0,0 +1,112 @@
package com.craisinlord.antarchy.fabric.client;
import com.craisinlord.antarchy.content.AntarchySoundEvents;
import com.craisinlord.antarchy.content.entity.portal.DimensionalTearEntity;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.sounds.AbstractTickableSoundInstance;
import net.minecraft.sounds.SoundSource;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
public final class TearIdleSoundHandler {
private static final double START_SCAN_RADIUS = 64.0D;
private static final int DISCOVERY_SCAN_INTERVAL_TICKS = 10;
private static final Map<UUID, TearIdleSound> ACTIVE_LOOPS = new HashMap<>();
private static long nextDiscoveryScanTick;
private TearIdleSoundHandler() {
}
public static void register() {
ClientTickEvents.END_CLIENT_TICK.register(client -> {
if (client.level == null || client.player == null || client.isPaused()) {
resetAll(client);
return;
}
pruneStaleLoops(client);
long gameTime = client.level.getGameTime();
if (gameTime >= nextDiscoveryScanTick) {
nextDiscoveryScanTick = gameTime + DISCOVERY_SCAN_INTERVAL_TICKS;
discoverNearbyTears(client);
}
});
}
private static void discoverNearbyTears(Minecraft mc) {
List<DimensionalTearEntity> tears = mc.level.getEntitiesOfClass(
DimensionalTearEntity.class,
mc.player.getBoundingBox().inflate(START_SCAN_RADIUS)
);
for (DimensionalTearEntity tear : tears) {
if (!tear.shouldPlayIdleSound() || ACTIVE_LOOPS.containsKey(tear.getUUID())) {
continue;
}
TearIdleSound sound = new TearIdleSound(tear);
ACTIVE_LOOPS.put(tear.getUUID(), sound);
mc.getSoundManager().play(sound);
}
}
private static void pruneStaleLoops(Minecraft mc) {
Iterator<Map.Entry<UUID, TearIdleSound>> iterator = ACTIVE_LOOPS.entrySet().iterator();
while (iterator.hasNext()) {
TearIdleSound sound = iterator.next().getValue();
if (!sound.isValid()) {
mc.getSoundManager().stop(sound);
iterator.remove();
}
}
}
private static void resetAll(Minecraft mc) {
for (TearIdleSound sound : ACTIVE_LOOPS.values()) {
mc.getSoundManager().stop(sound);
}
ACTIVE_LOOPS.clear();
nextDiscoveryScanTick = 0L;
}
private static final class TearIdleSound extends AbstractTickableSoundInstance {
private final DimensionalTearEntity tear;
private TearIdleSound(DimensionalTearEntity tear) {
super(AntarchySoundEvents.DIMENSIONAL_TEAR_IDLE.get(), SoundSource.HOSTILE, tear.getRandom());
this.tear = tear;
this.looping = true;
this.delay = 0;
this.volume = 0.6F;
this.pitch = 1.0F;
this.x = tear.getX();
this.y = tear.getY();
this.z = tear.getZ();
}
private boolean isValid() {
return !this.tear.isRemoved() && this.tear.shouldPlayIdleSound();
}
@Override
public void tick() {
if (!this.isValid()) {
this.stop();
return;
}
this.x = this.tear.getX();
this.y = this.tear.getY();
this.z = this.tear.getZ();
}
@Override
public boolean canStartSilent() {
return true;
}
}
}
@@ -19,6 +19,7 @@ public abstract class KeybindingConflictFixMixin {
@Shadow @Final private static Map<String, KeyMapping> ALL;
@Shadow private InputConstants.Key key;
@Shadow private boolean isDown;
@Shadow private int clickCount;
@Inject(method = "<init>(Ljava/lang/String;Lcom/mojang/blaze3d/platform/InputConstants$Type;ILjava/lang/String;)V", at = @At("TAIL"))
private void antarchy$addInitialMapping(String name, InputConstants.Type type, int key, String category, CallbackInfo ci) {
@@ -44,8 +45,31 @@ public abstract class KeybindingConflictFixMixin {
}
}
@Inject(method = "click", at = @At("TAIL"))
private static void antarchy$clickConflicts(InputConstants.Key key, CallbackInfo ci) {
if (!AntarchySettings.fabricKeybindingConflictFixEnabled()) {
return;
}
KeyMapping active = MAP.get(key);
for (KeyMapping mapping : KeybindingConflictFixStore.others(key, active)) {
if (((KeybindingConflictFixMixin) (Object) mapping).antarchy$isSprint()) {
((KeybindingConflictFixMixin) (Object) mapping).antarchy$click();
}
}
}
@Unique
private void antarchy$setDown(boolean down) {
this.isDown = down;
}
@Unique
private boolean antarchy$isSprint() {
return KeybindingConflictFixStore.isSprint((KeyMapping) (Object) this);
}
@Unique
private void antarchy$click() {
this.clickCount++;
}
}
@@ -51,6 +51,7 @@ import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.block.Mirror;
import net.minecraft.world.level.block.Rotation;
import net.fabricmc.fabric.api.registry.StrippableBlockRegistry;
public final class AntarchyFabricBlocks {
@@ -1759,4 +1760,17 @@ public final class AntarchyFabricBlocks {
BLOCK_ENTITY_TYPES.register();
}
public static void registerStripping() {
StrippableBlockRegistry.register(OURANWOOD_LOG.get(), STRIPPED_OURANWOOD_LOG.get());
StrippableBlockRegistry.register(OURANWOOD_WOOD.get(), STRIPPED_OURANWOOD_WOOD.get());
StrippableBlockRegistry.register(PEACH_LOG.get(), STRIPPED_PEACH_LOG.get());
StrippableBlockRegistry.register(PEACH_WOOD.get(), STRIPPED_PEACH_WOOD.get());
StrippableBlockRegistry.register(NADIR_LOG.get(), STRIPPED_NADIR_LOG.get());
StrippableBlockRegistry.register(NADIR_WOOD.get(), STRIPPED_NADIR_WOOD.get());
StrippableBlockRegistry.register(ROYAL_LOG.get(), STRIPPED_ROYAL_LOG.get());
StrippableBlockRegistry.register(ROYAL_WOOD.get(), STRIPPED_ROYAL_WOOD.get());
StrippableBlockRegistry.register(TRUFFALO_LOG.get(), STRIPPED_TRUFFALO_LOG.get());
StrippableBlockRegistry.register(TRUFFALO_WOOD.get(), STRIPPED_TRUFFALO_WOOD.get());
}
}
@@ -36,6 +36,7 @@
"minecraft": "~${minecraft_version}",
"java": ">=21",
"fabric-api": "*",
"architectury": "${architectury_api_version}",
"integrated_api": "*",
"geckolib": "*",
"sizeable_foliage": "*"
+5 -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=2.0.0
mod_version=2.0.2
maven_group=com.craisinlord
mixin_version=0.15.4+mixin.0.8.7
@@ -57,6 +57,10 @@ intapi_curseforge_file_id_neoforge = 7921681
intapi_curseforge_file_id_fabric = 7921674
intapi_curseforge_file_id_common = 5178461
antos_curseforge_id = 1700593
antos_curseforge_file_id_neoforge = 8936372
antos_curseforge_file_id_fabric = 8936369
create_curseforge_id_neoforge = 328085
#create_curseforge_id_fabric = 624165
create_curseforge_file_id_neoforge = 7408951
+6 -4
View File
@@ -46,9 +46,8 @@ neoForge {
}
dependencies {
// AntOS is developed beside Antarchy as a separate local project.
compileOnly(files("$rootDir/../AntOS/neoforge-1.21.1/build/libs/antos-neoforge-1.21.1-1.0.1.jar"))
runtimeOnly(files("$rootDir/../AntOS/neoforge-1.21.1/build/libs/antos-neoforge-1.21.1-1.0.1.jar"))
compileOnly("curse.maven:antos-${antos_curseforge_id}:${antos_curseforge_file_id_neoforge}")
runtimeOnly("curse.maven:antos-${antos_curseforge_id}:${antos_curseforge_file_id_neoforge}")
compileOnly("curse.maven:intapi-${intapi_curseforge_id}:${intapi_curseforge_file_id_neoforge}")
runtimeOnly("curse.maven:intapi-${intapi_curseforge_id}:${intapi_curseforge_file_id_neoforge}")
implementation "software.bernie.geckolib:geckolib-neoforge-1.21.1:${geckolib_version}"
@@ -79,7 +78,10 @@ dependencies {
tasks.withType(ProcessResources).configureEach {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
var replaceProperties = [version: project.version]
var replaceProperties = [
version: project.version,
architectury_api_version: architectury_api_version
]
inputs.properties replaceProperties
filesMatching('META-INF/neoforge.mods.toml') {
@@ -993,8 +993,8 @@ public final class AntarchyMobsConfig {
b.pop();
b.push("manticore");
MANTICORE_HEALTH = b.comment("Base max health.").defineInRange("health", 40.0D, 1.0D, 32768.0D);
MANTICORE_ATTACK_DAMAGE = b.comment("Base attack damage for bites and stings.").defineInRange("attackDamage", 7.0D, 0.0D, 1024.0D);
MANTICORE_HEALTH = b.comment("Base max health.").defineInRange("health", 60.0D, 1.0D, 32768.0D);
MANTICORE_ATTACK_DAMAGE = b.comment("Base attack damage for bites and stings.").defineInRange("attackDamage", 11.0D, 0.0D, 1024.0D);
MANTICORE_STING_POISON_TICKS = b.comment("Poison duration in ticks applied by a Manticore sting.").defineInRange("stingPoisonTicks", 100, 0, 12000);
QUEEN_MANTICORE_CAP = b.comment("Maximum number of living Manticores a single Queen may keep summoned.").defineInRange("queenSummonCap", 6, 1, 200);
QUEEN_MANTICORE_SUMMON_COOLDOWN_TICKS = b.comment("Ticks between Queen Manticore summon attempts.").defineInRange("queenSummonCooldownTicks", 800, 20, 200000);
@@ -83,6 +83,8 @@ public final class AntarchyNeoForgeClient {
private static final ResourceLocation NADIR_CHEST_BOAT_TEXTURE = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "textures/entity/chest_boat/nadir.png");
private static final ResourceLocation ROYAL_BOAT_TEXTURE = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "textures/entity/boat/royal.png");
private static final ResourceLocation ROYAL_CHEST_BOAT_TEXTURE = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "textures/entity/chest_boat/royal.png");
private static final ResourceLocation TRUFFALO_BOAT_TEXTURE = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "textures/entity/boat/truffalo.png");
private static final ResourceLocation TRUFFALO_CHEST_BOAT_TEXTURE = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "textures/entity/chest_boat/truffalo.png");
private static final ResourceLocation WATER_STILL = ResourceLocation.withDefaultNamespace("block/water_still");
private static final ResourceLocation WATER_FLOW = ResourceLocation.withDefaultNamespace("block/water_flow");
private static final ResourceLocation WATER_OVERLAY = ResourceLocation.withDefaultNamespace("block/water_overlay");
@@ -134,6 +136,8 @@ public final class AntarchyNeoForgeClient {
event.registerEntityRenderer(AntarchyNeoforgeEntites.NADIR_CHEST_BOAT_ENTITY.get(), context -> new PeachBoatRenderer<>(context, NADIR_CHEST_BOAT_TEXTURE, true));
event.registerEntityRenderer(AntarchyNeoforgeEntites.ROYAL_BOAT_ENTITY.get(), context -> new PeachBoatRenderer<>(context, ROYAL_BOAT_TEXTURE, false));
event.registerEntityRenderer(AntarchyNeoforgeEntites.ROYAL_CHEST_BOAT_ENTITY.get(), context -> new PeachBoatRenderer<>(context, ROYAL_CHEST_BOAT_TEXTURE, true));
event.registerEntityRenderer(AntarchyNeoforgeEntites.TRUFFALO_BOAT_ENTITY.get(), context -> new PeachBoatRenderer<>(context, TRUFFALO_BOAT_TEXTURE, false));
event.registerEntityRenderer(AntarchyNeoforgeEntites.TRUFFALO_CHEST_BOAT_ENTITY.get(), context -> new PeachBoatRenderer<>(context, TRUFFALO_CHEST_BOAT_TEXTURE, true));
event.registerEntityRenderer(AntarchyNeoforgeEntites.APPLE_COW.get(), context -> withParalyzedGeoLayer(new AppleCowRenderer(context)));
event.registerEntityRenderer(AntarchyNeoforgeEntites.GOLDEN_APPLE_COW.get(), context -> withParalyzedGeoLayer(new AppleCowRenderer(context)));
event.registerEntityRenderer(AntarchyNeoforgeEntites.ENCHANTED_GOLDEN_APPLE_COW.get(), context -> withParalyzedGeoLayer(new AppleCowRenderer(context)));
@@ -0,0 +1,117 @@
package com.craisinlord.antarchy.neoforge.client;
import com.craisinlord.antarchy.Antarchy;
import com.craisinlord.antarchy.content.AntarchySoundEvents;
import com.craisinlord.antarchy.content.entity.portal.DimensionalTearEntity;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.sounds.AbstractTickableSoundInstance;
import net.minecraft.sounds.SoundSource;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.client.event.ClientTickEvent;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@EventBusSubscriber(modid = Antarchy.MODID, value = Dist.CLIENT)
public final class TearIdleSoundHandler {
private static final double START_SCAN_RADIUS = 64.0D;
private static final int DISCOVERY_SCAN_INTERVAL_TICKS = 10;
private static final Map<UUID, TearIdleSound> ACTIVE_LOOPS = new HashMap<>();
private static long nextDiscoveryScanTick;
private TearIdleSoundHandler() {
}
@SubscribeEvent
public static void onClientTick(ClientTickEvent.Post event) {
Minecraft mc = Minecraft.getInstance();
if (mc.level == null || mc.player == null || mc.isPaused()) {
resetAll(mc);
return;
}
pruneStaleLoops(mc);
long gameTime = mc.level.getGameTime();
if (gameTime >= nextDiscoveryScanTick) {
nextDiscoveryScanTick = gameTime + DISCOVERY_SCAN_INTERVAL_TICKS;
discoverNearbyTears(mc);
}
}
private static void discoverNearbyTears(Minecraft mc) {
List<DimensionalTearEntity> tears = mc.level.getEntitiesOfClass(
DimensionalTearEntity.class,
mc.player.getBoundingBox().inflate(START_SCAN_RADIUS)
);
for (DimensionalTearEntity tear : tears) {
if (!tear.shouldPlayIdleSound() || ACTIVE_LOOPS.containsKey(tear.getUUID())) {
continue;
}
TearIdleSound sound = new TearIdleSound(tear);
ACTIVE_LOOPS.put(tear.getUUID(), sound);
mc.getSoundManager().play(sound);
}
}
private static void pruneStaleLoops(Minecraft mc) {
Iterator<Map.Entry<UUID, TearIdleSound>> iterator = ACTIVE_LOOPS.entrySet().iterator();
while (iterator.hasNext()) {
TearIdleSound sound = iterator.next().getValue();
if (!sound.isValid()) {
mc.getSoundManager().stop(sound);
iterator.remove();
}
}
}
private static void resetAll(Minecraft mc) {
for (TearIdleSound sound : ACTIVE_LOOPS.values()) {
mc.getSoundManager().stop(sound);
}
ACTIVE_LOOPS.clear();
nextDiscoveryScanTick = 0L;
}
private static final class TearIdleSound extends AbstractTickableSoundInstance {
private final DimensionalTearEntity tear;
private TearIdleSound(DimensionalTearEntity tear) {
super(AntarchySoundEvents.DIMENSIONAL_TEAR_IDLE.get(), SoundSource.HOSTILE, tear.getRandom());
this.tear = tear;
this.looping = true;
this.delay = 0;
this.volume = 0.6F;
this.pitch = 1.0F;
this.x = tear.getX();
this.y = tear.getY();
this.z = tear.getZ();
}
private boolean isValid() {
return !this.tear.isRemoved() && this.tear.shouldPlayIdleSound();
}
@Override
public void tick() {
if (!this.isValid()) {
this.stop();
return;
}
this.x = this.tear.getX();
this.y = this.tear.getY();
this.z = this.tear.getZ();
}
@Override
public boolean canStartSilent() {
return true;
}
}
}
@@ -32,6 +32,7 @@ import net.minecraft.core.registries.Registries;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.util.valueproviders.UniformInt;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.block.*;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockBehaviour;
@@ -43,6 +44,8 @@ import net.minecraft.world.level.block.state.properties.WoodType;
import net.minecraft.world.level.material.FlowingFluid;
import net.minecraft.world.level.material.FluidState;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.neoforge.common.ItemAbilities;
import net.neoforged.neoforge.common.ItemAbility;
import net.neoforged.neoforge.fluids.BaseFlowingFluid;
import net.neoforged.neoforge.registries.DeferredBlock;
import net.neoforged.neoforge.registries.DeferredHolder;
@@ -265,9 +268,25 @@ public final class AntarchyNeoforgeBlocks {
public static final DeferredBlock<WallHangingSignBlock> ROYAL_WALL_HANGING_SIGN = BLOCKS.register("royal_wall_hanging_sign",
() -> new WallHangingSignBlock(AntarchyWoodTypes.ROYAL, BlockBehaviour.Properties.ofFullCopy(Blocks.JUNGLE_WALL_HANGING_SIGN)));
public static final DeferredBlock<TruffaloLogBlock> TRUFFALO_LOG = BLOCKS.register("truffalo_log",
() -> new TruffaloLogBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.JUNGLE_LOG)));
() -> new TruffaloLogBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.JUNGLE_LOG)) {
@Override
public BlockState getToolModifiedState(BlockState state, UseOnContext context, ItemAbility itemAbility, boolean simulate) {
if (itemAbility == ItemAbilities.AXE_STRIP) {
return STRIPPED_TRUFFALO_LOG.get().withPropertiesOf(state);
}
return super.getToolModifiedState(state, context, itemAbility, simulate);
}
});
public static final DeferredBlock<RotatedPillarBlock> TRUFFALO_WOOD = BLOCKS.register("truffalo_wood",
() -> new RotatedPillarBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.JUNGLE_WOOD)));
() -> new RotatedPillarBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.JUNGLE_WOOD)) {
@Override
public BlockState getToolModifiedState(BlockState state, UseOnContext context, ItemAbility itemAbility, boolean simulate) {
if (itemAbility == ItemAbilities.AXE_STRIP) {
return STRIPPED_TRUFFALO_WOOD.get().withPropertiesOf(state);
}
return super.getToolModifiedState(state, context, itemAbility, simulate);
}
});
public static final DeferredBlock<TruffaloLogBlock> STRIPPED_TRUFFALO_LOG = BLOCKS.register("stripped_truffalo_log",
() -> new TruffaloLogBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.STRIPPED_JUNGLE_LOG)));
public static final DeferredBlock<RotatedPillarBlock> STRIPPED_TRUFFALO_WOOD = BLOCKS.register("stripped_truffalo_wood",
@@ -25,6 +25,13 @@ displayURL="https://www.curseforge.com/minecraft/mc-mods/antarchy"
type="required"
versionRange="[1.21.1,)"
[[dependencies.antarchy]]
modId="architectury"
type="required"
versionRange="[${architectury_api_version},)"
ordering="AFTER"
side="BOTH"
[[dependencies.antarchy]]
modId="antos"
type="required"