bumped required infinity version

fixed server client split issue fr this time
Buffed frying pan
Fixed prince princess anim bug
This commit is contained in:
craisinlord committed 2026-09-23 20:49:57 -05:00
1 parent 5010b6b7e1
commit 23599c4c59
52 files changed
+653 -62

No files matched your search

@@ -1,5 +1,6 @@
package com.craisinlord.antarchy;
import com.craisinlord.antarchy.content.computer.AntarchyArchiveLocators;
import com.craisinlord.antarchy.content.util.AttributeRangeInit;
import com.craisinlord.antarchy.content.worldgen.VillagePoolAdditions;
import com.craisinlord.integrated_api.events.lifecycle.ServerGoingToStartEvent;
@@ -15,6 +16,7 @@ public class Antarchy {
public static void init() {
AttributeRangeInit.apply();
AntarchyArchiveLocators.register();
ServerGoingToStartEvent.EVENT.addListener(Antarchy::serverAboutToStart);
}
private static void serverAboutToStart(final ServerGoingToStartEvent event) {
@@ -7,7 +7,7 @@ public final class InfinityCompatVersion {
private static final Pattern VERSION_PARTS = Pattern.compile("(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?");
private static final int REQUIRED_MAJOR = 2;
private static final int REQUIRED_MINOR = 7;
private static final int REQUIRED_PATCH = 2;
private static final int REQUIRED_PATCH = 3;
private InfinityCompatVersion() {
}
@@ -0,0 +1,82 @@
package com.craisinlord.antarchy.compat.infinity;
import com.craisinlord.antarchy.Antarchy;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public final class InfinityConfigRefresh {
private static final Map<String, Registry<?>> CHECKED_FILES = Map.of(
"mobs.json", BuiltInRegistries.ENTITY_TYPE,
"items.json", BuiltInRegistries.ITEM,
"effects.json", BuiltInRegistries.MOB_EFFECT
);
private InfinityConfigRefresh() {
}
public static void refreshIfStale(Path configDir) {
Path modularDir = configDir.resolve("infinity").resolve("modular");
Path invocationLock = modularDir.resolve("invocation.lock");
if (!Files.exists(invocationLock)) {
return;
}
Path antarchyDir = modularDir.resolve(Antarchy.MODID);
List<String> staleIds = new ArrayList<>();
CHECKED_FILES.forEach((fileName, registry) -> collectStaleIds(antarchyDir.resolve(fileName), registry, staleIds));
if (staleIds.isEmpty()) {
return;
}
try {
Files.delete(invocationLock);
Antarchy.LOGGER.info(
"[Antarchy] Infinite Dimensions config lists unregistered Antarchy content {}; its config will regenerate on next world join",
staleIds
);
} catch (Exception exception) {
Antarchy.LOGGER.warn("[Antarchy] Failed to reset stale Infinite Dimensions config at {}", invocationLock, exception);
}
}
private static void collectStaleIds(Path file, Registry<?> registry, List<String> staleIds) {
if (!Files.exists(file)) {
return;
}
try (Reader reader = Files.newBufferedReader(file, StandardCharsets.UTF_8)) {
JsonElement root = JsonParser.parseReader(reader);
if (!root.isJsonObject() || !root.getAsJsonObject().has("elements")) {
return;
}
for (JsonElement element : root.getAsJsonObject().getAsJsonArray("elements")) {
if (!element.isJsonObject()) {
continue;
}
JsonObject entry = element.getAsJsonObject();
if (!entry.has("key")) {
continue;
}
String key = entry.get("key").getAsString();
ResourceLocation id = ResourceLocation.tryParse(key);
if (id != null && Antarchy.MODID.equals(id.getNamespace()) && !registry.containsKey(id)) {
staleIds.add(key);
}
}
} catch (Exception exception) {
Antarchy.LOGGER.warn("[Antarchy] Failed to read Infinite Dimensions config {}", file, exception);
}
}
}
@@ -50,24 +50,10 @@ public final class QueenLocateCommand {
int originX = Mth.floor(source.getPosition().x);
int originZ = Mth.floor(source.getPosition().z);
int cellX = Math.floorDiv(originX, QueenTrailGrid.SPACING);
int cellZ = Math.floorDiv(originZ, QueenTrailGrid.SPACING);
List<QueenTrailGrid.Site> sites = new ArrayList<>();
for (int x = cellX - SEARCH_RADIUS_CELLS; x <= cellX + SEARCH_RADIUS_CELLS; x++) {
for (int z = cellZ - SEARCH_RADIUS_CELLS; z <= cellZ + SEARCH_RADIUS_CELLS; z++) {
sites.add(QueenTrailGrid.site(thoraxis.getSeed(), x, z));
}
}
sites.sort(Comparator.comparingDouble(site -> distanceSquared(originX, originZ, site)));
int checks = Math.min(MAX_SITE_CHECKS, sites.size());
for (int index = 0; index < checks; index++) {
QueenTrailGrid.Site site = sites.get(index);
thoraxis.getChunk(site.terminalX() >> 4, site.terminalZ() >> 4);
QueenTrailSpawnMarkerBlockEntity marker = findMarker(thoraxis, site);
if (marker == null) {
continue;
}
NearestSite nearest = findNearestSite(thoraxis, originX, originZ);
if (nearest != null) {
QueenTrailGrid.Site site = nearest.site();
QueenTrailSpawnMarkerBlockEntity marker = nearest.marker();
QueenEntity queen = marker.spawnNow(thoraxis);
if (queen == null && !marker.isConsumed()) {
source.sendFailure(Component.literal("A Queen spawn site was found, but the Queen could not spawn at a clear location. The site can be retried later."));
@@ -96,6 +82,33 @@ public final class QueenLocateCommand {
return 0;
}
/** Finds the nearest generated Queen spawn site without spawning her. Loads (and may generate) the checked chunks. */
public static NearestSite findNearestSite(ServerLevel thoraxis, int originX, int originZ) {
int cellX = Math.floorDiv(originX, QueenTrailGrid.SPACING);
int cellZ = Math.floorDiv(originZ, QueenTrailGrid.SPACING);
List<QueenTrailGrid.Site> sites = new ArrayList<>();
for (int x = cellX - SEARCH_RADIUS_CELLS; x <= cellX + SEARCH_RADIUS_CELLS; x++) {
for (int z = cellZ - SEARCH_RADIUS_CELLS; z <= cellZ + SEARCH_RADIUS_CELLS; z++) {
sites.add(QueenTrailGrid.site(thoraxis.getSeed(), x, z));
}
}
sites.sort(Comparator.comparingDouble(site -> distanceSquared(originX, originZ, site)));
int checks = Math.min(MAX_SITE_CHECKS, sites.size());
for (int index = 0; index < checks; index++) {
QueenTrailGrid.Site site = sites.get(index);
thoraxis.getChunk(site.terminalX() >> 4, site.terminalZ() >> 4);
QueenTrailSpawnMarkerBlockEntity marker = findMarker(thoraxis, site);
if (marker != null) {
return new NearestSite(site, marker);
}
}
return null;
}
public record NearestSite(QueenTrailGrid.Site site, QueenTrailSpawnMarkerBlockEntity marker) {
}
private static QueenTrailSpawnMarkerBlockEntity findMarker(ServerLevel level, QueenTrailGrid.Site site) {
BlockPos.MutableBlockPos cursor = new BlockPos.MutableBlockPos(site.terminalX(), level.getMinBuildHeight(), site.terminalZ());
for (int y = level.getMinBuildHeight(); y < level.getMaxBuildHeight(); y++) {
@@ -0,0 +1,32 @@
package com.craisinlord.antarchy.content.computer;
import com.craisinlord.antarchy.Antarchy;
import com.craisinlord.antarchy.content.command.QueenLocateCommand;
import com.craisinlord.antarchy.content.worldgen.elythia.KingsTreeGrid;
import com.craisinlord.antos.api.archive.ArchiveLocatorRegistry;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.levelgen.Heightmap;
/** Archive coordinate lookups for royals that live on grids rather than in vanilla structures. */
public final class AntarchyArchiveLocators {
private AntarchyArchiveLocators() {
}
public static void register() {
ArchiveLocatorRegistry.register(id("queen"), (level, origin) -> {
QueenLocateCommand.NearestSite nearest = QueenLocateCommand.findNearestSite(level, origin.getX(), origin.getZ());
return nearest == null ? null : nearest.marker().getSpawnPos();
});
ArchiveLocatorRegistry.register(id("kings_tree"), (level, origin) -> {
BlockPos center = KingsTreeGrid.nearestTreeCenter(origin);
int surfaceY = level.getChunkSource().getGenerator().getBaseHeight(center.getX(), center.getZ(),
Heightmap.Types.WORLD_SURFACE_WG, level, level.getChunkSource().randomState());
return new BlockPos(center.getX(), surfaceY, center.getZ());
});
}
private static ResourceLocation id(String path) {
return ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, path);
}
}
@@ -646,7 +646,7 @@ public final class CreativeTabContents {
acceptPotionFamily(output, potionPath);
}
for (String diskId : List.of("antarchy:introduction", "antarchy:toreterror_arena", "antarchy:high_fructose_corn_syrup",
"antarchy:elythia", "antarchy:flying_squirrel", "antarchy:brutalfly", "antarchy:rainbow_ant", "antarchy:cavaryn", "antarchy:hercules_beetle", "antarchy:thoraxis", "antarchy:temporal_fields", "antarchy:bloodglass", "antarchy:vortex")) {
"antarchy:elythia", "antarchy:flying_squirrel", "antarchy:brutalfly", "antarchy:rainbow_ant", "antarchy:kraken", "antarchy:cavaryn", "antarchy:hercules_beetle", "antarchy:thoraxis", "antarchy:temporal_fields", "antarchy:bloodglass", "antarchy:vortex")) {
ItemStack disk = new ItemStack(com.craisinlord.antos.content.AntOSObjects.FLOPPY_DISK.get());
disk.set(com.craisinlord.antos.content.AntOSObjects.FLOPPY_DISK_COMPONENT.get(), ResourceLocation.parse(diskId));
output.accept(disk);
@@ -26,7 +26,7 @@ public final class ComputerScientistTradeManager extends SimpleJsonResourceReloa
private static final String DIRECTORY = "computer_scientist_trades";
private static final List<ResourceLocation> GENERAL_DISKS = List.of(
id("introduction"), id("high_fructose_corn_syrup"),
id("elythia"), id("flying_squirrel"), id("rainbow_ant"), id("cavaryn"), id("thoraxis"),
id("elythia"), id("flying_squirrel"), id("rainbow_ant"), id("kraken"), id("cavaryn"), id("thoraxis"),
id("temporal_fields"), id("bloodglass"), id("vortex"));
private static volatile List<TradeEntry> loadedTrades = List.of();
@@ -31,7 +31,6 @@ import net.minecraft.world.entity.SlotAccess;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.inventory.ClickAction;
import net.minecraft.world.inventory.Slot;
import com.craisinlord.antarchy.Antarchy;
import com.craisinlord.antarchy.content.menu.GiantFryingPanMenu;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.EquipmentSlot;
@@ -133,14 +132,11 @@ public class GiantFryingPanItem extends SwordItem implements GeoItem {
ItemStack pan = player.getItemInHand(hand);
InteractionHand foodHand = hand == InteractionHand.MAIN_HAND ? InteractionHand.OFF_HAND : InteractionHand.MAIN_HAND;
ItemStack food = player.getItemInHand(foodHand);
Antarchy.LOGGER.info("[FryingPan] use client={} hand={} shift={} pan={} otherHand={}",
level.isClientSide, hand, player.isShiftKeyDown(), pan, food);
if (player.isShiftKeyDown()) {
openMenu(level, player, hand);
return InteractionResultHolder.sidedSuccess(pan, level.isClientSide);
}
if (!GiantFryingPanStorage.isCampfireInput(player, food)) {
Antarchy.LOGGER.info("[FryingPan] use client={} other hand item is not a campfire input", level.isClientSide);
return InteractionResultHolder.pass(pan);
}
return insertFromHand(level, player, pan, food)
@@ -154,19 +150,25 @@ public class GiantFryingPanItem extends SwordItem implements GeoItem {
ItemStack held = player.getMainHandItem();
if (!(pan.getItem() instanceof GiantFryingPanItem) || held.getItem() instanceof GiantFryingPanItem) return InteractionResult.PASS;
if (player.isShiftKeyDown()) {
Antarchy.LOGGER.info("[FryingPan] offhand pan shift-use client={} mainHand={}", level.isClientSide, held);
openMenu(level, player, InteractionHand.OFF_HAND);
return InteractionResult.sidedSuccess(level.isClientSide);
}
if (!GiantFryingPanStorage.isCampfireInput(player, held)) return InteractionResult.PASS;
Antarchy.LOGGER.info("[FryingPan] offhand pan insert client={} mainHand={}", level.isClientSide, held);
return insertFromHand(level, player, pan, held) ? InteractionResult.sidedSuccess(level.isClientSide) : InteractionResult.FAIL;
}
public static void openHeldMenu(Player player) {
if (!player.isShiftKeyDown()) return;
if (player.getMainHandItem().getItem() instanceof GiantFryingPanItem) {
openMenu(player.level(), player, InteractionHand.MAIN_HAND);
} else if (player.getOffhandItem().getItem() instanceof GiantFryingPanItem) {
openMenu(player.level(), player, InteractionHand.OFF_HAND);
}
}
private static void openMenu(Level level, Player player, InteractionHand hand) {
if (level.isClientSide) return;
if (level.isClientSide || player.containerMenu instanceof GiantFryingPanMenu) return;
int panSlot = hand == InteractionHand.MAIN_HAND ? player.getInventory().selected : Inventory.SLOT_OFFHAND;
Antarchy.LOGGER.info("[FryingPan] opening menu for {} panSlot={}", player.getName().getString(), panSlot);
player.openMenu(new SimpleMenuProvider(
(containerId, inventory, ignored) -> new GiantFryingPanMenu(containerId, inventory, panSlot),
Component.translatable("item.antarchy.giant_frying_pan")));
@@ -176,11 +178,9 @@ public class GiantFryingPanItem extends SwordItem implements GeoItem {
GiantFryingPanStorage storage = new GiantFryingPanStorage(pan, player);
ItemStack single = food.copyWithCount(1);
if (!storage.insertOne(single)) {
Antarchy.LOGGER.info("[FryingPan] insert failed client={} food={} (pan full or not cookable)", level.isClientSide, food);
return false;
}
if (!player.getAbilities().instabuild) food.shrink(1);
Antarchy.LOGGER.info("[FryingPan] inserted client={} food={}", level.isClientSide, single.getItem());
if (!level.isClientSide) {
level.playSound(null, player.blockPosition(), SoundEvents.CAMPFIRE_CRACKLE, SoundSource.PLAYERS, 0.8F, 1.0F);
}
@@ -194,7 +194,6 @@ public class GiantFryingPanItem extends SwordItem implements GeoItem {
if (!GiantFryingPanStorage.isCampfireInput(player, food) || !slot.mayPickup(player)) return false;
GiantFryingPanStorage storage = new GiantFryingPanStorage(pan, player);
boolean inserted = storage.hasSpace(food) && storage.insertOne(slot.safeTake(1, 1, player));
Antarchy.LOGGER.info("[FryingPan] cursor pan onto slot client={} food={} inserted={}", player.level().isClientSide, food.getItem(), inserted);
if (inserted) player.playSound(SoundEvents.CAMPFIRE_CRACKLE, 0.8F, 1.0F);
return true;
}
@@ -210,7 +209,6 @@ public class GiantFryingPanItem extends SwordItem implements GeoItem {
other.shrink(1);
player.playSound(SoundEvents.CAMPFIRE_CRACKLE, 0.8F, 1.0F);
}
Antarchy.LOGGER.info("[FryingPan] cursor food onto pan client={} food={} inserted={}", player.level().isClientSide, single.getItem(), inserted);
return true;
}
@@ -1,6 +1,5 @@
package com.craisinlord.antarchy.content.menu;
import com.craisinlord.antarchy.Antarchy;
import com.craisinlord.antarchy.content.AntarchyObjects;
import com.craisinlord.antarchy.content.item.GiantFryingPanStorage;
import net.minecraft.world.entity.player.Inventory;
@@ -26,8 +25,6 @@ public final class GiantFryingPanMenu extends AbstractContainerMenu {
Player player = inventory.player;
this.panSlot = panSlot;
this.panStorage = new GiantFryingPanStorage(player, panSlot);
Antarchy.LOGGER.info("[FryingPan] Menu created client={} containerId={} panSlot={} pan={}",
player.level().isClientSide, containerId, panSlot, this.panStorage.pan());
for (int slot = 0; slot < GiantFryingPanStorage.SLOT_COUNT; slot++) {
this.addSlot(new Slot(this.panStorage, slot, 8 + slot * 18, PAN_ROW_Y) {
@Override
@@ -0,0 +1,19 @@
package com.craisinlord.antarchy.content.network;
import com.craisinlord.antarchy.Antarchy;
import io.netty.buffer.ByteBuf;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
public record OpenGiantFryingPanPayload() implements CustomPacketPayload {
public static final OpenGiantFryingPanPayload INSTANCE = new OpenGiantFryingPanPayload();
public static final Type<OpenGiantFryingPanPayload> TYPE =
new Type<>(ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "open_giant_frying_pan"));
public static final StreamCodec<ByteBuf, OpenGiantFryingPanPayload> STREAM_CODEC = StreamCodec.unit(INSTANCE);
@Override
public Type<OpenGiantFryingPanPayload> type() {
return TYPE;
}
}
@@ -17,6 +17,7 @@ import net.minecraft.util.Mth;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.block.LeavesBlock;
import net.minecraft.world.level.block.RotatedPillarBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.feature.Feature;
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
@@ -105,7 +106,7 @@ public class RoyalTreeFeature extends Feature<RoyalTreeConfiguration> {
if (s % 2 == 0) {
cursor = cursor.above();
}
placeLog(level, random, config, cursor, logs);
placeLog(level, random, config, cursor, logs, branchDir.getAxis());
}
int padRadius = 2 + random.nextInt(3);
placeCanopy(level, random, config, cursor.above(), padRadius, Math.max(2, padRadius - 1), 1, 0, leaves);
@@ -188,10 +189,18 @@ public class RoyalTreeFeature extends Feature<RoyalTreeConfiguration> {
}
private void placeLog(WorldGenLevel level, RandomSource random, RoyalTreeConfiguration config, BlockPos pos, Set<BlockPos> logs) {
placeLog(level, random, config, pos, logs, Direction.Axis.Y);
}
private void placeLog(WorldGenLevel level, RandomSource random, RoyalTreeConfiguration config, BlockPos pos, Set<BlockPos> logs, Direction.Axis axis) {
if (!canReplace(level, pos)) {
return;
}
setBlock(level, pos, config.trunkProvider().getState(random, pos));
BlockState state = config.trunkProvider().getState(random, pos);
if (state.hasProperty(RotatedPillarBlock.AXIS)) {
state = state.setValue(RotatedPillarBlock.AXIS, axis);
}
setBlock(level, pos, state);
logs.add(pos.immutable());
}
@@ -37,6 +37,10 @@ public final class AntarchyMixinPlugin implements IMixinConfigPlugin {
if (mixinClassName.startsWith("com.craisinlord.antarchy.mixins.compat.ars_nouveau.")) {
return classPresent("com.hollingsworth.arsnouveau.common.entity.EntityProjectileSpell");
}
if (mixinClassName.startsWith("com.craisinlord.antarchy.mixins.compat.biolith.")) {
return classPresent("com.terraformersmc.biolith.api.biome.BiolithFittestNodes")
&& classPresent("com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod");
}
if (mixinClassName.startsWith("com.craisinlord.antarchy.mixins.compat.alexscaves.")) {
// The target class was found above. Checking the target itself avoids depending on
// whether a loader exposes Alex's Caves' entrypoint resource to this classloader.
@@ -0,0 +1,37 @@
package com.craisinlord.antarchy.mixins.compat.biolith;
import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import net.minecraft.core.Holder;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.Climate;
import net.minecraft.world.level.biome.MultiNoiseBiomeSource;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(MultiNoiseBiomeSource.class)
public abstract class MultiNoiseBiomeSourceNullGuardMixin {
@Shadow
protected abstract Climate.ParameterList<Holder<Biome>> parameters();
@WrapMethod(method = "getNoiseBiome(IIILnet/minecraft/world/level/biome/Climate$Sampler;)Lnet/minecraft/core/Holder;")
private Holder<Biome> antarchy$neverReturnNullBiome(int x, int y, int z, Climate.Sampler sampler, Operation<Holder<Biome>> original) {
Holder<Biome> biome = original.call(x, y, z, sampler);
if (biome != null) {
return biome;
}
Climate.ParameterList<Holder<Biome>> parameters = this.parameters();
biome = parameters.findValue(sampler.sample(x, y, z));
if (biome != null) {
return biome;
}
for (var entry : parameters.values()) {
if (entry.getSecond() != null) {
return entry.getSecond();
}
}
return null;
}
}