diff --git a/build.gradle b/build.gradle index 3aa40f66e..787f881c9 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ import net.fabricmc.loom.task.RemapJarTask plugins { - id 'fabric-loom' version '1.5.7' + id 'fabric-loom' version '1.6.3' // This dependency is only used to determine the state of the Git working tree so that build artifacts can be // more easily identified. TODO: Lazily load GrGit via a service only when builds are performed. @@ -94,7 +94,7 @@ dependencies { mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" - modImplementation 'com.github.2No2Name:McTester:v0.4.0' + //modImplementation 'com.github.2No2Name:McTester:v0.4.0' //TODO update mctester Set fabricApiModulesCompileOnly = [ "fabric-transfer-api-v1" diff --git a/gradle.properties b/gradle.properties index 0d8e2e057..57d689727 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,12 +2,11 @@ org.gradle.jvmargs=-Xmx3G # Fabric Properties # check these on https://modmuss50.me/fabric.html - -minecraft_version=1.20.4 -yarn_mappings=1.20.4+build.1 -loader_version=0.15.1 +minecraft_version=1.20.5-pre1 +yarn_mappings=1.20.5-pre1+build.5 +loader_version=0.15.9 #Fabric api -fabric_version=0.91.2+1.20.4 +fabric_version=0.96.15+1.20.5 # Mod Properties mod_version=0.12.1 maven_group=me.jellysquid.mods diff --git a/lithium-mixin-config.md b/lithium-mixin-config.md index fd1b638dc..a6f3f4fa1 100644 --- a/lithium-mixin-config.md +++ b/lithium-mixin-config.md @@ -20,22 +20,6 @@ mixin.gen.biome_noise_cache=false (default: `true`) Mob AI optimizations -### `mixin.ai.nearby_entity_tracking` -(default: `false`) -Event-based system for tracking nearby entities. - -Requirements: -- `mixin.util.entity_section_position=true` -- `mixin.util.accessors=true` - -### `mixin.ai.nearby_entity_tracking.goals` -(default: `true`) -A number of AI goals which query for nearby entities in the world every tick will use the event-based -system for tracking nearby entities. In other words, instead of entities constantly polling to see if -other entities are nearby, they will instead be notified only occasionally when such an entity enters -their range. - - ### `mixin.ai.pathing` (default: `true`) A faster code path is used for determining what kind of path-finding node type is associated with a @@ -141,10 +125,6 @@ NBT tags use a fastutil hashmap instead of a standard HashMap (default: `true`) Optimizations related to blocks -### `mixin.block.beehive` -(default: `true`) -Beehives check if they are obstructed before performing expensive nbt copy operations for each exit attempt. - ### `mixin.block.flatten_states` (default: `true`) FluidStates store directly whether they are empty @@ -280,18 +260,6 @@ In chunks with many mobs in ladders a separate list of pushable entities for cra Requirements: - `mixin.chunk.entity_class_groups=true` -### `mixin.entity.data_tracker` -(default: `true`) -Various entity data tracker optimizations - -### `mixin.entity.data_tracker.no_locks` -(default: `true`) -Remove unnecessary locking when accessing the data tracker - -### `mixin.entity.data_tracker.use_arrays` -(default: `true`) -Data trackers use a custom optimized entry map - ### `mixin.entity.fast_elytra_check` (default: `true`) Skip repeatedly writing to the data tracker that an entity is not flying @@ -308,10 +276,6 @@ Skip checking whether an entity is inside powder snow for movement speed slowdow (default: `true`) Access entities faster when accessing a relatively small number of entity sections -### `mixin.entity.hopper_minecart` -(default: `true`) -Hopper minecarts search for item entities faster by combining multiple item entity searches. Also eliminates duplicated item entity pickup attempts - ### `mixin.entity.inactive_navigations` (default: `true`) Block updates skip notifying mobs that won't react to the block update anyways diff --git a/src/main/java/me/jellysquid/mods/lithium/common/ai/pathing/PathNodeCache.java b/src/main/java/me/jellysquid/mods/lithium/common/ai/pathing/PathNodeCache.java index d58873c73..e006161fb 100644 --- a/src/main/java/me/jellysquid/mods/lithium/common/ai/pathing/PathNodeCache.java +++ b/src/main/java/me/jellysquid/mods/lithium/common/ai/pathing/PathNodeCache.java @@ -5,9 +5,11 @@ import me.jellysquid.mods.lithium.common.util.Pos; import me.jellysquid.mods.lithium.common.world.ChunkView; import me.jellysquid.mods.lithium.common.world.WorldHelper; +import me.jellysquid.mods.lithium.mixin.ai.pathing.PathContextAccessor; import net.minecraft.block.AbstractBlock; import net.minecraft.block.BlockState; import net.minecraft.entity.ai.pathing.LandPathNodeMaker; +import net.minecraft.entity.ai.pathing.PathContext; import net.minecraft.entity.ai.pathing.PathNodeType; import net.minecraft.util.math.BlockPos; import net.minecraft.world.BlockView; @@ -29,7 +31,7 @@ public static PathNodeType getNeighborPathNodeType(AbstractBlock.AbstractBlockSt } /** - * Returns whether or not a chunk section is free of dangers. This makes use of a caching layer to greatly + * Returns whether a chunk section is free of dangers. This makes use of a caching layer to greatly * accelerate neighbor danger checks when path-finding. * * @param section The chunk section to test for dangers @@ -49,22 +51,20 @@ public static boolean isSectionSafeAsNeighbor(ChunkSection section) { } - public static PathNodeType getNodeTypeFromNeighbors(BlockView world, BlockPos.Mutable pos, PathNodeType type) { - int x = pos.getX(); - int y = pos.getY(); - int z = pos.getZ(); + public static PathNodeType getNodeTypeFromNeighbors(PathContext context, int x, int y, int z, PathNodeType fallback) { + BlockView world = context.getWorld(); ChunkSection section = null; // Check that all the block's neighbors are within the same chunk column. If so, we can isolate all our block // reads to just one chunk and avoid hits against the server chunk manager. - if (world instanceof ChunkView chunkView && WorldHelper.areNeighborsWithinSameChunkSection(pos)) { + if (world instanceof ChunkView chunkView && WorldHelper.areNeighborsWithinSameChunkSection(x, y, z)) { // If the y-coordinate is within bounds, we can cache the chunk section. Otherwise, the if statement to check // if the cached chunk section was initialized will early-exit. if (!world.isOutOfHeightLimit(y)) { Chunk chunk = chunkView.lithium$getLoadedChunk(Pos.ChunkCoord.fromBlockCoord(x), Pos.ChunkCoord.fromBlockCoord(z)); - // If the chunk is absent, the cached section above will remain null, as there is no chunk section anyways. + // If the chunk is absent, the cached section above will remain null, as there is no chunk section anyway. // An empty chunk or section will never pose any danger sources, which will be caught later. if (chunk != null) { section = chunk.getSectionArray()[Pos.SectionYIndex.fromBlockCoord(world, y)]; @@ -75,7 +75,7 @@ public static PathNodeType getNodeTypeFromNeighbors(BlockView world, BlockPos.Mu // section is empty or contains any dangerous blocks within the palette. If not, we can assume any checks // against this chunk section will always fail, allowing us to fast-exit. if (section == null || PathNodeCache.isSectionSafeAsNeighbor(section)) { - return type; + return fallback; } } @@ -103,19 +103,19 @@ public static PathNodeType getNodeTypeFromNeighbors(BlockView world, BlockPos.Mu if (section != null) { state = section.getBlockState(adjX & 15, adjY & 15, adjZ & 15); } else { - state = world.getBlockState(pos.set(adjX, adjY, adjZ)); + BlockPos.Mutable pos = ((PathContextAccessor) context).getLastNodePos().set(adjX, adjY, adjZ); + state = world.getBlockState(pos); } - // Ensure that the block isn't air first to avoid expensive hash table accesses if (state.isAir()) { continue; } PathNodeType neighborType = PathNodeCache.getNeighborPathNodeType(state); - if (neighborType == null) { //Here null means that no path node type is cached (uninitalized or dynamic) + if (neighborType == null) { //Here null means that no path node type is cached (uninitialized or dynamic) //Passing null as previous node type to the method signals to other lithium mixins that we only want the neighbor behavior of this block and not its neighbors - neighborType = LandPathNodeMaker.getNodeTypeFromNeighbors(world, pos, null); + neighborType = LandPathNodeMaker.getNodeTypeFromNeighbors(context, adjX, adjY, adjZ, null); //Here null means that the path node type is not changed by the block! if (neighborType == null) { neighborType = PathNodeType.OPEN; @@ -128,7 +128,7 @@ public static PathNodeType getNodeTypeFromNeighbors(BlockView world, BlockPos.Mu } } - return type; + return fallback; } } diff --git a/src/main/java/me/jellysquid/mods/lithium/common/ai/raid/OminousBannerCache.java b/src/main/java/me/jellysquid/mods/lithium/common/ai/raid/OminousBannerCache.java new file mode 100644 index 000000000..ed9fadcf0 --- /dev/null +++ b/src/main/java/me/jellysquid/mods/lithium/common/ai/raid/OminousBannerCache.java @@ -0,0 +1,7 @@ +package me.jellysquid.mods.lithium.common.ai.raid; + +import net.minecraft.item.ItemStack; + +public interface OminousBannerCache { + ItemStack lithium$getCachedOminousBanner(); +} diff --git a/src/main/java/me/jellysquid/mods/lithium/common/entity/movement_tracker/SectionedItemEntityMovementTracker.java b/src/main/java/me/jellysquid/mods/lithium/common/entity/movement_tracker/SectionedItemEntityMovementTracker.java index 2422de98c..02fae09e9 100644 --- a/src/main/java/me/jellysquid/mods/lithium/common/entity/movement_tracker/SectionedItemEntityMovementTracker.java +++ b/src/main/java/me/jellysquid/mods/lithium/common/entity/movement_tracker/SectionedItemEntityMovementTracker.java @@ -1,6 +1,5 @@ package me.jellysquid.mods.lithium.common.entity.movement_tracker; -import me.jellysquid.mods.lithium.common.util.collections.BucketedList; import me.jellysquid.mods.lithium.common.util.tuples.WorldSectionBox; import me.jellysquid.mods.lithium.mixin.block.hopper.EntityTrackingSectionAccessor; import me.jellysquid.mods.lithium.mixin.util.entity_movement_tracking.ServerEntityManagerAccessor; @@ -10,6 +9,7 @@ import net.minecraft.util.collection.TypeFilterableList; import net.minecraft.util.math.Box; +import java.util.ArrayList; import java.util.List; public class SectionedItemEntityMovementTracker extends SectionedEntityMovementTracker { @@ -18,10 +18,10 @@ public SectionedItemEntityMovementTracker(WorldSectionBox worldSectionBox, Class super(worldSectionBox, clazz); } - public static SectionedItemEntityMovementTracker registerAt(ServerWorld world, Box encompassingBox, Class clazz) { + public static SectionedItemEntityMovementTracker registerAt(ServerWorld world, Box interactionArea, Class clazz) { MovementTrackerCache cache = (MovementTrackerCache) ((ServerEntityManagerAccessor) ((ServerWorldAccessor) world).getEntityManager()).getCache(); - WorldSectionBox worldSectionBox = WorldSectionBox.entityAccessBox(world, encompassingBox); + WorldSectionBox worldSectionBox = WorldSectionBox.entityAccessBox(world, interactionArea); SectionedItemEntityMovementTracker tracker = new SectionedItemEntityMovementTracker<>(worldSectionBox, clazz); tracker = cache.lithium$deduplicate(tracker); @@ -29,10 +29,8 @@ public static SectionedItemEntityMovementTracker registerA return tracker; } - public List getEntities(Box[] areas) { - int numBoxes = areas.length - 1; - BucketedList entities = new BucketedList<>(numBoxes); - Box encompassingBox = areas[numBoxes]; + public List getEntities(Box interactionArea) { + ArrayList entities = new ArrayList<>(); for (int sectionIndex = 0; sectionIndex < this.sortedSections.size(); sectionIndex++) { if (this.sectionVisible[sectionIndex]) { //noinspection unchecked @@ -41,16 +39,8 @@ public List getEntities(Box[] areas) { for (S entity : collection.getAllOfType(this.clazz)) { if (entity.isAlive()) { Box entityBoundingBox = entity.getBoundingBox(); - //even though there are usually only two boxes to check, checking the encompassing box only will be faster in most cases - //In vanilla the number of boxes checked is always 2. Here it is 1 (miss) and 2-3 (hit) - if (entityBoundingBox.intersects(encompassingBox)) { - for (int j = 0; j < numBoxes; j++) { - if (entityBoundingBox.intersects(areas[j])) { - entities.addToBucket(j, entity); - //Only add each entity once. A hopper cannot pick up from the entity twice anyways. - break; - } - } + if (entityBoundingBox.intersects(interactionArea)) { + entities.add(entity); } } } diff --git a/src/main/java/me/jellysquid/mods/lithium/common/entity/nearby_tracker/NearbyEntityListenerMulti.java b/src/main/java/me/jellysquid/mods/lithium/common/entity/nearby_tracker/NearbyEntityListenerMulti.java index caaf44cb1..14191acd4 100644 --- a/src/main/java/me/jellysquid/mods/lithium/common/entity/nearby_tracker/NearbyEntityListenerMulti.java +++ b/src/main/java/me/jellysquid/mods/lithium/common/entity/nearby_tracker/NearbyEntityListenerMulti.java @@ -39,7 +39,7 @@ private void updateRange(NearbyEn this.range = updatedRange; //noinspection unchecked - SectionedEntityCache entityCache = ((ServerEntityManagerAccessor)((ServerWorldAccessor)tracker.getEntity().getWorld()).getEntityManager()).getCache(); + SectionedEntityCache entityCache = ((ServerEntityManagerAccessor) ((ServerWorldAccessor) tracker.getEntity().getWorld()).getEntityManager()).getCache(); ChunkSectionPos chunkPos = ChunkSectionPos.from(tracker.getEntity().getBlockPos()); this.updateChunkRegistrations(entityCache, chunkPos, this.range, chunkPos, updatedRange); diff --git a/src/main/java/me/jellysquid/mods/lithium/common/hopper/HopperHelper.java b/src/main/java/me/jellysquid/mods/lithium/common/hopper/HopperHelper.java index 04d5a15f9..c2cedd1c5 100644 --- a/src/main/java/me/jellysquid/mods/lithium/common/hopper/HopperHelper.java +++ b/src/main/java/me/jellysquid/mods/lithium/common/hopper/HopperHelper.java @@ -1,65 +1,17 @@ package me.jellysquid.mods.lithium.common.hopper; -import net.minecraft.block.Block; -import net.minecraft.block.BlockState; -import net.minecraft.block.ChestBlock; -import net.minecraft.block.InventoryProvider; -import net.minecraft.block.entity.*; +import net.minecraft.block.entity.HopperBlockEntity; +import net.minecraft.block.entity.LootableContainerBlockEntity; import net.minecraft.inventory.DoubleInventory; import net.minecraft.inventory.Inventory; import net.minecraft.inventory.SidedInventory; import net.minecraft.item.ItemStack; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Box; import net.minecraft.util.math.Direction; import net.minecraft.util.math.MathHelper; -import net.minecraft.util.shape.VoxelShape; -import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; -import java.util.Objects; - public class HopperHelper { - private static final VoxelShape CACHED_INPUT_VOLUME = Hopper.INPUT_AREA_SHAPE; - private static final Box[] CACHED_INPUT_VOLUME_BOXES = CACHED_INPUT_VOLUME.getBoundingBoxes().toArray(new Box[0]); - - public static Box[] getHopperPickupVolumeBoxes(Hopper hopper) { - VoxelShape inputAreaShape = hopper.getInputAreaShape(); - if (inputAreaShape == CACHED_INPUT_VOLUME) { - return CACHED_INPUT_VOLUME_BOXES; - } - return inputAreaShape.getBoundingBoxes().toArray(new Box[0]); - } - - /** - * Gets the block inventory at the given position, exactly like vanilla gets it. - * Needed because we don't want to search for entity inventories like the vanilla method does. - * - * @param world world we are searching in - * @param blockPos position of the block inventory - * @return the block inventory at the given position - */ - @Nullable - public static Inventory vanillaGetBlockInventory(World world, BlockPos blockPos) { - //[VanillaCopy] - Inventory inventory = null; - BlockState blockState = world.getBlockState(blockPos); - Block block = blockState.getBlock(); - if (block instanceof InventoryProvider) { - inventory = ((InventoryProvider)block).getInventory(blockState, world, blockPos); - } else if (blockState.hasBlockEntity()) { - BlockEntity blockEntity = world.getBlockEntity(blockPos); - if (blockEntity instanceof Inventory) { - inventory = (Inventory)blockEntity; - if (inventory instanceof ChestBlockEntity && block instanceof ChestBlock) { - inventory = ChestBlock.getInventory((ChestBlock)block, blockState, world, blockPos, true); - } - } - } - return inventory; - } - public static boolean tryMoveSingleItem(Inventory to, ItemStack stack, @Nullable Direction fromDirection) { SidedInventory toSided = to instanceof SidedInventory ? ((SidedInventory) to) : null; if (toSided != null && fromDirection != null) { @@ -83,14 +35,14 @@ public static boolean tryMoveSingleItem(Inventory to, ItemStack stack, @Nullable public static boolean tryMoveSingleItem(Inventory to, @Nullable SidedInventory toSided, ItemStack transferStack, int targetSlot, @Nullable Direction fromDirection) { ItemStack toStack = to.getStack(targetSlot); - //Assumption: no mods depend on the the stack size of transferStack in isValid or canInsert, like vanilla doesn't + //Assumption: no mods depend on the stack size of transferStack in isValid or canInsert, like vanilla doesn't if (to.isValid(targetSlot, transferStack) && (toSided == null || toSided.canInsert(targetSlot, transferStack, fromDirection))) { int toCount; if (toStack.isEmpty()) { ItemStack singleItem = transferStack.split(1); to.setStack(targetSlot, singleItem); return true; //caller needs to call to.markDirty() - } else if (toStack.isOf(transferStack.getItem()) && toStack.getMaxCount() > (toCount = toStack.getCount()) && to.getMaxCountPerStack() > toCount && areNbtEqual(toStack, transferStack)) { + } else if (toStack.getMaxCount() > (toCount = toStack.getCount()) && to.getMaxCountPerStack() > toCount && ItemStack.areItemsAndComponentsEqual(toStack, transferStack)) { transferStack.decrement(1); toStack.increment(1); return true; //caller needs to call to.markDirty() @@ -99,12 +51,8 @@ public static boolean tryMoveSingleItem(Inventory to, @Nullable SidedInventory t return false; } - private static boolean areNbtEqual(ItemStack stack1, ItemStack stack2) { - return Objects.equals(stack1.getNbt(), stack2.getNbt()); - } - private static int calculateReducedSignalStrength(float contentWeight, int inventorySize, int inventoryMaxCountPerStack, int numOccupiedSlots, int itemStackCount, int itemStackMaxCount) { - //contentWeight adaption can include rounding error for non power of 2 max stack sizes, which do not exist in vanilla anyways + //contentWeight adaption can include rounding error for non-power of 2 max stack sizes, which do not exist in vanilla anyways int maxStackSize = Math.min(inventoryMaxCountPerStack, itemStackMaxCount); int newNumOccupiedSlots = numOccupiedSlots - (itemStackCount == 1 ? 1 : 0); float newContentWeight = contentWeight - (1f / (float) maxStackSize); diff --git a/src/main/java/me/jellysquid/mods/lithium/common/world/ItemEntityHelper.java b/src/main/java/me/jellysquid/mods/lithium/common/world/ItemEntityHelper.java index 486823646..f39add209 100644 --- a/src/main/java/me/jellysquid/mods/lithium/common/world/ItemEntityHelper.java +++ b/src/main/java/me/jellysquid/mods/lithium/common/world/ItemEntityHelper.java @@ -2,47 +2,19 @@ import me.jellysquid.mods.lithium.common.entity.TypeFilterableListInternalAccess; import me.jellysquid.mods.lithium.common.entity.item.ItemEntityCategorizingList; -import me.jellysquid.mods.lithium.common.hopper.HopperHelper; -import me.jellysquid.mods.lithium.common.util.collections.BucketedList; import me.jellysquid.mods.lithium.mixin.util.accessors.EntityTrackingSectionAccessor; -import net.minecraft.block.entity.Hopper; import net.minecraft.entity.Entity; import net.minecraft.entity.ItemEntity; import net.minecraft.util.collection.TypeFilterableList; import net.minecraft.util.function.LazyIterationConsumer; import net.minecraft.util.math.Box; import net.minecraft.world.entity.SectionedEntityCache; -import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; public class ItemEntityHelper { - @NotNull - public static BucketedList getItemEntityBucketedList(Hopper hopper, double xOffset, double yOffset, double zOffset, List nearbyEntities) { - Box[] boundingBoxes = HopperHelper.getHopperPickupVolumeBoxes(hopper); - int numBoxes = boundingBoxes.length; - Box[] offsetBoundingBoxes = new Box[numBoxes]; - for (int i = 0; i < numBoxes; i++) { - offsetBoundingBoxes[i] = boundingBoxes[i].offset(xOffset, yOffset, zOffset); - } - - BucketedList entities = new BucketedList<>(numBoxes); - - for (ItemEntity itemEntity : nearbyEntities) { - Box entityBoundingBox = itemEntity.getBoundingBox(); - for (int j = 0; j < numBoxes; j++) { - if (entityBoundingBox.intersects(offsetBoundingBoxes[j])) { - entities.addToBucket(j, itemEntity); - //Only add each entity once. A hopper cannot pick up from the entity twice anyway. - break; - } - } - } - return entities; - } - public static void consumeItemEntitiesForMerge(SectionedEntityCache cache, ItemEntity searchingItemEntity, Box box, LazyIterationConsumer itemEntityConsumer) { cache.forEachInBox(box, section -> { //noinspection unchecked diff --git a/src/main/java/me/jellysquid/mods/lithium/common/world/WorldHelper.java b/src/main/java/me/jellysquid/mods/lithium/common/world/WorldHelper.java index 9b12cf710..3b48b031c 100644 --- a/src/main/java/me/jellysquid/mods/lithium/common/world/WorldHelper.java +++ b/src/main/java/me/jellysquid/mods/lithium/common/world/WorldHelper.java @@ -96,10 +96,10 @@ public static boolean areNeighborsWithinSameChunk(BlockPos pos) { return localX > 0 && localZ > 0 && localX < 15 && localZ < 15; } - public static boolean areNeighborsWithinSameChunkSection(BlockPos pos) { - int localX = pos.getX() & 15; - int localY = pos.getY() & 15; - int localZ = pos.getZ() & 15; + public static boolean areNeighborsWithinSameChunkSection(int x, int y, int z) { + int localX = x & 15; + int localY = y & 15; + int localZ = z & 15; return localX > 0 && localY > 0 && localZ > 0 && localX < 15 && localY < 15 && localZ < 15; } diff --git a/src/main/java/me/jellysquid/mods/lithium/common/world/chunk/ChunkHolderExtended.java b/src/main/java/me/jellysquid/mods/lithium/common/world/chunk/ChunkHolderExtended.java index fed915b7c..dfe910349 100644 --- a/src/main/java/me/jellysquid/mods/lithium/common/world/chunk/ChunkHolderExtended.java +++ b/src/main/java/me/jellysquid/mods/lithium/common/world/chunk/ChunkHolderExtended.java @@ -1,7 +1,6 @@ package me.jellysquid.mods.lithium.common.world.chunk; -import com.mojang.datafixers.util.Either; -import net.minecraft.server.world.ChunkHolder; +import net.minecraft.server.world.OptionalChunk; import net.minecraft.world.chunk.Chunk; import java.util.concurrent.CompletableFuture; @@ -10,12 +9,12 @@ public interface ChunkHolderExtended { /** * @return The existing future for the status at ordinal {@param index} or null if none exists */ - CompletableFuture> lithium$getFutureByStatus(int index); + CompletableFuture> lithium$getFutureByStatus(int index); /** * Updates the future for the status at ordinal {@param index}. */ - void lithium$setFutureForStatus(int index, CompletableFuture> future); + void lithium$setFutureForStatus(int index, CompletableFuture> future); /** * Updates the last accessed timestamp for this chunk. This is used to determine if a ticket was recently diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/nearby_entity_tracking/EntityMixin.java b/src/main/java/me/jellysquid/mods/lithium/mixin/ai/nearby_entity_tracking/EntityMixin.java deleted file mode 100644 index c1e2b6518..000000000 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/nearby_entity_tracking/EntityMixin.java +++ /dev/null @@ -1,31 +0,0 @@ -package me.jellysquid.mods.lithium.mixin.ai.nearby_entity_tracking; - -import me.jellysquid.mods.lithium.common.entity.nearby_tracker.NearbyEntityListenerMulti; -import me.jellysquid.mods.lithium.common.entity.nearby_tracker.NearbyEntityListenerProvider; -import me.jellysquid.mods.lithium.common.entity.nearby_tracker.NearbyEntityTracker; -import net.minecraft.entity.Entity; -import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Mixin; - -/** - * Extends the base living entity class to provide a {@link NearbyEntityListenerMulti} which will handle the - * child {@link NearbyEntityListenerProvider}s of AI tasks attached to this entity. - */ -@Mixin(Entity.class) -public class EntityMixin implements NearbyEntityListenerProvider { - private NearbyEntityListenerMulti tracker = null; - - @Override - @Nullable - public NearbyEntityListenerMulti lithium$getListener() { - return this.tracker; - } - - @Override - public void lithium$addListener(NearbyEntityTracker listener) { - if (this.tracker == null) { - this.tracker = new NearbyEntityListenerMulti(); - } - this.tracker.addListener(listener); - } -} diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/nearby_entity_tracking/EntityTrackingSectionMixin.java b/src/main/java/me/jellysquid/mods/lithium/mixin/ai/nearby_entity_tracking/EntityTrackingSectionMixin.java deleted file mode 100644 index 56b58a265..000000000 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/nearby_entity_tracking/EntityTrackingSectionMixin.java +++ /dev/null @@ -1,105 +0,0 @@ -package me.jellysquid.mods.lithium.mixin.ai.nearby_entity_tracking; - -import com.llamalad7.mixinextras.injector.ModifyReturnValue; -import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; -import me.jellysquid.mods.lithium.common.entity.PositionedEntityTrackingSection; -import me.jellysquid.mods.lithium.common.entity.nearby_tracker.NearbyEntityListener; -import me.jellysquid.mods.lithium.common.entity.nearby_tracker.NearbyEntityListenerSection; -import net.minecraft.entity.Entity; -import net.minecraft.util.collection.TypeFilterableList; -import net.minecraft.world.entity.EntityLike; -import net.minecraft.world.entity.EntityTrackingSection; -import net.minecraft.world.entity.EntityTrackingStatus; -import net.minecraft.world.entity.SectionedEntityCache; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.ModifyVariable; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(EntityTrackingSection.class) -public abstract class EntityTrackingSectionMixin implements NearbyEntityListenerSection, PositionedEntityTrackingSection { - @Shadow - private EntityTrackingStatus status; - @Shadow - @Final - private TypeFilterableList collection; - - @Shadow - public abstract boolean isEmpty(); - - @Unique - private final ReferenceOpenHashSet nearbyEntityListeners = new ReferenceOpenHashSet<>(0); - - @Override - public void lithium$addListener(NearbyEntityListener listener) { - this.nearbyEntityListeners.add(listener); - if (this.status.shouldTrack()) { - listener.onSectionEnteredRange(this, this.collection); - } - } - - @Override - public void lithium$removeListener(SectionedEntityCache sectionedEntityCache, NearbyEntityListener listener) { - boolean removed = this.nearbyEntityListeners.remove(listener); - if (this.status.shouldTrack() && removed) { - listener.onSectionLeftRange(this, this.collection); - } - if (this.isEmpty()) { - sectionedEntityCache.removeSection(this.lithium$getPos()); - } - } - - /** - * @author ishland, 2No2Name - */ - @ModifyReturnValue(method = "isEmpty()Z", at = @At(value = "RETURN")) - public boolean modifyIsEmpty(boolean previousIsEmpty) { - return previousIsEmpty && this.nearbyEntityListeners.isEmpty(); - } - - @Inject(method = "add(Lnet/minecraft/world/entity/EntityLike;)V", at = @At("RETURN")) - private void onEntityAdded(T entityLike, CallbackInfo ci) { - if (!this.status.shouldTrack() || this.nearbyEntityListeners.isEmpty()) { - return; - } - if (entityLike instanceof Entity entity) { - for (NearbyEntityListener nearbyEntityListener : this.nearbyEntityListeners) { - nearbyEntityListener.onEntityEnteredRange(entity); - } - } - } - - @Inject(method = "remove(Lnet/minecraft/world/entity/EntityLike;)Z", at = @At("RETURN")) - private void onEntityRemoved(T entityLike, CallbackInfoReturnable cir) { - if (this.status.shouldTrack() && !this.nearbyEntityListeners.isEmpty() && entityLike instanceof Entity entity) { - for (NearbyEntityListener nearbyEntityListener : this.nearbyEntityListeners) { - nearbyEntityListener.onEntityLeftRange(entity); - } - } - } - - @ModifyVariable(method = "swapStatus(Lnet/minecraft/world/entity/EntityTrackingStatus;)Lnet/minecraft/world/entity/EntityTrackingStatus;", at = @At(value = "HEAD"), argsOnly = true) - public EntityTrackingStatus swapStatus(final EntityTrackingStatus newStatus) { - if (this.status.shouldTrack() != newStatus.shouldTrack()) { - if (!newStatus.shouldTrack()) { - if (!this.nearbyEntityListeners.isEmpty()) { - for (NearbyEntityListener nearbyEntityListener : this.nearbyEntityListeners) { - nearbyEntityListener.onSectionLeftRange(this, this.collection); - } - } - } else { - if (!this.nearbyEntityListeners.isEmpty()) { - for (NearbyEntityListener nearbyEntityListener : this.nearbyEntityListeners) { - nearbyEntityListener.onSectionEnteredRange(this, this.collection); - } - } - } - } - return newStatus; - } -} diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/nearby_entity_tracking/ServerEntityManagerListenerMixin.java b/src/main/java/me/jellysquid/mods/lithium/mixin/ai/nearby_entity_tracking/ServerEntityManagerListenerMixin.java deleted file mode 100644 index ea656aadd..000000000 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/nearby_entity_tracking/ServerEntityManagerListenerMixin.java +++ /dev/null @@ -1,75 +0,0 @@ -package me.jellysquid.mods.lithium.mixin.ai.nearby_entity_tracking; - -import me.jellysquid.mods.lithium.common.entity.nearby_tracker.NearbyEntityListenerMulti; -import me.jellysquid.mods.lithium.common.entity.nearby_tracker.NearbyEntityListenerProvider; -import me.jellysquid.mods.lithium.common.util.tuples.Range6Int; -import me.jellysquid.mods.lithium.mixin.util.accessors.ServerEntityManagerAccessor; -import net.minecraft.entity.Entity; -import net.minecraft.server.world.ServerEntityManager; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.ChunkSectionPos; -import net.minecraft.world.entity.EntityLike; -import net.minecraft.world.entity.EntityTrackingSection; -import net.minecraft.world.entity.EntityTrackingStatus; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; - -@Mixin(targets = "net/minecraft/server/world/ServerEntityManager$Listener") -public class ServerEntityManagerListenerMixin { - @Shadow - @Final - private T entity; - - @Final - @SuppressWarnings("ShadowTarget") - @Shadow - ServerEntityManager manager; - - @Shadow - private long sectionPos; - - @Inject( - method = "updateEntityPosition()V", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/world/entity/EntityTrackingSection;add(Lnet/minecraft/world/entity/EntityLike;)V", - shift = At.Shift.AFTER - ), - locals = LocalCapture.CAPTURE_FAILHARD - ) - private void onUpdateEntityPosition(CallbackInfo ci, BlockPos blockPos, long newPos, EntityTrackingStatus entityTrackingStatus, EntityTrackingSection entityTrackingSection) { - NearbyEntityListenerMulti listener = ((NearbyEntityListenerProvider) this.entity).lithium$getListener(); - if (listener != null) - { - Range6Int chunkRange = listener.getChunkRange(); - //noinspection unchecked - listener.updateChunkRegistrations( - ((ServerEntityManagerAccessor) this.manager).getCache(), - ChunkSectionPos.from(this.sectionPos), chunkRange, - ChunkSectionPos.from(newPos), chunkRange - ); - } - } - - @Inject( - method = "remove(Lnet/minecraft/entity/Entity$RemovalReason;)V", - at = @At( - value = "HEAD" - ) - ) - private void onRemoveEntity(Entity.RemovalReason reason, CallbackInfo ci) { - NearbyEntityListenerMulti listener = ((NearbyEntityListenerProvider) this.entity).lithium$getListener(); - if (listener != null) { - //noinspection unchecked - listener.removeFromAllChunksInRange( - ((ServerEntityManagerAccessor) this.manager).getCache(), - ChunkSectionPos.from(this.sectionPos) - ); - } - } -} diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/nearby_entity_tracking/ServerEntityManagerMixin.java b/src/main/java/me/jellysquid/mods/lithium/mixin/ai/nearby_entity_tracking/ServerEntityManagerMixin.java deleted file mode 100644 index 614bcf1ed..000000000 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/nearby_entity_tracking/ServerEntityManagerMixin.java +++ /dev/null @@ -1,39 +0,0 @@ -package me.jellysquid.mods.lithium.mixin.ai.nearby_entity_tracking; - -import me.jellysquid.mods.lithium.common.entity.nearby_tracker.NearbyEntityListenerMulti; -import me.jellysquid.mods.lithium.common.entity.nearby_tracker.NearbyEntityListenerProvider; -import net.minecraft.server.world.ServerEntityManager; -import net.minecraft.util.math.ChunkSectionPos; -import net.minecraft.world.entity.EntityLike; -import net.minecraft.world.entity.SectionedEntityCache; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(ServerEntityManager.class) -public abstract class ServerEntityManagerMixin { - @Shadow - @Final - SectionedEntityCache cache; - - @Inject( - method = "addEntity(Lnet/minecraft/world/entity/EntityLike;Z)Z", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/world/entity/EntityLike;setChangeListener(Lnet/minecraft/world/entity/EntityChangeListener;)V", - shift = At.Shift.AFTER - ) - ) - private void onAddEntity(T entity, boolean existing, CallbackInfoReturnable cir) { - NearbyEntityListenerMulti listener = ((NearbyEntityListenerProvider) entity).lithium$getListener(); - if (listener != null) { - listener.addToAllChunksInRange( - this.cache, - ChunkSectionPos.from(entity.getBlockPos()) - ); - } - } -} diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/nearby_entity_tracking/goals/FleeEntityGoalMixin.java b/src/main/java/me/jellysquid/mods/lithium/mixin/ai/nearby_entity_tracking/goals/FleeEntityGoalMixin.java deleted file mode 100644 index cb7d61707..000000000 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/nearby_entity_tracking/goals/FleeEntityGoalMixin.java +++ /dev/null @@ -1,61 +0,0 @@ -package me.jellysquid.mods.lithium.mixin.ai.nearby_entity_tracking.goals; - -import me.jellysquid.mods.lithium.common.entity.nearby_tracker.NearbyEntityListenerProvider; -import me.jellysquid.mods.lithium.common.entity.nearby_tracker.NearbyEntityTracker; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityDimensions; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.ai.TargetPredicate; -import net.minecraft.entity.ai.goal.FleeEntityGoal; -import net.minecraft.entity.mob.PathAwareEntity; -import net.minecraft.util.math.Box; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.Vec3i; -import net.minecraft.world.World; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import java.util.List; -import java.util.function.Predicate; - -@Mixin(FleeEntityGoal.class) -public class FleeEntityGoalMixin { - @Shadow - @Final - protected PathAwareEntity mob; - @Shadow - @Final - protected float fleeDistance; - private NearbyEntityTracker tracker; - - @Inject(method = "(Lnet/minecraft/entity/mob/PathAwareEntity;Ljava/lang/Class;Ljava/util/function/Predicate;FDDLjava/util/function/Predicate;)V", at = @At("RETURN")) - private void init(PathAwareEntity mob, Class fleeFromType, Predicate predicate, float distance, double slowSpeed, double fastSpeed, Predicate predicate2, CallbackInfo ci) { - EntityDimensions dimensions = this.mob.getType().getDimensions(); - double adjustedRange = dimensions.width * 0.5D + this.fleeDistance + 2D; - int horizontalRange = MathHelper.ceil(adjustedRange); - this.tracker = new NearbyEntityTracker<>(fleeFromType, mob, new Vec3i(horizontalRange, MathHelper.ceil(dimensions.height + 3 + 2), horizontalRange)); - - ((NearbyEntityListenerProvider) mob).lithium$addListener(this.tracker); - } - - @Redirect( - method = "canStart()Z", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/world/World;getClosestEntity(Ljava/util/List;Lnet/minecraft/entity/ai/TargetPredicate;Lnet/minecraft/entity/LivingEntity;DDD)Lnet/minecraft/entity/LivingEntity;" - ) - ) - private T redirectGetNearestEntity(World world, List entityList, TargetPredicate targetPredicate, LivingEntity entity, double x, double y, double z) { - return this.tracker.getClosestEntity(this.mob.getBoundingBox().expand(this.fleeDistance, 3.0D, this.fleeDistance), targetPredicate, x, y, z); - } - - @Redirect(method = "canStart()Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;getEntitiesByClass(Ljava/lang/Class;Lnet/minecraft/util/math/Box;Ljava/util/function/Predicate;)Ljava/util/List;")) - private List redirectGetEntities(World world, Class entityClass, Box box, Predicate predicate) { - return null; - } -} diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/nearby_entity_tracking/goals/LookAtEntityGoalMixin.java b/src/main/java/me/jellysquid/mods/lithium/mixin/ai/nearby_entity_tracking/goals/LookAtEntityGoalMixin.java deleted file mode 100644 index 465a149c2..000000000 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/nearby_entity_tracking/goals/LookAtEntityGoalMixin.java +++ /dev/null @@ -1,73 +0,0 @@ -package me.jellysquid.mods.lithium.mixin.ai.nearby_entity_tracking.goals; - -import me.jellysquid.mods.lithium.common.entity.nearby_tracker.NearbyEntityListenerProvider; -import me.jellysquid.mods.lithium.common.entity.nearby_tracker.NearbyEntityTracker; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityDimensions; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.ai.TargetPredicate; -import net.minecraft.entity.ai.goal.LookAtEntityGoal; -import net.minecraft.entity.mob.MobEntity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.util.math.Box; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.Vec3i; -import net.minecraft.world.World; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import java.util.List; -import java.util.function.Predicate; - -@Mixin(LookAtEntityGoal.class) -public class LookAtEntityGoalMixin { - @Shadow - @Final - protected MobEntity mob; - @Shadow - @Final - protected float range; - private NearbyEntityTracker tracker; - - @Inject(method = "(Lnet/minecraft/entity/mob/MobEntity;Ljava/lang/Class;FFZ)V", at = @At("RETURN")) - private void init(MobEntity mob, Class targetType, float range, float chance, boolean b, CallbackInfo ci) { - EntityDimensions dimensions = this.mob.getType().getDimensions(); - double adjustedRange = dimensions.width * 0.5D + this.range + 2D; - int horizontalRange = MathHelper.ceil(adjustedRange); - this.tracker = new NearbyEntityTracker<>(targetType, mob, new Vec3i(horizontalRange, MathHelper.ceil(dimensions.height + 3 + 2), horizontalRange)); - - ((NearbyEntityListenerProvider) mob).lithium$addListener(this.tracker); - } - - @Redirect( - method = "canStart()Z", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/world/World;getClosestEntity(Ljava/util/List;Lnet/minecraft/entity/ai/TargetPredicate;Lnet/minecraft/entity/LivingEntity;DDD)Lnet/minecraft/entity/LivingEntity;" - ) - ) - private LivingEntity redirectGetNearestEntity(World world, List entityList, TargetPredicate targetPredicate, LivingEntity entity, double x, double y, double z) { - return this.tracker.getClosestEntity(this.mob.getBoundingBox().expand(this.range, 3.0D, this.range), targetPredicate, x, y, z); - } - - @Redirect(method = "canStart()Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;getEntitiesByClass(Ljava/lang/Class;Lnet/minecraft/util/math/Box;Ljava/util/function/Predicate;)Ljava/util/List;")) - private List redirectGetEntities(World world, Class entityClass, Box box, Predicate predicate) { - return null; - } - - @Redirect( - method = "canStart()Z", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/world/World;getClosestPlayer(Lnet/minecraft/entity/ai/TargetPredicate;Lnet/minecraft/entity/LivingEntity;DDD)Lnet/minecraft/entity/player/PlayerEntity;" - ) - ) - private PlayerEntity redirectGetClosestPlayer(World world, TargetPredicate targetPredicate, LivingEntity entity, double x, double y, double z) { - return (PlayerEntity) this.tracker.getClosestEntity(null, targetPredicate, x, y, z); - } -} diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/nearby_entity_tracking/goals/package-info.java b/src/main/java/me/jellysquid/mods/lithium/mixin/ai/nearby_entity_tracking/goals/package-info.java deleted file mode 100644 index 52cf5a221..000000000 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/nearby_entity_tracking/goals/package-info.java +++ /dev/null @@ -1,11 +0,0 @@ -@MixinConfigOption( - description = """ - A number of AI goals which query for nearby entities in the world every tick will use the event-based - system for tracking nearby entities. In other words, instead of entities constantly polling to see if - other entities are nearby, they will instead be notified only occasionally when such an entity enters - their range. - """ -) -package me.jellysquid.mods.lithium.mixin.ai.nearby_entity_tracking.goals; - -import net.caffeinemc.gradle.MixinConfigOption; \ No newline at end of file diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/nearby_entity_tracking/package-info.java b/src/main/java/me/jellysquid/mods/lithium/mixin/ai/nearby_entity_tracking/package-info.java deleted file mode 100644 index 403f4d318..000000000 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/nearby_entity_tracking/package-info.java +++ /dev/null @@ -1,14 +0,0 @@ -@MixinConfigOption( - description = """ - Event-based system for tracking nearby entities. - """, - depends = { - @MixinConfigDependency(dependencyPath = "mixin.util.entity_section_position"), - @MixinConfigDependency(dependencyPath = "mixin.util.accessors") - }, - enabled = false //Disabled, because mspt increase in normal worlds has been measured consistently -) -package me.jellysquid.mods.lithium.mixin.ai.nearby_entity_tracking; - -import net.caffeinemc.gradle.MixinConfigDependency; -import net.caffeinemc.gradle.MixinConfigOption; \ No newline at end of file diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/pathing/AbstractBlockStateMixin.java b/src/main/java/me/jellysquid/mods/lithium/mixin/ai/pathing/AbstractBlockStateMixin.java index b041e7722..3a21b8dc1 100644 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/pathing/AbstractBlockStateMixin.java +++ b/src/main/java/me/jellysquid/mods/lithium/mixin/ai/pathing/AbstractBlockStateMixin.java @@ -6,6 +6,7 @@ import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.entity.ai.pathing.LandPathNodeMaker; +import net.minecraft.entity.ai.pathing.PathContext; import net.minecraft.entity.ai.pathing.PathNodeType; import net.minecraft.util.math.BlockPos; import org.apache.commons.lang3.Validate; @@ -28,9 +29,9 @@ private void init(CallbackInfo ci) { BlockState state = this.asBlockState(); - SingleBlockBlockView blockView = SingleBlockBlockView.of(state, BlockPos.ORIGIN); + SingleBlockBlockView singleBlockBlockView = SingleBlockBlockView.of(state, BlockPos.ORIGIN); try { - this.pathNodeType = Validate.notNull(LandPathNodeMaker.getCommonNodeType(blockView, BlockPos.ORIGIN)); + this.pathNodeType = Validate.notNull(LandPathNodeMaker.getCommonNodeType(singleBlockBlockView, BlockPos.ORIGIN), "Block has no common path node type!"); } catch (SingleBlockBlockView.SingleBlockViewException | ClassCastException e) { //This is usually hit by shulker boxes, as their hitbox depends on the block entity, and the node type depends on the hitbox //Also catch ClassCastException in case some modded code casts BlockView to ChunkCache @@ -38,11 +39,12 @@ private void init(CallbackInfo ci) { } try { //Passing null as previous node type to the method signals to other lithium mixins that we only want the neighbor behavior of this block and not its neighbors - this.pathNodeTypeNeighbor = (LandPathNodeMaker.getNodeTypeFromNeighbors(blockView, BlockPos.ORIGIN.mutableCopy(), null)); + //Using exceptions for control flow, but this way we do not need to copy the code for the cache initialization, reducing required maintenance and improving mod compatibility + this.pathNodeTypeNeighbor = (LandPathNodeMaker.getNodeTypeFromNeighbors(new PathContext(singleBlockBlockView, null), 1, 1, 1, null)); if (this.pathNodeTypeNeighbor == null) { this.pathNodeTypeNeighbor = PathNodeType.OPEN; } - } catch (SingleBlockBlockView.SingleBlockViewException | ClassCastException e) { + } catch (SingleBlockBlockView.SingleBlockViewException | NullPointerException | ClassCastException e) { this.pathNodeTypeNeighbor = null; } } diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/pathing/BirdPathNodeMakerMixin.java b/src/main/java/me/jellysquid/mods/lithium/mixin/ai/pathing/BirdPathNodeMakerMixin.java index 9215ccdda..86c6d271f 100644 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/pathing/BirdPathNodeMakerMixin.java +++ b/src/main/java/me/jellysquid/mods/lithium/mixin/ai/pathing/BirdPathNodeMakerMixin.java @@ -2,9 +2,8 @@ import me.jellysquid.mods.lithium.common.ai.pathing.PathNodeCache; import net.minecraft.entity.ai.pathing.BirdPathNodeMaker; +import net.minecraft.entity.ai.pathing.PathContext; import net.minecraft.entity.ai.pathing.PathNodeType; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.BlockView; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; @@ -16,8 +15,8 @@ public class BirdPathNodeMakerMixin { * @reason Use optimized implementation which avoids scanning blocks for dangers where possible * @author JellySquid, 2No2Name */ - @Redirect(method = "getDefaultNodeType", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/ai/pathing/BirdPathNodeMaker;getNodeTypeFromNeighbors(Lnet/minecraft/world/BlockView;Lnet/minecraft/util/math/BlockPos$Mutable;Lnet/minecraft/entity/ai/pathing/PathNodeType;)Lnet/minecraft/entity/ai/pathing/PathNodeType;")) - private PathNodeType getNodeTypeFromNeighbors(BlockView world, BlockPos.Mutable pos, PathNodeType type) { - return PathNodeCache.getNodeTypeFromNeighbors(world, pos, type); + @Redirect(method = "getDefaultNodeType", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/ai/pathing/BirdPathNodeMaker;getNodeTypeFromNeighbors(Lnet/minecraft/entity/ai/pathing/PathContext;IIILnet/minecraft/entity/ai/pathing/PathNodeType;)Lnet/minecraft/entity/ai/pathing/PathNodeType;")) + private PathNodeType getNodeTypeFromNeighbors(PathContext pathContext, int x, int y, int z, PathNodeType pathNodeType) { + return PathNodeCache.getNodeTypeFromNeighbors(pathContext, x, y, z, pathNodeType); } } diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/pathing/LandPathNodeMakerMixin.java b/src/main/java/me/jellysquid/mods/lithium/mixin/ai/pathing/LandPathNodeMakerMixin.java index 792f32242..090e8ddf0 100644 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/pathing/LandPathNodeMakerMixin.java +++ b/src/main/java/me/jellysquid/mods/lithium/mixin/ai/pathing/LandPathNodeMakerMixin.java @@ -3,6 +3,7 @@ import me.jellysquid.mods.lithium.common.ai.pathing.PathNodeCache; import net.minecraft.block.BlockState; import net.minecraft.entity.ai.pathing.LandPathNodeMaker; +import net.minecraft.entity.ai.pathing.PathContext; import net.minecraft.entity.ai.pathing.PathNodeType; import net.minecraft.util.math.BlockPos; import net.minecraft.world.BlockView; @@ -22,12 +23,11 @@ @Mixin(value = LandPathNodeMaker.class, priority = 990) public abstract class LandPathNodeMakerMixin { /** - * This mixin requires a priority < 1000 due to fabric api using 1000 and we need to inject before them. + * This mixin requires a priority < 1000 due to fabric api using 1000 and us needing to inject before them. * * @reason Use optimized implementation * @author JellySquid, 2No2Name */ - @SuppressWarnings("InvalidInjectorMethodSignature") @Inject(method = "getCommonNodeType", at = @At( value = "INVOKE_ASSIGN", @@ -57,16 +57,14 @@ private static void getLithiumCachedCommonNodeType(BlockView world, BlockPos pos @Inject( method = "getNodeTypeFromNeighbors", locals = LocalCapture.CAPTURE_FAILHARD, at = @At( - value = "INVOKE", shift = At.Shift.AFTER, - target = "Lnet/minecraft/util/math/BlockPos$Mutable;set(III)Lnet/minecraft/util/math/BlockPos$Mutable;" + value = "INVOKE", shift = At.Shift.BEFORE, + target = "Lnet/minecraft/entity/ai/pathing/PathContext;getNodeType(III)Lnet/minecraft/entity/ai/pathing/PathNodeType;" ), cancellable = true ) - private static void doNotChangePositionIfLithiumSinglePosCall(BlockView world, BlockPos.Mutable pos, PathNodeType nodeType, CallbackInfoReturnable cir, int posX, int posY, int posZ, int dX, int dY, int dZ) { - if (nodeType == null) { - if (dX == -1 && dY == -1 && dZ == -1) { - pos.set(posX, posY, posZ); - } else { + private static void doNotIteratePositionsIfLithiumSinglePosCall(PathContext context, int x, int y, int z, PathNodeType fallback, CallbackInfoReturnable cir) { + if (fallback == null) { + if (x != -1 || y != -1 || z != -1) { cir.setReturnValue(null); } } @@ -76,8 +74,8 @@ private static void doNotChangePositionIfLithiumSinglePosCall(BlockView world, B * @reason Use optimized implementation which avoids scanning blocks for dangers where possible * @author JellySquid, 2No2Name */ - @Redirect(method = "getLandNodeType", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/ai/pathing/LandPathNodeMaker;getNodeTypeFromNeighbors(Lnet/minecraft/world/BlockView;Lnet/minecraft/util/math/BlockPos$Mutable;Lnet/minecraft/entity/ai/pathing/PathNodeType;)Lnet/minecraft/entity/ai/pathing/PathNodeType;")) - private static PathNodeType getNodeTypeFromNeighbors(BlockView world, BlockPos.Mutable pos, PathNodeType type) { - return PathNodeCache.getNodeTypeFromNeighbors(world, pos, type); + @Redirect(method = "getLandNodeType(Lnet/minecraft/entity/ai/pathing/PathContext;Lnet/minecraft/util/math/BlockPos$Mutable;)Lnet/minecraft/entity/ai/pathing/PathNodeType;", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/ai/pathing/LandPathNodeMaker;getNodeTypeFromNeighbors(Lnet/minecraft/entity/ai/pathing/PathContext;IIILnet/minecraft/entity/ai/pathing/PathNodeType;)Lnet/minecraft/entity/ai/pathing/PathNodeType;")) + private static PathNodeType getNodeTypeFromNeighbors(PathContext context, int x, int y, int z, PathNodeType fallback) { + return PathNodeCache.getNodeTypeFromNeighbors(context, x, y, z, fallback); } } diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/pathing/PathContextAccessor.java b/src/main/java/me/jellysquid/mods/lithium/mixin/ai/pathing/PathContextAccessor.java new file mode 100644 index 000000000..77c6ec7ef --- /dev/null +++ b/src/main/java/me/jellysquid/mods/lithium/mixin/ai/pathing/PathContextAccessor.java @@ -0,0 +1,14 @@ +package me.jellysquid.mods.lithium.mixin.ai.pathing; + +import net.minecraft.entity.ai.pathing.PathContext; +import net.minecraft.util.math.BlockPos; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(PathContext.class) +public interface PathContextAccessor { + + @Accessor + BlockPos.Mutable getLastNodePos(); + +} diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/pathing/PathContextMixin.java b/src/main/java/me/jellysquid/mods/lithium/mixin/ai/pathing/PathContextMixin.java new file mode 100644 index 000000000..14a9d1850 --- /dev/null +++ b/src/main/java/me/jellysquid/mods/lithium/mixin/ai/pathing/PathContextMixin.java @@ -0,0 +1,36 @@ +package me.jellysquid.mods.lithium.mixin.ai.pathing; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import net.minecraft.entity.ai.pathing.PathContext; +import net.minecraft.entity.mob.MobEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(PathContext.class) +public class PathContextMixin { + + @WrapOperation( + method = "", + at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/mob/MobEntity;getWorld()Lnet/minecraft/world/World;") + ) + private World getWorldIfNonNull(MobEntity instance, Operation original) { + if (instance == null) { + return null; + } + return original.call(instance); + } + + @WrapOperation( + method = "", + at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/mob/MobEntity;getBlockPos()Lnet/minecraft/util/math/BlockPos;") + ) + private BlockPos getBlockPosIfNonNull(MobEntity instance, Operation original) { + if (instance == null) { + return null; + } + return original.call(instance); + } +} diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/poi/PointOfInterestStorageMixin.java b/src/main/java/me/jellysquid/mods/lithium/mixin/ai/poi/PointOfInterestStorageMixin.java index 8bc8c8bce..6c22a45c5 100644 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/poi/PointOfInterestStorageMixin.java +++ b/src/main/java/me/jellysquid/mods/lithium/mixin/ai/poi/PointOfInterestStorageMixin.java @@ -1,6 +1,5 @@ package me.jellysquid.mods.lithium.mixin.ai.poi; -import com.mojang.datafixers.DataFixer; import com.mojang.serialization.Codec; import me.jellysquid.mods.lithium.common.util.Distances; import me.jellysquid.mods.lithium.common.world.interests.PointOfInterestSetExtended; @@ -9,7 +8,6 @@ import me.jellysquid.mods.lithium.common.world.interests.iterator.NearbyPointOfInterestStream; import me.jellysquid.mods.lithium.common.world.interests.iterator.SinglePointOfInterestTypeFilter; import me.jellysquid.mods.lithium.common.world.interests.iterator.SphereChunkOrderedPoiSetSpliterator; -import net.minecraft.datafixer.DataFixTypes; import net.minecraft.registry.DynamicRegistryManager; import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.util.annotation.Debug; @@ -24,13 +22,13 @@ import net.minecraft.world.poi.PointOfInterestSet; import net.minecraft.world.poi.PointOfInterestStorage; import net.minecraft.world.poi.PointOfInterestType; +import net.minecraft.world.storage.ChunkPosKeyedStorage; import net.minecraft.world.storage.SerializingRegionBasedStorage; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Shadow; -import java.nio.file.Path; import java.util.ArrayList; import java.util.Optional; import java.util.function.BiConsumer; @@ -44,8 +42,9 @@ public abstract class PointOfInterestStorageMixin extends SerializingRegionBasedStorage implements PointOfInterestStorageExtended { - public PointOfInterestStorageMixin(Path path, Function> codecFactory, Function factory, DataFixer dataFixer, DataFixTypes dataFixTypes, boolean dsync, DynamicRegistryManager dynamicRegistryManager, HeightLimitView world) { - super(path, codecFactory, factory, dataFixer, dataFixTypes, dsync, dynamicRegistryManager, world); + + public PointOfInterestStorageMixin(ChunkPosKeyedStorage storageAccess, Function> codecFactory, Function factory, DynamicRegistryManager registryManager, HeightLimitView world) { + super(storageAccess, codecFactory, factory, registryManager, world); } /** diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/poi/SerializingRegionBasedStorageMixin.java b/src/main/java/me/jellysquid/mods/lithium/mixin/ai/poi/SerializingRegionBasedStorageMixin.java index 2b881777b..580fab3cd 100644 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/poi/SerializingRegionBasedStorageMixin.java +++ b/src/main/java/me/jellysquid/mods/lithium/mixin/ai/poi/SerializingRegionBasedStorageMixin.java @@ -1,17 +1,16 @@ package me.jellysquid.mods.lithium.mixin.ai.poi; import com.google.common.collect.AbstractIterator; -import com.mojang.datafixers.DataFixer; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import me.jellysquid.mods.lithium.common.util.Pos; import me.jellysquid.mods.lithium.common.util.collections.ListeningLong2ObjectOpenHashMap; import me.jellysquid.mods.lithium.common.world.interests.RegionBasedStorageSectionExtended; -import net.minecraft.datafixer.DataFixTypes; import net.minecraft.registry.DynamicRegistryManager; import net.minecraft.util.math.ChunkPos; import net.minecraft.util.math.ChunkSectionPos; import net.minecraft.world.HeightLimitView; +import net.minecraft.world.storage.ChunkPosKeyedStorage; import net.minecraft.world.storage.SerializingRegionBasedStorage; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -21,7 +20,6 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.nio.file.Path; import java.util.*; import java.util.function.Function; import java.util.stream.Stream; @@ -47,7 +45,7 @@ public abstract class SerializingRegionBasedStorageMixin implements RegionBas @SuppressWarnings("rawtypes") @Inject(method = "", at = @At("RETURN")) - private void init(Path path, Function codecFactory, Function factory, DataFixer dataFixer, DataFixTypes dataFixTypes, boolean dsync, DynamicRegistryManager dynamicRegistryManager, HeightLimitView world, CallbackInfo ci) { + private void init(ChunkPosKeyedStorage storageAccess, Function codecFactory, Function factory, DynamicRegistryManager registryManager, HeightLimitView world, CallbackInfo ci) { this.columns = new Long2ObjectOpenHashMap<>(); this.loadedElements = new ListeningLong2ObjectOpenHashMap<>(this::onEntryAdded, this::onEntryRemoved); } diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/poi/fast_portals/PointOfInterestStorageMixin.java b/src/main/java/me/jellysquid/mods/lithium/mixin/ai/poi/fast_portals/PointOfInterestStorageMixin.java index ad602884e..382266880 100644 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/poi/fast_portals/PointOfInterestStorageMixin.java +++ b/src/main/java/me/jellysquid/mods/lithium/mixin/ai/poi/fast_portals/PointOfInterestStorageMixin.java @@ -1,9 +1,8 @@ package me.jellysquid.mods.lithium.mixin.ai.poi.fast_portals; -import com.mojang.datafixers.DataFixer; +import com.mojang.serialization.Codec; import it.unimi.dsi.fastutil.longs.LongOpenHashSet; import it.unimi.dsi.fastutil.longs.LongSet; -import net.minecraft.datafixer.DataFixTypes; import net.minecraft.registry.DynamicRegistryManager; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.ChunkPos; @@ -13,11 +12,12 @@ import net.minecraft.world.chunk.ChunkStatus; import net.minecraft.world.poi.PointOfInterestSet; import net.minecraft.world.poi.PointOfInterestStorage; +import net.minecraft.world.storage.ChunkPosKeyedStorage; import net.minecraft.world.storage.SerializingRegionBasedStorage; import org.spongepowered.asm.mixin.*; -import java.nio.file.Path; import java.util.Optional; +import java.util.function.Function; @Mixin(PointOfInterestStorage.class) public abstract class PointOfInterestStorageMixin extends SerializingRegionBasedStorage { @@ -31,14 +31,8 @@ public abstract class PointOfInterestStorageMixin extends SerializingRegionBased @Unique private int preloadRadius = 0; - public PointOfInterestStorageMixin( - Path path, DataFixer dataFixer, boolean dsync, - DynamicRegistryManager registryManager, HeightLimitView world - ) { - super( - path, PointOfInterestSet::createCodec, PointOfInterestSet::new, - dataFixer, DataFixTypes.POI_CHUNK, dsync, registryManager, world - ); + public PointOfInterestStorageMixin(ChunkPosKeyedStorage storageAccess, Function> codecFactory, Function factory, DynamicRegistryManager registryManager, HeightLimitView world) { + super(storageAccess, codecFactory, factory, registryManager, world); } /** diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/raid/PickupBannerAsLeaderGoalMixin.java b/src/main/java/me/jellysquid/mods/lithium/mixin/ai/raid/PickupBannerAsLeaderGoalMixin.java index 0b33af889..bcdeb034a 100644 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/raid/PickupBannerAsLeaderGoalMixin.java +++ b/src/main/java/me/jellysquid/mods/lithium/mixin/ai/raid/PickupBannerAsLeaderGoalMixin.java @@ -1,25 +1,31 @@ package me.jellysquid.mods.lithium.mixin.ai.raid; +import me.jellysquid.mods.lithium.common.ai.raid.OminousBannerCache; +import net.minecraft.block.entity.BannerPattern; import net.minecraft.entity.raid.RaiderEntity; import net.minecraft.item.ItemStack; -import net.minecraft.village.raid.Raid; +import net.minecraft.registry.RegistryEntryLookup; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; @Mixin(RaiderEntity.PickupBannerAsLeaderGoal.class) -public class PickupBannerAsLeaderGoalMixin { - // The call to Raid#getOminousBanner() is very expensive, so cache it and re-use it during AI ticking - private static final ItemStack CACHED_OMINOUS_BANNER = Raid.getOminousBanner(); +public class PickupBannerAsLeaderGoalMixin { + @Shadow + @Final + private T actor; + // The call to Raid#getOminousBanner() is very expensive, use a cached banner during AI ticking @Redirect( method = "canStart()Z", at = @At( value = "INVOKE", - target = "Lnet/minecraft/village/raid/Raid;getOminousBanner()Lnet/minecraft/item/ItemStack;" + target = "Lnet/minecraft/village/raid/Raid;getOminousBanner(Lnet/minecraft/registry/RegistryEntryLookup;)Lnet/minecraft/item/ItemStack;" ) ) - private ItemStack getOminousBanner() { - return CACHED_OMINOUS_BANNER; + private ItemStack getOminousBanner(RegistryEntryLookup bannerPatternLookup) { + return ((OminousBannerCache) this.actor.getWorld()).lithium$getCachedOminousBanner(); } } \ No newline at end of file diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/raid/RaiderEntityMixin.java b/src/main/java/me/jellysquid/mods/lithium/mixin/ai/raid/RaiderEntityMixin.java index 8fab93237..951a68ca1 100644 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/raid/RaiderEntityMixin.java +++ b/src/main/java/me/jellysquid/mods/lithium/mixin/ai/raid/RaiderEntityMixin.java @@ -1,9 +1,14 @@ package me.jellysquid.mods.lithium.mixin.ai.raid; +import me.jellysquid.mods.lithium.common.ai.raid.OminousBannerCache; +import net.minecraft.block.entity.BannerPattern; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; import net.minecraft.entity.ItemEntity; import net.minecraft.entity.raid.RaiderEntity; import net.minecraft.item.ItemStack; -import net.minecraft.village.raid.Raid; +import net.minecraft.registry.RegistryEntryLookup; +import net.minecraft.world.World; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mutable; @@ -14,23 +19,27 @@ import java.util.function.Predicate; @Mixin(RaiderEntity.class) -public class RaiderEntityMixin { - // The call to Raid#getOminousBanner() is very expensive, so cache it and re-use it during AI ticking - private static final ItemStack CACHED_OMINOUS_BANNER = Raid.getOminousBanner(); +public abstract class RaiderEntityMixin extends Entity { @Mutable @Shadow @Final static Predicate OBTAINABLE_OMINOUS_BANNER_PREDICATE; static { - OBTAINABLE_OMINOUS_BANNER_PREDICATE = (itemEntity) -> !itemEntity.cannotPickup() && itemEntity.isAlive() && ItemStack.areEqual(itemEntity.getStack(), CACHED_OMINOUS_BANNER); + // The call to Raid#getOminousBanner() is very expensive, use a cached banner during AI ticking + OBTAINABLE_OMINOUS_BANNER_PREDICATE = (itemEntity) -> !itemEntity.cannotPickup() && itemEntity.isAlive() && + ItemStack.areEqual(itemEntity.getStack(), ((OminousBannerCache) itemEntity.getWorld()).lithium$getCachedOminousBanner()); + } + + public RaiderEntityMixin(EntityType type, World world) { + super(type, world); } @Redirect( method = "onDeath(Lnet/minecraft/entity/damage/DamageSource;)V", - at = @At(value = "INVOKE", target = "Lnet/minecraft/village/raid/Raid;getOminousBanner()Lnet/minecraft/item/ItemStack;") + at = @At(value = "INVOKE", target = "Lnet/minecraft/village/raid/Raid;getOminousBanner(Lnet/minecraft/registry/RegistryEntryLookup;)Lnet/minecraft/item/ItemStack;") ) - private ItemStack getOminousBanner() { - return CACHED_OMINOUS_BANNER; + private ItemStack getOminousBanner(RegistryEntryLookup bannerPatternLookup) { + return ((OminousBannerCache) this.getWorld()).lithium$getCachedOminousBanner(); } } diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/ai/raid/WorldMixin.java b/src/main/java/me/jellysquid/mods/lithium/mixin/ai/raid/WorldMixin.java new file mode 100644 index 000000000..d84c23c36 --- /dev/null +++ b/src/main/java/me/jellysquid/mods/lithium/mixin/ai/raid/WorldMixin.java @@ -0,0 +1,40 @@ +package me.jellysquid.mods.lithium.mixin.ai.raid; + +import me.jellysquid.mods.lithium.common.ai.raid.OminousBannerCache; +import net.minecraft.item.ItemStack; +import net.minecraft.registry.DynamicRegistryManager; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.village.raid.Raid; +import net.minecraft.world.MutableWorldProperties; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.function.Supplier; + +@Mixin(World.class) +public abstract class WorldMixin implements OminousBannerCache { + @Shadow + public abstract DynamicRegistryManager getRegistryManager(); + + // The call to Raid#getOminousBanner() is very expensive, so cache it and re-use it during AI ticking + private ItemStack cachedOminousBanner; + + @Inject( + method = "", + at = @At("RETURN") + ) + protected void initCachedOminiousBanner(MutableWorldProperties properties, RegistryKey registryRef, DynamicRegistryManager registryManager, RegistryEntry dimensionEntry, Supplier profiler, boolean isClient, boolean debugWorld, long biomeAccess, int maxChainedNeighborUpdates, CallbackInfo ci) { + this.cachedOminousBanner = Raid.getOminousBanner(this.getRegistryManager().getWrapperOrThrow(RegistryKeys.BANNER_PATTERN)); + } + + @Override + public ItemStack lithium$getCachedOminousBanner() { + return cachedOminousBanner; + } +} diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/block/beehive/BeehiveBlockEntityMixin.java b/src/main/java/me/jellysquid/mods/lithium/mixin/block/beehive/BeehiveBlockEntityMixin.java deleted file mode 100644 index 72acb72bb..000000000 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/block/beehive/BeehiveBlockEntityMixin.java +++ /dev/null @@ -1,35 +0,0 @@ -package me.jellysquid.mods.lithium.mixin.block.beehive; - -import net.minecraft.block.BeehiveBlock; -import net.minecraft.block.BlockState; -import net.minecraft.block.entity.BeehiveBlockEntity; -import net.minecraft.entity.Entity; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; -import net.minecraft.world.World; -import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Coerce; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import java.util.List; - -@Mixin(BeehiveBlockEntity.class) -public class BeehiveBlockEntityMixin { - - @Inject( - method = "releaseBee", - at = @At(value = "INVOKE", shift = At.Shift.BEFORE, target = "Lnet/minecraft/nbt/NbtCompound;copy()Lnet/minecraft/nbt/NbtCompound;"), - cancellable = true - ) - private static void exitEarlyIfHiveObstructed(World world, BlockPos pos, BlockState state, @Coerce Object bee, @Nullable List entities, BeehiveBlockEntity.BeeState beeState, @Nullable BlockPos flowerPos, CallbackInfoReturnable cir) { - Direction direction = state.get(BeehiveBlock.FACING); - BlockPos blockPos = pos.offset(direction); - - if (beeState != BeehiveBlockEntity.BeeState.EMERGENCY && !world.getBlockState(blockPos).getCollisionShape(world, blockPos).isEmpty()) { - cir.setReturnValue(false); - }; - } -} diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/block/beehive/package-info.java b/src/main/java/me/jellysquid/mods/lithium/mixin/block/beehive/package-info.java deleted file mode 100644 index 413b9b948..000000000 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/block/beehive/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -@MixinConfigOption(description = "Beehives check if they are obstructed before performing expensive nbt copy operations for each exit attempt.") -package me.jellysquid.mods.lithium.mixin.block.beehive; - -import net.caffeinemc.gradle.MixinConfigOption; \ No newline at end of file diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/block/flatten_states/FluidStateMixin.java b/src/main/java/me/jellysquid/mods/lithium/mixin/block/flatten_states/FluidStateMixin.java index 93c8e5256..74ae45ce4 100644 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/block/flatten_states/FluidStateMixin.java +++ b/src/main/java/me/jellysquid/mods/lithium/mixin/block/flatten_states/FluidStateMixin.java @@ -1,10 +1,9 @@ package me.jellysquid.mods.lithium.mixin.block.flatten_states; -import com.google.common.collect.ImmutableMap; import com.mojang.serialization.MapCodec; +import it.unimi.dsi.fastutil.objects.Reference2ObjectArrayMap; import net.minecraft.fluid.Fluid; import net.minecraft.fluid.FluidState; -import net.minecraft.state.property.Property; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Shadow; @@ -19,9 +18,8 @@ public abstract class FluidStateMixin { private boolean isEmptyCache; - @Inject(method = "(Lnet/minecraft/fluid/Fluid;Lcom/google/common/collect/ImmutableMap;Lcom/mojang/serialization/MapCodec;)V", at = @At("RETURN")) - private void initFluidCache(Fluid fluid, ImmutableMap, Comparable> propertyMap, - MapCodec codec, CallbackInfo ci) { + @Inject(method = "", at = @At("RETURN")) + private void initFluidCache(Fluid fluid, Reference2ObjectArrayMap propertyMap, MapCodec codec, CallbackInfo ci) { this.isEmptyCache = this.getFluid().isEmpty(); } diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/block/hopper/HopperBlockEntityMixin.java b/src/main/java/me/jellysquid/mods/lithium/mixin/block/hopper/HopperBlockEntityMixin.java index 6004f90f9..f8d82333a 100644 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/block/hopper/HopperBlockEntityMixin.java +++ b/src/main/java/me/jellysquid/mods/lithium/mixin/block/hopper/HopperBlockEntityMixin.java @@ -29,19 +29,15 @@ import net.minecraft.util.math.Direction; import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Intrinsic; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.ModifyVariable; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; -import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; @@ -56,10 +52,6 @@ public HopperBlockEntityMixin(BlockEntityType type, BlockPos pos, BlockState super(type, pos, state); } - @Shadow - @Nullable - private static native Inventory getInputInventory(World world, Hopper hopper); - @Shadow protected abstract boolean isDisabled(); @@ -85,8 +77,7 @@ public HopperBlockEntityMixin(BlockEntityType type, BlockPos pos, BlockState private SectionedItemEntityMovementTracker collectItemEntityTracker; private boolean collectItemEntityTrackerWasEmpty; - //item pickup bounding boxes in order. The last box in the array is the box that encompasses all of the others - private Box[] collectItemEntityBoxes; + private Box collectItemEntityBox; private long collectItemEntityAttemptTime; private SectionedInventoryEntityMovementTracker extractInventoryEntityTracker; @@ -99,13 +90,13 @@ public HopperBlockEntityMixin(BlockEntityType type, BlockPos pos, BlockState private boolean shouldCheckSleep; - @Redirect(method = "extract(Lnet/minecraft/world/World;Lnet/minecraft/block/entity/Hopper;)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/entity/HopperBlockEntity;getInputInventory(Lnet/minecraft/world/World;Lnet/minecraft/block/entity/Hopper;)Lnet/minecraft/inventory/Inventory;")) - private static Inventory getExtractInventory(World world, Hopper hopper) { + @Redirect(method = "extract(Lnet/minecraft/world/World;Lnet/minecraft/block/entity/Hopper;)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/entity/HopperBlockEntity;getInputInventory(Lnet/minecraft/world/World;Lnet/minecraft/block/entity/Hopper;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;)Lnet/minecraft/inventory/Inventory;")) + private static Inventory getExtractInventory(World world, Hopper hopper, BlockPos extractBlockPos, BlockState extractBlockState) { if (!(hopper instanceof HopperBlockEntityMixin hopperBlockEntity)) { - return getInputInventory(world, hopper); //Hopper Minecarts do not cache Inventories + return getInputInventory(world, hopper, extractBlockPos, extractBlockState); //Hopper Minecarts do not cache Inventories } - Inventory blockInventory = hopperBlockEntity.getExtractBlockInventory(world); + Inventory blockInventory = hopperBlockEntity.getExtractBlockInventory(world, extractBlockPos, extractBlockState); if (blockInventory != null) { return blockInventory; } @@ -148,19 +139,19 @@ private static Inventory getExtractInventory(World world, Hopper hopper) { @SuppressWarnings("JavadocReference") @Inject( cancellable = true, - method = "insert(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;Lnet/minecraft/inventory/Inventory;)Z", + method = "insert(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/entity/HopperBlockEntity;)Z", at = @At( value = "INVOKE", shift = At.Shift.BEFORE, target = "Lnet/minecraft/block/entity/HopperBlockEntity;isInventoryFull(Lnet/minecraft/inventory/Inventory;Lnet/minecraft/util/math/Direction;)Z" ), locals = LocalCapture.CAPTURE_FAILHARD ) - private static void lithiumInsert(World world, BlockPos pos, BlockState hopperState, Inventory hopper, CallbackInfoReturnable cir, Inventory insertInventory, Direction direction) { - if (insertInventory == null || !(hopper instanceof HopperBlockEntity) || hopper instanceof SidedInventory) { + private static void lithiumInsert(World world, BlockPos pos, HopperBlockEntity blockEntity, CallbackInfoReturnable cir, Inventory insertInventory, Direction direction) { + if (insertInventory == null || !(blockEntity instanceof HopperBlockEntity) || blockEntity instanceof SidedInventory) { //call the vanilla code to allow other mods inject features //e.g. carpet mod allows hoppers to insert items into wool blocks return; } - HopperBlockEntityMixin hopperBlockEntity = (HopperBlockEntityMixin) hopper; + HopperBlockEntityMixin hopperBlockEntity = (HopperBlockEntityMixin) (Object) blockEntity; LithiumStackList hopperStackList = InventoryHelper.getLithiumStackList(hopperBlockEntity); if (hopperBlockEntity.insertInventory == insertInventory && hopperStackList.getModCount() == hopperBlockEntity.myModCountAtLastInsert) { @@ -184,7 +175,7 @@ private static void lithiumInsert(World world, BlockPos pos, BlockState hopperSt //noinspection ConstantConditions if (!(hopperBlockEntity.insertInventory == insertInventory && hopperBlockEntity.insertStackList.getFullSlots() == hopperBlockEntity.insertStackList.size())) { - Direction fromDirection = hopperState.get(HopperBlock.FACING).getOpposite(); + Direction fromDirection = hopperBlockEntity.facing.getOpposite(); int size = hopperStackList.size(); //noinspection ForLoopReplaceableByForEach for (int i = 0; i < size; ++i) { @@ -225,7 +216,7 @@ private static void lithiumInsert(World world, BlockPos pos, BlockState hopperSt * @param from Inventory the hopper is extracting from */ @Inject(method = "extract(Lnet/minecraft/world/World;Lnet/minecraft/block/entity/Hopper;)Z", at = @At(value = "FIELD", target = "Lnet/minecraft/util/math/Direction;DOWN:Lnet/minecraft/util/math/Direction;", shift = At.Shift.AFTER), cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD) - private static void lithiumExtract(World world, Hopper to, CallbackInfoReturnable cir, Inventory from) { + private static void lithiumExtract(World world, Hopper to, CallbackInfoReturnable cir, BlockPos blockPos, BlockState blockState, Inventory from) { if (!(to instanceof HopperBlockEntityMixin hopperBlockEntity)) { return; //optimizations not implemented for hopper minecarts } @@ -316,6 +307,17 @@ private static boolean lithiumHopperIsEmpty(HopperBlockEntity hopperBlockEntity) @Shadow private static native boolean canExtract(Inventory hopperInventory, Inventory fromInventory, ItemStack stack, int slot, Direction facing); + @Shadow + private Direction facing; + + @Shadow + @Nullable + private static native Inventory getBlockInventoryAt(World world, BlockPos pos, BlockState state); + + @Shadow + @Nullable + protected static native Inventory getInputInventory(World world, Hopper hopper, BlockPos pos, BlockState state); + @Override public void lithium$invalidateCacheOnNeighborUpdate(boolean fromAbove) { //Clear the block inventory cache (composter inventories and no inventory present) on block update / observer update @@ -338,22 +340,10 @@ private static boolean lithiumHopperIsEmpty(HopperBlockEntity hopperBlockEntity) } } - @Redirect(method = "insert(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;Lnet/minecraft/inventory/Inventory;)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/entity/HopperBlockEntity;getOutputInventory(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;)Lnet/minecraft/inventory/Inventory;")) - private static Inventory nullify(World world, BlockPos pos, BlockState state) { - return null; - } - - @ModifyVariable( - method = "insert(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;Lnet/minecraft/inventory/Inventory;)Z", - at = @At( - value = "INVOKE_ASSIGN", - target = "Lnet/minecraft/block/entity/HopperBlockEntity;getOutputInventory(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;)Lnet/minecraft/inventory/Inventory;" - ), - ordinal = 1 - ) - private static Inventory getLithiumOutputInventory(Inventory inventory, World world, BlockPos pos, BlockState hopperState, Inventory hopper) { - HopperBlockEntityMixin hopperBlockEntity = (HopperBlockEntityMixin) hopper; - return hopperBlockEntity.getInsertInventory(world, hopperState); + @Redirect(method = "insert(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/entity/HopperBlockEntity;)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/entity/HopperBlockEntity;getOutputInventory(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/entity/HopperBlockEntity;)Lnet/minecraft/inventory/Inventory;")) + private static Inventory getLithiumOutputInventory(World world, BlockPos pos, HopperBlockEntity blockEntity) { + HopperBlockEntityMixin hopperBlockEntity = (HopperBlockEntityMixin) (Object) blockEntity; + return hopperBlockEntity.getInsertInventory(world); } @Redirect(method = "extract(Lnet/minecraft/world/World;Lnet/minecraft/block/entity/Hopper;)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/entity/HopperBlockEntity;getInputItemEntities(Lnet/minecraft/world/World;Lnet/minecraft/block/entity/Hopper;)Ljava/util/List;")) @@ -374,7 +364,7 @@ private static List lithiumGetInputItemEntities(World world, Hopper hopperBlockEntity.myModCountAtLastItemCollect = modCount; hopperBlockEntity.shouldCheckSleep = false; - List itemEntities = hopperBlockEntity.collectItemEntityTracker.getEntities(hopperBlockEntity.collectItemEntityBoxes); + List itemEntities = hopperBlockEntity.collectItemEntityTracker.getEntities(hopperBlockEntity.collectItemEntityBox); hopperBlockEntity.collectItemEntityAttemptTime = hopperBlockEntity.lastTickTime; hopperBlockEntity.collectItemEntityTrackerWasEmpty = itemEntities.isEmpty(); //set unchanged so that if this extract fails and there is no other change to hoppers or items, extracting @@ -430,23 +420,6 @@ private void cacheExtractLithiumInventory(LithiumInventory optimizedInventory) { this.extractStackListModCount = extractInventoryStackList.getModCount() - 1; } - /** - * @author 2No2Name - * @reason avoid stream code - */ - @Overwrite - private static boolean isInventoryEmpty(Inventory inv, Direction side) { - int[] availableSlots = inv instanceof SidedInventory ? ((SidedInventory) inv).getAvailableSlots(side) : null; - int fromSize = availableSlots != null ? availableSlots.length : inv.size(); - for (int i = 0; i < fromSize; i++) { - int slot = availableSlots != null ? availableSlots[i] : i; - if (!inv.getStack(slot).isEmpty()) { - return false; - } - } - return true; - } - /** * Makes this hopper remember the given inventory. * @@ -481,7 +454,7 @@ private void cacheExtractBlockInventory(Inventory extractInventory) { } } - public Inventory getExtractBlockInventory(World world) { + public Inventory getExtractBlockInventory(World world, BlockPos extractBlockPos, BlockState extractBlockState) { Inventory blockInventory = this.extractBlockInventory; if (this.extractionMode == HopperCachingState.BlockInventory.NO_BLOCK_INVENTORY) { return null; @@ -493,11 +466,7 @@ public Inventory getExtractBlockInventory(World world) { BlockEntity blockEntity = (BlockEntity) Objects.requireNonNull(blockInventory); //Movable Block Entity compatibility - position comparison BlockPos pos = blockEntity.getPos(); - BlockPos thisPos = this.getPos(); - if (!(blockEntity).isRemoved() && - pos.getX() == thisPos.getX() && - pos.getY() == thisPos.getY() + 1 && - pos.getZ() == thisPos.getZ()) { + if (!(blockEntity).isRemoved() && pos.equals(extractBlockPos)) { LithiumInventory optimizedInventory; if ((optimizedInventory = this.extractInventory) != null) { LithiumStackList insertInventoryStackList = InventoryHelper.getLithiumStackList(optimizedInventory); @@ -514,13 +483,13 @@ public Inventory getExtractBlockInventory(World world) { } //No Cached Inventory: Get like vanilla and cache - blockInventory = HopperHelper.vanillaGetBlockInventory(world, this.getPos().up()); + blockInventory = getBlockInventoryAt(world, extractBlockPos, extractBlockState); blockInventory = HopperHelper.replaceDoubleInventory(blockInventory); this.cacheExtractBlockInventory(blockInventory); return blockInventory; } - public Inventory getInsertBlockInventory(World world, BlockState hopperState) { + public Inventory getInsertBlockInventory(World world) { Inventory blockInventory = this.insertBlockInventory; if (this.insertionMode == HopperCachingState.BlockInventory.NO_BLOCK_INVENTORY) { return null; @@ -532,7 +501,7 @@ public Inventory getInsertBlockInventory(World world, BlockState hopperState) { BlockEntity blockEntity = (BlockEntity) Objects.requireNonNull(blockInventory); //Movable Block Entity compatibility - position comparison BlockPos pos = blockEntity.getPos(); - Direction direction = hopperState.get(HopperBlock.FACING); + Direction direction = this.facing; BlockPos transferPos = this.getPos().offset(direction); if (!(blockEntity).isRemoved() && pos.equals(transferPos)) { @@ -552,22 +521,24 @@ public Inventory getInsertBlockInventory(World world, BlockState hopperState) { } //No Cached Inventory: Get like vanilla and cache - Direction direction = hopperState.get(HopperBlock.FACING); - blockInventory = HopperHelper.vanillaGetBlockInventory(world, this.getPos().offset(direction)); + Direction direction = this.facing; + BlockPos insertBlockPos = this.getPos().offset(direction); + BlockState blockState = world.getBlockState(insertBlockPos); + blockInventory = getBlockInventoryAt(world, insertBlockPos, blockState); blockInventory = HopperHelper.replaceDoubleInventory(blockInventory); this.cacheInsertBlockInventory(blockInventory); return blockInventory; } - public Inventory getInsertInventory(World world, BlockState hopperState) { - Inventory blockInventory = this.getInsertBlockInventory(world, hopperState); + public Inventory getInsertInventory(World world) { + Inventory blockInventory = this.getInsertBlockInventory(world); if (blockInventory != null) { return blockInventory; } if (this.insertInventoryEntityTracker == null) { - this.initInsertInventoryTracker(world, hopperState); + this.initInsertInventoryTracker(world); } if (this.insertInventoryEntityTracker.isUnchangedSince(this.insertInventoryEntityFailedSearchTime)) { this.insertInventoryEntityFailedSearchTime = this.lastTickTime; @@ -597,23 +568,12 @@ public Inventory getInsertInventory(World world, BlockState hopperState) { private void initCollectItemEntityTracker() { assert this.world instanceof ServerWorld; - List list = new ArrayList<>(); - Box encompassingBox = null; - for (Box box : HopperHelper.getHopperPickupVolumeBoxes(this)) { - Box offsetBox = box.offset(this.pos.getX(), this.pos.getY(), this.pos.getZ()); - list.add(offsetBox); - if (encompassingBox == null) { - encompassingBox = offsetBox; - } else { - encompassingBox = encompassingBox.union(offsetBox); - } - } - list.add(encompassingBox); - this.collectItemEntityBoxes = list.toArray(new Box[0]); + Box inputBox = this.getInputAreaShape(); + this.collectItemEntityBox = inputBox; this.collectItemEntityTracker = SectionedItemEntityMovementTracker.registerAt( (ServerWorld) this.world, - encompassingBox, + inputBox, ItemEntity.class ); this.collectItemEntityAttemptTime = Long.MIN_VALUE; @@ -632,9 +592,9 @@ private void initExtractInventoryTracker(World world) { this.extractInventoryEntityFailedSearchTime = Long.MIN_VALUE; } - private void initInsertInventoryTracker(World world, BlockState hopperState) { + private void initInsertInventoryTracker(World world) { assert world instanceof ServerWorld; - Direction direction = hopperState.get(HopperBlock.FACING); + Direction direction = this.facing; BlockPos pos = this.pos.offset(direction); this.insertInventoryEntityBox = new Box(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1); this.insertInventoryEntityTracker = @@ -647,14 +607,7 @@ private void initInsertInventoryTracker(World world, BlockState hopperState) { } //Cached data invalidation: - @SuppressWarnings("deprecation") - @Intrinsic - @Override - public void setCachedState(BlockState state) { - super.setCachedState(state); - } - @SuppressWarnings({"MixinAnnotationTarget", "UnresolvedMixinReference"}) @Inject(method = "setCachedState(Lnet/minecraft/block/BlockState;)V", at = @At("HEAD")) private void invalidateOnSetCachedState(BlockState state, CallbackInfo ci) { if (this.world != null && !this.world.isClient() && state.get(HopperBlock.FACING) != this.getCachedState().get(HopperBlock.FACING)) { @@ -708,7 +661,7 @@ private void invalidateExtractionData() { if (this.collectItemEntityTracker != null) { this.collectItemEntityTracker.unRegister(serverWorld); this.collectItemEntityTracker = null; - this.collectItemEntityBoxes = null; + this.collectItemEntityBox = null; this.collectItemEntityTrackerWasEmpty = false; } } @@ -811,7 +764,7 @@ private void checkSleepingConditions() { } if (listenToInsertEntities) { if (this.insertInventoryEntityTracker == null) { - this.initInsertInventoryTracker(this.world, this.getCachedState()); + this.initInsertInventoryTracker(this.world); } this.insertInventoryEntityTracker.listenToEntityMovementOnce(this); } diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/block/hopper/HopperBlockMixin.java b/src/main/java/me/jellysquid/mods/lithium/mixin/block/hopper/HopperBlockMixin.java index b53fead6b..94fbff749 100644 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/block/hopper/HopperBlockMixin.java +++ b/src/main/java/me/jellysquid/mods/lithium/mixin/block/hopper/HopperBlockMixin.java @@ -22,7 +22,6 @@ protected HopperBlockMixin(Settings settings) { super(settings); } - @SuppressWarnings("deprecation") @Intrinsic @Override public BlockState getStateForNeighborUpdate(BlockState myBlockState, Direction direction, BlockState newState, WorldAccess world, BlockPos myPos, BlockPos posFrom) { diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/entity/collisions/unpushable_cramming/EntityMixin.java b/src/main/java/me/jellysquid/mods/lithium/mixin/entity/collisions/unpushable_cramming/EntityMixin.java index dec57863f..595a00dab 100644 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/entity/collisions/unpushable_cramming/EntityMixin.java +++ b/src/main/java/me/jellysquid/mods/lithium/mixin/entity/collisions/unpushable_cramming/EntityMixin.java @@ -14,7 +14,7 @@ @Mixin(Entity.class) public class EntityMixin implements BlockCachingEntity { @Shadow - private @Nullable BlockState blockStateAtPos; + private @Nullable BlockState stateAtPos; @Inject( method = "setPos(DDD)V", @@ -51,11 +51,11 @@ private void onBaseTick(CallbackInfo ci) { ) ) private void onBlockCached(CallbackInfoReturnable cir) { - this.lithium$OnBlockCacheSet(this.blockStateAtPos); + this.lithium$OnBlockCacheSet(this.stateAtPos); } @Override public BlockState lithium$getCachedFeetBlockState() { - return this.blockStateAtPos; + return this.stateAtPos; } } diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/entity/data_tracker/no_locks/DataTrackerMixin.java b/src/main/java/me/jellysquid/mods/lithium/mixin/entity/data_tracker/no_locks/DataTrackerMixin.java deleted file mode 100644 index 76ab87e5c..000000000 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/entity/data_tracker/no_locks/DataTrackerMixin.java +++ /dev/null @@ -1,38 +0,0 @@ -package me.jellysquid.mods.lithium.mixin.entity.data_tracker.no_locks; - -import me.jellysquid.mods.lithium.common.util.lock.NullReadWriteLock; -import net.minecraft.entity.Entity; -import net.minecraft.entity.data.DataTracker; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Mutable; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import java.util.concurrent.locks.ReadWriteLock; - -/** - * The vanilla implementation of {@link DataTracker} performs locking when fetching or updating data due to a legacy - * quirk in older versions of the game where updates would occur on a network thread for (de)serialization while entities - * were ticking and accessing values from it on the main thread. In newer versions (1.14+) this no longer happens. - *

- * The DataTracker is expected to only ever updated on the main-thread (or the thread owning it in recent versions when - * baking entities) during entity initialization and main-thread network updates, and as such the locking mechanism - * is unnecessary since the job is to only protect against simultaneous reading and writing. - */ -@Mixin(value = DataTracker.class, priority = 1001) -public abstract class DataTrackerMixin { - private static final NullReadWriteLock NULL_READ_WRITE_LOCK = new NullReadWriteLock(); - - @Mutable - @Shadow - @Final - private ReadWriteLock lock; - - @Inject(method = "(Lnet/minecraft/entity/Entity;)V", at = @At("RETURN")) - private void init(Entity entity, CallbackInfo ci) { - this.lock = NULL_READ_WRITE_LOCK; - } -} diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/entity/data_tracker/no_locks/package-info.java b/src/main/java/me/jellysquid/mods/lithium/mixin/entity/data_tracker/no_locks/package-info.java deleted file mode 100644 index 7c27a06cb..000000000 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/entity/data_tracker/no_locks/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -@MixinConfigOption(description = "Remove unnecessary locking when accessing the data tracker") -package me.jellysquid.mods.lithium.mixin.entity.data_tracker.no_locks; - -import net.caffeinemc.gradle.MixinConfigOption; \ No newline at end of file diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/entity/data_tracker/package-info.java b/src/main/java/me/jellysquid/mods/lithium/mixin/entity/data_tracker/package-info.java deleted file mode 100644 index 145bb97cb..000000000 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/entity/data_tracker/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -@MixinConfigOption(description = "Various entity data tracker optimizations") -package me.jellysquid.mods.lithium.mixin.entity.data_tracker; - -import net.caffeinemc.gradle.MixinConfigOption; \ No newline at end of file diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/entity/data_tracker/use_arrays/DataTrackerMixin.java b/src/main/java/me/jellysquid/mods/lithium/mixin/entity/data_tracker/use_arrays/DataTrackerMixin.java deleted file mode 100644 index 19c14319f..000000000 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/entity/data_tracker/use_arrays/DataTrackerMixin.java +++ /dev/null @@ -1,112 +0,0 @@ -package me.jellysquid.mods.lithium.mixin.entity.data_tracker.use_arrays; - -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import net.minecraft.entity.data.DataTracker; -import net.minecraft.entity.data.TrackedData; -import net.minecraft.util.crash.CrashException; -import net.minecraft.util.crash.CrashReport; -import net.minecraft.util.crash.CrashReportSection; -import org.spongepowered.asm.mixin.*; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -import java.util.Arrays; -import java.util.concurrent.locks.ReadWriteLock; - -/** - * Optimizes the DataTracker to use a simple array-based storage for entries and avoids integer boxing. This reduces - * a lot of the overhead associated with retrieving tracked data about an entity. - */ -@Mixin(DataTracker.class) -public abstract class DataTrackerMixin { - private static final int DEFAULT_ENTRY_COUNT = 10, GROW_FACTOR = 8; - - @Shadow - @Final - private ReadWriteLock lock; - - @Mutable - @Shadow - @Final - private Int2ObjectMap> entries; - /** - * Mirrors the vanilla backing entries map. Each DataTracker.Entry can be accessed in this array through its ID. - **/ - private DataTracker.Entry[] entriesArray = new DataTracker.Entry[DEFAULT_ENTRY_COUNT]; - - /** - * We redirect the call to add a tracked data to the internal map so we can add it to our new storage structure. This - * should only ever occur during entity initialization. Type-erasure is a bit of a pain here since we must redirect - * a calls to the generic Map interface. - */ - @Redirect( - method = "addTrackedData(Lnet/minecraft/entity/data/TrackedData;Ljava/lang/Object;)V", - at = @At( - value = "INVOKE", - target = "Lit/unimi/dsi/fastutil/ints/Int2ObjectMap;put(ILjava/lang/Object;)Ljava/lang/Object;", - remap = false - ) - ) - private Object onAddTrackedDataInsertMap(Int2ObjectMap int2ObjectMap, int k, Object valueRaw) { - DataTracker.Entry v = (DataTracker.Entry) valueRaw; - - DataTracker.Entry[] storage = this.entriesArray; - - // Check if we need to grow the backing array to accommodate the new key range - if (storage.length <= k) { - // Grow the array to accommodate 8 entries after this one, but limit it to never be larger - // than 256 entries as per the vanilla limit - int newSize = Math.min(k + GROW_FACTOR, 256); - - this.entriesArray = storage = Arrays.copyOf(storage, newSize); - } - - // Update the storage - storage[k] = v; - - // Ensure that the vanilla backing storage is still updated appropriately - return this.entries.put(k, v); - } - - /** - * @reason Avoid integer boxing/unboxing and use our array-based storage - * @author JellySquid - */ - @Overwrite - private DataTracker.Entry getEntry(TrackedData data) { - this.lock.readLock().lock(); - - try { - DataTracker.Entry[] array = this.entriesArray; - - int id = data.getId(); - - // The vanilla implementation will simply return null if the tracker doesn't contain the specified entry. However, - // accessing an array with an invalid pointer will throw a OOB exception, where-as a HashMap would simply - // return null. We check this case (which should be free, even if so insignificant, as the subsequent bounds - // check will hopefully be eliminated) - if (id < 0 || id >= array.length) { - return null; - } - - // This cast can fail if trying to access a entry which doesn't belong to this tracker, as the ID could - // instead point to an entry of a different type. However, that is also vanilla behaviour. - // noinspection unchecked - return (DataTracker.Entry) array[id]; - } catch (Throwable cause) { - // Move to another method so this function can be in-lined better - throw onGetException(cause, data); - } finally { - this.lock.readLock().unlock(); - } - } - - private static CrashException onGetException(Throwable cause, TrackedData data) { - CrashReport report = CrashReport.create(cause, "Getting synced entity data"); - - CrashReportSection section = report.addElement("Synced entity data"); - section.add("Data ID", data); - - return new CrashException(report); - } -} diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/entity/data_tracker/use_arrays/package-info.java b/src/main/java/me/jellysquid/mods/lithium/mixin/entity/data_tracker/use_arrays/package-info.java deleted file mode 100644 index 2407e4e7d..000000000 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/entity/data_tracker/use_arrays/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -@MixinConfigOption(description = "Data trackers use a custom optimized entry map") -package me.jellysquid.mods.lithium.mixin.entity.data_tracker.use_arrays; - -import net.caffeinemc.gradle.MixinConfigOption; \ No newline at end of file diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/entity/fast_powder_snow_check/LivingEntityMixin.java b/src/main/java/me/jellysquid/mods/lithium/mixin/entity/fast_powder_snow_check/LivingEntityMixin.java index f0fb10bce..825c03a1a 100644 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/entity/fast_powder_snow_check/LivingEntityMixin.java +++ b/src/main/java/me/jellysquid/mods/lithium/mixin/entity/fast_powder_snow_check/LivingEntityMixin.java @@ -6,6 +6,7 @@ import net.minecraft.entity.LivingEntity; import net.minecraft.entity.attribute.EntityAttribute; import net.minecraft.entity.attribute.EntityAttributeInstance; +import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; @@ -17,8 +18,7 @@ public abstract class LivingEntityMixin extends Entity { @Shadow - public @Nullable - abstract EntityAttributeInstance getAttributeInstance(EntityAttribute attribute); + public abstract @Nullable EntityAttributeInstance getAttributeInstance(RegistryEntry attribute); public LivingEntityMixin(EntityType type, World world) { super(type, world); @@ -50,10 +50,10 @@ private boolean delayAirTest(BlockState instance) { method = "addPowderSnowSlowIfNeeded()V", at = @At( value = "INVOKE", - target = "Lnet/minecraft/entity/LivingEntity;getAttributeInstance(Lnet/minecraft/entity/attribute/EntityAttribute;)Lnet/minecraft/entity/attribute/EntityAttributeInstance;" + target = "Lnet/minecraft/entity/LivingEntity;getAttributeInstance(Lnet/minecraft/registry/entry/RegistryEntry;)Lnet/minecraft/entity/attribute/EntityAttributeInstance;" ) ) - private EntityAttributeInstance doDelayedBlockStateAirTest(LivingEntity instance, EntityAttribute attribute) { + private EntityAttributeInstance doDelayedBlockStateAirTest(LivingEntity instance, RegistryEntry attribute) { //noinspection deprecation return this.getLandingBlockState().isAir() ? null : this.getAttributeInstance(attribute); } diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/entity/hopper_minecart/HopperBlockEntityMixin.java b/src/main/java/me/jellysquid/mods/lithium/mixin/entity/hopper_minecart/HopperBlockEntityMixin.java deleted file mode 100644 index fbc77bf21..000000000 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/entity/hopper_minecart/HopperBlockEntityMixin.java +++ /dev/null @@ -1,39 +0,0 @@ -package me.jellysquid.mods.lithium.mixin.entity.hopper_minecart; - -import me.jellysquid.mods.lithium.common.world.ItemEntityHelper; -import net.minecraft.block.entity.Hopper; -import net.minecraft.block.entity.HopperBlockEntity; -import net.minecraft.entity.ItemEntity; -import net.minecraft.predicate.entity.EntityPredicates; -import net.minecraft.util.math.Box; -import net.minecraft.world.World; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; - -import java.util.Collections; -import java.util.List; - -@Mixin(HopperBlockEntity.class) -public class HopperBlockEntityMixin { - - /** - * @author 2No2Name - * @reason avoid checking 5 boxes - *

- * This code is run by hopper minecarts. Hopper blocks use a different optimization unless it is disabled. - */ - @Overwrite - public static List getInputItemEntities(World world, Hopper hopper) { - Box encompassingBox = hopper.getInputAreaShape().getBoundingBox(); - double xOffset = hopper.getHopperX() - 0.5; - double yOffset = hopper.getHopperY() - 0.5; - double zOffset = hopper.getHopperZ() - 0.5; - List nearbyEntities = world.getEntitiesByClass(ItemEntity.class, encompassingBox.offset(xOffset, yOffset, zOffset), EntityPredicates.VALID_ENTITY); - - if (nearbyEntities.isEmpty()) { - return Collections.emptyList(); - } - - return ItemEntityHelper.getItemEntityBucketedList(hopper, xOffset, yOffset, zOffset, nearbyEntities); - } -} diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/entity/hopper_minecart/package-info.java b/src/main/java/me/jellysquid/mods/lithium/mixin/entity/hopper_minecart/package-info.java deleted file mode 100644 index 68e2bc07a..000000000 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/entity/hopper_minecart/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -@MixinConfigOption(description = "Hopper minecarts search for item entities faster by combining multiple item entity searches. Also eliminates duplicated item entity pickup attempts") -package me.jellysquid.mods.lithium.mixin.entity.hopper_minecart; - -import net.caffeinemc.gradle.MixinConfigOption; \ No newline at end of file diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/experimental/chunk_tickets/ChunkTicketManagerMixin.java b/src/main/java/me/jellysquid/mods/lithium/mixin/experimental/chunk_tickets/ChunkTicketManagerMixin.java index 3f5c922c5..2f2e13a92 100644 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/experimental/chunk_tickets/ChunkTicketManagerMixin.java +++ b/src/main/java/me/jellysquid/mods/lithium/mixin/experimental/chunk_tickets/ChunkTicketManagerMixin.java @@ -59,7 +59,7 @@ private static boolean canExpire(ChunkTicket ticket) { at = @At(value = "INVOKE", target = "Lnet/minecraft/server/world/ChunkTicket;setTickCreated(J)V"), locals = LocalCapture.CAPTURE_FAILHARD ) - private void registerExpiringTicket(long position, ChunkTicket ticket, CallbackInfo ci, SortedArraySet> ticketsAtPos, int i, ChunkTicket chunkTicket) { + private void registerExpiringTicket(long position, ChunkTicket ticket, CallbackInfo ci, ChunkTicket ticket2, SortedArraySet> ticketsAtPos, int i, ChunkTicket chunkTicket) { if (canExpire(ticket)) { this.positionWithExpiringTicket.put(position, ticketsAtPos); } @@ -86,7 +86,7 @@ private void unregisterExpiringTicket(long pos, ChunkTicket ticket, CallbackI ), locals = LocalCapture.CAPTURE_FAILHARD ) - private void updateSetMinExpiryTime(long position, ChunkTicket ticket, CallbackInfo ci, SortedArraySet> sortedArraySet, int i) { + private void updateSetMinExpiryTime(long position, ChunkTicket ticket, CallbackInfo ci, ChunkTicket ticket2, SortedArraySet sortedArraySet, int i) { if (canExpire(ticket) && sortedArraySet instanceof ChunkTicketSortedArraySet chunkTickets) { chunkTickets.addExpireTime(this.age + ticket.getType().getExpiryTicks()); } diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/util/inventory_change_listening/StackListReplacementTracking.java b/src/main/java/me/jellysquid/mods/lithium/mixin/util/inventory_change_listening/StackListReplacementTracking.java index c0a748a30..305998e17 100644 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/util/inventory_change_listening/StackListReplacementTracking.java +++ b/src/main/java/me/jellysquid/mods/lithium/mixin/util/inventory_change_listening/StackListReplacementTracking.java @@ -4,6 +4,7 @@ import net.minecraft.block.entity.*; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NbtCompound; +import net.minecraft.registry.RegistryWrapper; import net.minecraft.util.collection.DefaultedList; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -25,7 +26,7 @@ public abstract static class InventoryChangeTrackingBrewingStandBlockEntity impl @Mixin(LockableContainerBlockEntity.class) public abstract static class StackListReplacementTrackingLockableContainerBlockEntity { @Inject(method = "readNbt", at = @At("RETURN" )) - public void readNbtStackListReplacement(NbtCompound nbt, CallbackInfo ci) { + public void readNbtStackListReplacement(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup, CallbackInfo ci) { if (this instanceof InventoryChangeTracker inventoryChangeTracker) { inventoryChangeTracker.lithium$emitStackListReplaced(); } @@ -34,7 +35,7 @@ public void readNbtStackListReplacement(NbtCompound nbt, CallbackInfo ci) { @Mixin(BarrelBlockEntity.class) public abstract static class InventoryChangeTrackingBarrelBlockEntity implements InventoryChangeTracker { - @Inject(method = "setInvStackList", at = @At("RETURN" )) + @Inject(method = "setHeldStacks", at = @At("RETURN")) public void setInventoryStackListReplacement(DefaultedList list, CallbackInfo ci) { this.lithium$emitStackListReplaced(); } @@ -42,7 +43,7 @@ public void setInventoryStackListReplacement(DefaultedList list, Call @Mixin(ChestBlockEntity.class) public abstract static class InventoryChangeTrackingChestBlockEntity implements InventoryChangeTracker { - @Inject(method = "setInvStackList", at = @At("RETURN" )) + @Inject(method = "setHeldStacks", at = @At("RETURN")) public void setInventoryStackListReplacement(DefaultedList list, CallbackInfo ci) { this.lithium$emitStackListReplaced(); } @@ -50,7 +51,7 @@ public void setInventoryStackListReplacement(DefaultedList list, Call @Mixin(DispenserBlockEntity.class) public abstract static class InventoryChangeTrackingDispenserBlockEntity implements InventoryChangeTracker { - @Inject(method = "setInvStackList", at = @At("RETURN" )) + @Inject(method = "setHeldStacks", at = @At("RETURN")) public void setInventoryStackListReplacement(DefaultedList list, CallbackInfo ci) { this.lithium$emitStackListReplaced(); } @@ -58,7 +59,7 @@ public void setInventoryStackListReplacement(DefaultedList list, Call @Mixin(HopperBlockEntity.class) public abstract static class InventoryChangeTrackingHopperBlockEntity implements InventoryChangeTracker { - @Inject(method = "setInvStackList", at = @At("RETURN" )) + @Inject(method = "setHeldStacks", at = @At("RETURN")) public void setInventoryStackListReplacement(DefaultedList list, CallbackInfo ci) { this.lithium$emitStackListReplaced(); } @@ -66,7 +67,7 @@ public void setInventoryStackListReplacement(DefaultedList list, Call @Mixin(ShulkerBoxBlockEntity.class) public abstract static class InventoryChangeTrackingShulkerBoxBlockEntity implements InventoryChangeTracker { - @Inject(method = "setInvStackList", at = @At("RETURN" )) + @Inject(method = "setHeldStacks", at = @At("RETURN")) public void setInventoryStackListReplacement(DefaultedList list, CallbackInfo ci) { this.lithium$emitStackListReplaced(); } diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/world/block_entity_ticking/sleeping/campfire/CampfireBlockEntityMixin.java b/src/main/java/me/jellysquid/mods/lithium/mixin/world/block_entity_ticking/sleeping/campfire/CampfireBlockEntityMixin.java index e4875e74d..1c30143fa 100644 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/world/block_entity_ticking/sleeping/campfire/CampfireBlockEntityMixin.java +++ b/src/main/java/me/jellysquid/mods/lithium/mixin/world/block_entity_ticking/sleeping/campfire/CampfireBlockEntityMixin.java @@ -9,6 +9,7 @@ import net.minecraft.entity.Entity; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NbtCompound; +import net.minecraft.registry.RegistryWrapper; import net.minecraft.util.math.BlockPos; import net.minecraft.world.chunk.BlockEntityTickInvoker; import org.spongepowered.asm.mixin.Mixin; @@ -61,7 +62,7 @@ private void wakeUpOnAddItem(Entity user, ItemStack stack, int cookTime, Callbac method = "readNbt", at = @At(value = "RETURN") ) - private void wakeUpOnReadNbt(NbtCompound nbt, CallbackInfo ci) { + private void wakeUpOnReadNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup, CallbackInfo ci) { this.wakeUpNow(); } } diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/world/chunk_access/ChunkHolderMixin.java b/src/main/java/me/jellysquid/mods/lithium/mixin/world/chunk_access/ChunkHolderMixin.java index fe6fdb858..414f89870 100644 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/world/chunk_access/ChunkHolderMixin.java +++ b/src/main/java/me/jellysquid/mods/lithium/mixin/world/chunk_access/ChunkHolderMixin.java @@ -1,8 +1,8 @@ package me.jellysquid.mods.lithium.mixin.world.chunk_access; -import com.mojang.datafixers.util.Either; import me.jellysquid.mods.lithium.common.world.chunk.ChunkHolderExtended; import net.minecraft.server.world.ChunkHolder; +import net.minecraft.server.world.OptionalChunk; import net.minecraft.world.chunk.Chunk; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -13,19 +13,20 @@ @Mixin(ChunkHolder.class) public class ChunkHolderMixin implements ChunkHolderExtended { + ; + @Shadow @Final - private AtomicReferenceArray>> futuresByStatus; - + private AtomicReferenceArray>> futuresByStatus; private long lastRequestTime; @Override - public CompletableFuture> lithium$getFutureByStatus(int index) { + public CompletableFuture> lithium$getFutureByStatus(int index) { return this.futuresByStatus.get(index); } @Override - public void lithium$setFutureForStatus(int index, CompletableFuture> future) { + public void lithium$setFutureForStatus(int index, CompletableFuture> future) { this.futuresByStatus.set(index, future); } diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/world/chunk_access/ServerChunkManagerMixin.java b/src/main/java/me/jellysquid/mods/lithium/mixin/world/chunk_access/ServerChunkManagerMixin.java index a1229f470..e7e793b29 100644 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/world/chunk_access/ServerChunkManagerMixin.java +++ b/src/main/java/me/jellysquid/mods/lithium/mixin/world/chunk_access/ServerChunkManagerMixin.java @@ -1,6 +1,5 @@ package me.jellysquid.mods.lithium.mixin.world.chunk_access; -import com.mojang.datafixers.util.Either; import me.jellysquid.mods.lithium.common.world.chunk.ChunkHolderExtended; import net.minecraft.server.world.*; import net.minecraft.util.Util; @@ -16,7 +15,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.Arrays; -import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.function.BooleanSupplier; @@ -160,19 +158,18 @@ private Chunk getChunkBlocking(int x, int z, ChunkStatus status, boolean create) this.createChunkLoadTicket(x, z, level); } - CompletableFuture> loadFuture = null; - CompletableFuture> statusFuture = ((ChunkHolderExtended) holder).lithium$getFutureByStatus(status.getIndex()); + CompletableFuture> loadFuture = null; + CompletableFuture> statusFuture = ((ChunkHolderExtended) holder).lithium$getFutureByStatus(status.getIndex()); if (statusFuture != null) { - Either immediate = statusFuture.getNow(null); + OptionalChunk optionalChunk = statusFuture.getNow(null); // If the result is already available, return it - if (immediate != null) { - Optional chunk = immediate.left(); + if (optionalChunk != null) { - if (chunk.isPresent()) { + if (optionalChunk.isPresent()) { // Early-return with the already ready chunk - return chunk.get(); + return optionalChunk.orElse(null); } } else { // The load future will first start with the existing future for this status @@ -184,7 +181,7 @@ private Chunk getChunkBlocking(int x, int z, ChunkStatus status, boolean create) if (loadFuture == null) { if (ChunkLevels.getStatus(holder.getLevel()).isAtLeast(status)) { // Create a new future which upgrades the chunk from the previous status level to the desired one - CompletableFuture> mergedFuture = this.threadedAnvilChunkStorage.getChunk(holder, status); + CompletableFuture> mergedFuture = this.threadedAnvilChunkStorage.getChunk(holder, status); // Add this future to the chunk holder so subsequent calls will see it holder.combineSavingFuture(mergedFuture, "schedule chunk status"); @@ -210,7 +207,7 @@ private Chunk getChunkBlocking(int x, int z, ChunkStatus status, boolean create) } // Wait for the result of the future and unwrap it, returning null if the chunk is absent - return loadFuture.join().left().orElse(null); + return loadFuture.join().orElse(null); } private void createChunkLoadTicket(int x, int z, int level) { diff --git a/src/main/java/me/jellysquid/mods/lithium/mixin/world/explosions/ExplosionMixin.java b/src/main/java/me/jellysquid/mods/lithium/mixin/world/explosions/ExplosionMixin.java index d3c6770ac..5e71d01a1 100644 --- a/src/main/java/me/jellysquid/mods/lithium/mixin/world/explosions/ExplosionMixin.java +++ b/src/main/java/me/jellysquid/mods/lithium/mixin/world/explosions/ExplosionMixin.java @@ -11,7 +11,7 @@ import net.minecraft.fluid.FluidState; import net.minecraft.fluid.Fluids; import net.minecraft.particle.ParticleEffect; -import net.minecraft.sound.SoundEvent; +import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.random.Random; @@ -85,10 +85,10 @@ public abstract class ExplosionMixin { private int minY, maxY; @Inject( - method = "(Lnet/minecraft/world/World;Lnet/minecraft/entity/Entity;Lnet/minecraft/entity/damage/DamageSource;Lnet/minecraft/world/explosion/ExplosionBehavior;DDDFZLnet/minecraft/world/explosion/Explosion$DestructionType;Lnet/minecraft/particle/ParticleEffect;Lnet/minecraft/particle/ParticleEffect;Lnet/minecraft/sound/SoundEvent;)V", + method = "(Lnet/minecraft/world/World;Lnet/minecraft/entity/Entity;Lnet/minecraft/entity/damage/DamageSource;Lnet/minecraft/world/explosion/ExplosionBehavior;DDDFZLnet/minecraft/world/explosion/Explosion$DestructionType;Lnet/minecraft/particle/ParticleEffect;Lnet/minecraft/particle/ParticleEffect;Lnet/minecraft/registry/entry/RegistryEntry;)V", at = @At("TAIL") ) - private void init(World world, Entity entity, DamageSource damageSource, ExplosionBehavior behavior, double x, double y, double z, float power, boolean createFire, Explosion.DestructionType destructionType, ParticleEffect particle, ParticleEffect emitterParticle, SoundEvent soundEvent, CallbackInfo ci) { + private void init(World world, Entity entity, DamageSource damageSource, ExplosionBehavior behavior, double x, double y, double z, float power, boolean createFire, Explosion.DestructionType destructionType, ParticleEffect particle, ParticleEffect emitterParticle, RegistryEntry soundEvent, CallbackInfo ci) { this.minY = this.world.getBottomY(); this.maxY = this.world.getTopY(); diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 28b97716f..0262f4601 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -27,7 +27,7 @@ "accessWidener": "lithium.accesswidener", "depends": { "fabricloader": ">=0.15.1", - "minecraft": "1.20.4" + "minecraft": "1.20.5-beta.1" }, "breaks": { "optifabric": "*" diff --git a/src/main/resources/lithium.mixins.json b/src/main/resources/lithium.mixins.json index 88826edb1..65cd25800 100644 --- a/src/main/resources/lithium.mixins.json +++ b/src/main/resources/lithium.mixins.json @@ -7,16 +7,12 @@ "defaultRequire": 1 }, "mixins": [ - "ai.nearby_entity_tracking.EntityMixin", - "ai.nearby_entity_tracking.EntityTrackingSectionMixin", - "ai.nearby_entity_tracking.ServerEntityManagerListenerMixin", - "ai.nearby_entity_tracking.ServerEntityManagerMixin", - "ai.nearby_entity_tracking.goals.FleeEntityGoalMixin", - "ai.nearby_entity_tracking.goals.LookAtEntityGoalMixin", "ai.pathing.AbstractBlockStateMixin", "ai.pathing.BirdPathNodeMakerMixin", "ai.pathing.ChunkCacheMixin", "ai.pathing.LandPathNodeMakerMixin", + "ai.pathing.PathContextAccessor", + "ai.pathing.PathContextMixin", "ai.poi.PointOfInterestSetMixin", "ai.poi.PointOfInterestStorageMixin", "ai.poi.PointOfInterestTypesMixin", @@ -28,6 +24,7 @@ "ai.raid.PickupBannerAsLeaderGoalMixin", "ai.raid.RaiderEntityMixin", "ai.raid.RaidMixin", + "ai.raid.WorldMixin", "ai.sensor.secondary_poi.SecondaryPointsOfInterestSensorMixin", "ai.task.launch.BrainMixin", "ai.task.memory_change_counting.BrainMixin", @@ -50,7 +47,6 @@ "alloc.explosion_behavior.EntityExplosionBehaviorMixin", "alloc.nbt.NbtCompoundMixin", "alloc.nbt.NbtCompoundMixin$Type", - "block.beehive.BeehiveBlockEntityMixin", "block.flatten_states.FluidStateMixin", "block.hopper.AbstractMinecartEntityMixin", "block.hopper.ChestBoatEntityMixin", @@ -109,13 +105,10 @@ "entity.collisions.unpushable_cramming.EntityPredicatesMixin", "entity.collisions.unpushable_cramming.EntityTrackingSectionMixin", "entity.collisions.unpushable_cramming.LivingEntityMixin", - "entity.data_tracker.no_locks.DataTrackerMixin", - "entity.data_tracker.use_arrays.DataTrackerMixin", "entity.fast_elytra_check.LivingEntityMixin", "entity.fast_hand_swing.LivingEntityMixin", "entity.fast_powder_snow_check.LivingEntityMixin", "entity.fast_retrieval.SectionedEntityCacheMixin", - "entity.hopper_minecart.HopperBlockEntityMixin", "entity.inactive_navigations.DrownedEntityLeaveWaterGoalMixin", "entity.inactive_navigations.DrownedEntityMixin", "entity.inactive_navigations.EntityNavigationMixin", @@ -139,13 +132,13 @@ "experimental.entity.block_caching.fluid_pushing.EntityMixin", "experimental.entity.block_caching.suffocation.EntityMixin", "experimental.entity.item_entity_merging.ItemEntityMixin", - "experimental.util.item_entity_by_type.ItemEntityMixin", - "experimental.util.item_entity_by_type.TypeFilterableListMixin", "experimental.spawning.EntityTrackingSectionAccessor", "experimental.spawning.SectionedEntityCacheMixin", "experimental.spawning.ServerChunkManagerMixin", "experimental.spawning.ServerEntityManagerAccessor", "experimental.spawning.ServerWorldAccessor", + "experimental.util.item_entity_by_type.ItemEntityMixin", + "experimental.util.item_entity_by_type.TypeFilterableListMixin", "gen.cached_generator_settings.NoiseChunkGeneratorMixin", "gen.chunk_region.ChunkRegionMixin", "math.fast_blockpos.BlockPosMixin",