lithium$getEntityManager() {
19 | return this.entityStorage;
20 | }
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/common/src/main/java/net/caffeinemc/mods/lithium/mixin/util/chunk_access/LevelReaderMixin.java:
--------------------------------------------------------------------------------
1 | package net.caffeinemc.mods.lithium.mixin.util.chunk_access;
2 |
3 | import net.caffeinemc.mods.lithium.common.world.ChunkView;
4 | import net.minecraft.world.level.LevelReader;
5 | import net.minecraft.world.level.chunk.ChunkAccess;
6 | import net.minecraft.world.level.chunk.status.ChunkStatus;
7 | import org.jetbrains.annotations.Nullable;
8 | import org.spongepowered.asm.mixin.Mixin;
9 | import org.spongepowered.asm.mixin.Shadow;
10 |
11 | @Mixin(LevelReader.class)
12 | public interface LevelReaderMixin extends ChunkView {
13 |
14 | @Shadow
15 | @Nullable ChunkAccess getChunk(int var1, int var2, ChunkStatus var3, boolean var4);
16 |
17 | @Override
18 | default @Nullable ChunkAccess lithium$getLoadedChunk(int chunkX, int chunkZ) {
19 | return this.getChunk(chunkX, chunkZ, ChunkStatus.FULL, false);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/fabric/src/main/java/net/caffeinemc/mods/lithium/fabric/mixin/util/inventory_change_listening/BlockEntityMixin.java:
--------------------------------------------------------------------------------
1 | package net.caffeinemc.mods.lithium.fabric.mixin.util.inventory_change_listening;
2 |
3 | import net.caffeinemc.mods.lithium.common.block.entity.SetBlockStateHandlingBlockEntity;
4 | import net.minecraft.world.level.block.entity.BlockEntity;
5 | import org.spongepowered.asm.mixin.Mixin;
6 | import org.spongepowered.asm.mixin.injection.At;
7 | import org.spongepowered.asm.mixin.injection.Inject;
8 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
9 |
10 | @Mixin(BlockEntity.class)
11 | public class BlockEntityMixin implements SetBlockStateHandlingBlockEntity {
12 |
13 | @Inject(method = "setBlockState(Lnet/minecraft/world/level/block/state/BlockState;)V", at = @At("RETURN"))
14 | private void emitRemovedOnSetCachedState(CallbackInfo ci) {
15 | this.lithium$handleSetBlockState();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/common/src/main/java/net/caffeinemc/mods/lithium/common/util/lock/NullLock.java:
--------------------------------------------------------------------------------
1 | package net.caffeinemc.mods.lithium.common.util.lock;
2 |
3 | import java.util.concurrent.TimeUnit;
4 | import java.util.concurrent.locks.Condition;
5 | import java.util.concurrent.locks.Lock;
6 |
7 | /**
8 | * A Lock which doesn't do anything.
9 | */
10 | public class NullLock implements Lock {
11 | @Override
12 | public void lock() {
13 |
14 | }
15 |
16 | @Override
17 | public void lockInterruptibly() {
18 |
19 | }
20 |
21 | @Override
22 | public boolean tryLock() {
23 | return true;
24 | }
25 |
26 | @Override
27 | public boolean tryLock(long time, TimeUnit unit) {
28 | return true;
29 | }
30 |
31 | @Override
32 | public void unlock() {
33 |
34 | }
35 |
36 | @Override
37 | public Condition newCondition() {
38 | throw new UnsupportedOperationException();
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/common/src/main/java/net/caffeinemc/mods/lithium/mixin/world/game_events/dispatch/package-info.java:
--------------------------------------------------------------------------------
1 | @MixinConfigOption(
2 | description = "Create game event dispatchers for chunk sections only when needed, i.e. when a" +
3 | " listener is added to a section. This reduces memory usage for chunks that do not have any listeners." +
4 | " The dispatchers are accessed more directly instead of indirectly through chunks." +
5 | " In total this speeds up attempting to dispatch events especially when there are no nearby listeners.",
6 | depends = {
7 | @MixinConfigDependency(dependencyPath = "mixin.util.data_storage"),
8 | @MixinConfigDependency(dependencyPath = "mixin.util.chunk_status_tracking")
9 | }
10 | )
11 | package net.caffeinemc.mods.lithium.mixin.world.game_events.dispatch;
12 |
13 | import net.caffeinemc.gradle.MixinConfigDependency;
14 | import net.caffeinemc.gradle.MixinConfigOption;
--------------------------------------------------------------------------------
/common/src/main/java/net/caffeinemc/mods/lithium/common/tracking/block/BlockChangeTracker.java:
--------------------------------------------------------------------------------
1 | package net.caffeinemc.mods.lithium.common.tracking.block;
2 |
3 | import net.caffeinemc.mods.lithium.common.block.BlockListeningSection;
4 | import net.minecraft.core.SectionPos;
5 | import net.minecraft.world.level.block.state.BlockState;
6 |
7 | public interface BlockChangeTracker {
8 |
9 | /**
10 | * Handles block changes from the subscribed section.
11 | *
12 | * Staying subscribed to a section can be computationally expensive, since bursts of block changes,
13 | * e.g. redstone wire flicker, can lead to thousands of block changes. Use cautiously!
14 | *
15 | * @return Whether this tracker should stay subscribed.
16 | */
17 | boolean setChanged(BlockListeningSection section, int localX, int localY, int localZ, BlockState oldState, BlockState newState);
18 |
19 | void onChunkSectionInvalidated(SectionPos sectionPos);
20 | }
21 |
--------------------------------------------------------------------------------
/.github/workflows/pull_request.yml:
--------------------------------------------------------------------------------
1 | name: PR CI
2 |
3 | on: [ pull_request ]
4 |
5 | jobs:
6 | Build:
7 | runs-on: ubuntu-latest
8 |
9 | steps:
10 | - name: Checkout Repository
11 | uses: actions/checkout@v4
12 |
13 | - name: Setup JDK 21
14 | uses: actions/setup-java@v4
15 | with:
16 | distribution: adopt
17 | java-version: 21
18 |
19 | - name: Setup Gradle
20 | uses: gradle/actions/setup-gradle@v4
21 |
22 | - name: Grant execute permission for gradlew
23 | run: chmod +x gradlew
24 |
25 | - name: Build with Gradle
26 | run: ./gradlew build
27 |
28 | - name: Run Test Servers
29 | timeout-minutes: 5
30 | run: |
31 | ./gradlew fabric:runGameTest &
32 | ./gradlew neoforge:runGameTest &
33 | wait
--------------------------------------------------------------------------------
/common/src/main/java/net/caffeinemc/mods/lithium/mixin/minimal_nonvanilla/world/block_entity_ticking/support_cache/package-info.java:
--------------------------------------------------------------------------------
1 | @MixinConfigOption(
2 | description = "BlockEntity ticking caches whether the BlockEntity can exist in the BlockState at the same location." +
3 | " This deviates from vanilla in the case of placing a hopper in a powered location, immediately updating the" +
4 | " cached BlockState (which is incorrect in vanilla). This most likely does not affect your gameplay, as this" +
5 | " deviation only affects hoppers, and in vanilla, hoppers never use the cached state information anyway.",
6 | depends = @MixinConfigDependency(dependencyPath = "mixin.world.block_entity_ticking")
7 | )
8 | package net.caffeinemc.mods.lithium.mixin.minimal_nonvanilla.world.block_entity_ticking.support_cache;
9 |
10 | import net.caffeinemc.gradle.MixinConfigDependency;
11 | import net.caffeinemc.gradle.MixinConfigOption;
--------------------------------------------------------------------------------
/common/src/main/java/net/caffeinemc/mods/lithium/common/tracking/entity/EntityMovementTrackerSection.java:
--------------------------------------------------------------------------------
1 | package net.caffeinemc.mods.lithium.common.tracking.entity;
2 |
3 | import net.minecraft.world.level.entity.EntityAccess;
4 | import net.minecraft.world.level.entity.EntitySectionStorage;
5 |
6 | public interface EntityMovementTrackerSection {
7 | void lithium$addListener(SectionedEntityMovementTracker> listener);
8 |
9 | void lithium$removeListener(EntitySectionStorage> sectionedEntityCache, SectionedEntityMovementTracker> listener);
10 |
11 | void lithium$trackEntityMovement(int notificationMask, long time);
12 |
13 | long lithium$getChangeTime(int trackedClass);
14 |
15 | void lithium$listenToMovementOnce(SectionedEntityMovementTracker listener, int trackedClass);
16 |
17 | void lithium$removeListenToMovementOnce(SectionedEntityMovementTracker listener, int trackedClass);
18 | }
19 |
--------------------------------------------------------------------------------
/common/src/main/java/net/caffeinemc/mods/lithium/common/util/tuples/RefIntPair.java:
--------------------------------------------------------------------------------
1 | package net.caffeinemc.mods.lithium.common.util.tuples;
2 |
3 | import java.util.Objects;
4 |
5 | public record RefIntPair(A left, int right) {
6 |
7 | @Override
8 | public boolean equals(Object obj) {
9 | if (obj == this) {
10 | return true;
11 | }
12 | if (obj == null || obj.getClass() != this.getClass()) {
13 | return false;
14 | }
15 | var that = (RefIntPair>) obj;
16 | return this.left == that.left &&
17 | this.right == that.right;
18 | }
19 |
20 | @Override
21 | public int hashCode() {
22 | return Objects.hash(System.identityHashCode(this.left), right);
23 | }
24 |
25 | @Override
26 | public String toString() {
27 | return "RefIntPair[" +
28 | "left=" + left + ", " +
29 | "right=" + right + ']';
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/common/src/main/java/net/caffeinemc/mods/lithium/mixin/alloc/enum_values/piston_block/PistonBaseBlockMixin.java:
--------------------------------------------------------------------------------
1 | package net.caffeinemc.mods.lithium.mixin.alloc.enum_values.piston_block;
2 |
3 | import net.caffeinemc.mods.lithium.common.util.DirectionConstants;
4 | import net.minecraft.core.Direction;
5 | import net.minecraft.world.level.block.piston.PistonBaseBlock;
6 | import org.spongepowered.asm.mixin.Mixin;
7 | import org.spongepowered.asm.mixin.injection.At;
8 | import org.spongepowered.asm.mixin.injection.Redirect;
9 |
10 | @Mixin(PistonBaseBlock.class)
11 | public class PistonBaseBlockMixin {
12 |
13 | @Redirect(
14 | method = "getNeighborSignal",
15 | at = @At(
16 | value = "INVOKE",
17 | target = "Lnet/minecraft/core/Direction;values()[Lnet/minecraft/core/Direction;"
18 | )
19 | )
20 | private Direction[] removeAllocation() {
21 | return DirectionConstants.ALL;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/common/src/main/java/net/caffeinemc/mods/lithium/mixin/experimental/entity/item_entity_merging/package-info.java:
--------------------------------------------------------------------------------
1 | @MixinConfigOption(
2 | description = "Optimize item entity merging by categorizing item entities by item type and only attempting to" +
3 | " merge with the same type. Categorizing by stack size allows skipping merge attempts of full item" +
4 | " entities or two more than half full item entities.",
5 | depends = {
6 | @MixinConfigDependency(dependencyPath = "mixin.util.accessors"),
7 | @MixinConfigDependency(dependencyPath = "mixin.util.entity_collection_replacement"),
8 | @MixinConfigDependency(dependencyPath = "mixin.util.item_component_and_count_tracking")
9 | }
10 | )
11 | package net.caffeinemc.mods.lithium.mixin.experimental.entity.item_entity_merging;
12 |
13 | import net.caffeinemc.gradle.MixinConfigDependency;
14 | import net.caffeinemc.gradle.MixinConfigOption;
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | _ReleaseTag_ is automatically replaced with the release tag, e.g. mc1.21.4-0.14.5
2 | _MCVersion_ is automatically replaced with the minecraft version, e.g. 1.21.4
3 | _LithiumVersion_ is automatically replaced with the lithium version, e.g. 0.14.5
4 | Everything above the line is ignored and not included in the changelog. Everything below will be in the
5 | changelog on GitHub, Modrinth and CurseForge.
6 | ----------
7 | Lithium _LithiumVersion_ for Minecraft _MCVersion_ fixes a minor issue.
8 |
9 | Make sure to take a backup of your world before using the mod and please report any bugs and mod compatibility issues at the [issue tracker](https://github.com/CaffeineMC/lithium-fabric/issues). You can check the [description of each optimization](https://github.com/CaffeineMC/lithium/blob/_ReleaseTag_/lithium-mixin-config.md) and how to disable it when encountering a problem.
10 |
11 | ## Fixes
12 | - Register happy ghast navigation correctly after growth state change
13 |
14 |
--------------------------------------------------------------------------------
/common/src/main/java/net/caffeinemc/mods/lithium/mixin/minimal_nonvanilla/collisions/empty_space/package-info.java:
--------------------------------------------------------------------------------
1 | @MixinConfigOption(
2 | description = "Speed up finding empty spaces mobs fit into. This speeds up entity pose checks and nether portal" +
3 | " positioning for colliding mobs (This code is vanilla's nether portal horse suffocation fix)." +
4 | " If certain block collision surfaces have coordinates that are different but within 1e-7 of each other," +
5 | " this optimization may cause entities coming from nether portals or changing pose to be placed in a" +
6 | " different position or pose than vanilla. This effect only occurs when the decision whether the entity" +
7 | " fits into a space depends on a difference in the magnitude of 1e-7 blocks."
8 | )
9 | package net.caffeinemc.mods.lithium.mixin.minimal_nonvanilla.collisions.empty_space;
10 |
11 | import net.caffeinemc.gradle.MixinConfigOption;
--------------------------------------------------------------------------------
/common/src/main/java/net/caffeinemc/mods/lithium/common/world/ClimbingMobCachingSection.java:
--------------------------------------------------------------------------------
1 | package net.caffeinemc.mods.lithium.common.world;
2 |
3 | import net.caffeinemc.mods.lithium.common.entity.pushable.EntityPushablePredicate;
4 | import net.caffeinemc.mods.lithium.common.entity.pushable.FeetBlockCachingEntity;
5 | import net.minecraft.util.AbortableIterationConsumer;
6 | import net.minecraft.world.entity.Entity;
7 | import net.minecraft.world.level.Level;
8 | import net.minecraft.world.level.block.state.BlockState;
9 | import net.minecraft.world.phys.AABB;
10 |
11 | import java.util.ArrayList;
12 |
13 | public interface ClimbingMobCachingSection {
14 |
15 | AbortableIterationConsumer.Continuation lithium$collectPushableEntities(Level world, Entity except, AABB box, EntityPushablePredicate super Entity> entityPushablePredicate, ArrayList entities);
16 |
17 | void lithium$onEntityModifiedCachedBlock(FeetBlockCachingEntity entity, BlockState newBlockState);
18 | }
19 |
--------------------------------------------------------------------------------
/common/src/main/java/net/caffeinemc/mods/lithium/common/block/entity/inventory_change_tracking/InventoryChangeTracker.java:
--------------------------------------------------------------------------------
1 | package net.caffeinemc.mods.lithium.common.block.entity.inventory_change_tracking;
2 |
3 | import net.caffeinemc.mods.lithium.common.hopper.LithiumStackList;
4 |
5 | public interface InventoryChangeTracker extends InventoryChangeEmitter {
6 | default void listenForContentChangesOnce(LithiumStackList stackList, InventoryChangeListener inventoryChangeListener) {
7 | this.lithium$forwardContentChangeOnce(inventoryChangeListener, stackList, this);
8 | }
9 |
10 | default void listenForMajorInventoryChanges(InventoryChangeListener inventoryChangeListener) {
11 | this.lithium$forwardMajorInventoryChanges(inventoryChangeListener);
12 | }
13 |
14 | default void stopListenForMajorInventoryChanges(InventoryChangeListener inventoryChangeListener) {
15 | this.lithium$stopForwardingMajorInventoryChanges(inventoryChangeListener);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/common/src/main/java/net/caffeinemc/mods/lithium/mixin/entity/fast_hand_swing/LivingEntityMixin.java:
--------------------------------------------------------------------------------
1 | package net.caffeinemc.mods.lithium.mixin.entity.fast_hand_swing;
2 |
3 | import net.minecraft.world.entity.LivingEntity;
4 | import org.spongepowered.asm.mixin.Mixin;
5 | import org.spongepowered.asm.mixin.Shadow;
6 | import org.spongepowered.asm.mixin.injection.At;
7 | import org.spongepowered.asm.mixin.injection.Inject;
8 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
9 |
10 | @Mixin(LivingEntity.class)
11 | public abstract class LivingEntityMixin {
12 | @Shadow
13 | public boolean swinging;
14 |
15 | @Shadow
16 | public int swingTime;
17 |
18 | @Inject(
19 | method = "updateSwingTime()V",
20 | at = @At("HEAD"),
21 | cancellable = true
22 | )
23 | private void skipGetDuration(CallbackInfo ci) {
24 | if (!this.swinging && this.swingTime == 0) {
25 | ci.cancel();
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/common/src/main/java/net/caffeinemc/mods/lithium/mixin/util/block_tracking/package-info.java:
--------------------------------------------------------------------------------
1 | @MixinConfigOption(
2 | description = "Chunk sections count certain blocks inside them and provide a method to quickly check whether a" +
3 | " chunk contains any of these blocks. Furthermore, chunk sections can notify registered listeners about" +
4 | " certain blocks being placed or broken.",
5 | depends = {
6 | @MixinConfigDependency(dependencyPath = "mixin.util.data_storage"),
7 | @MixinConfigDependency(dependencyPath = "mixin.util.chunk_status_tracking"),
8 | @MixinConfigDependency(dependencyPath = "mixin.util.initialization"),
9 | @MixinConfigDependency(dependencyPath = "mixin.util.section_data_storage")
10 | }
11 | )
12 | package net.caffeinemc.mods.lithium.mixin.util.block_tracking;
13 |
14 | import net.caffeinemc.gradle.MixinConfigDependency;
15 | import net.caffeinemc.gradle.MixinConfigOption;
--------------------------------------------------------------------------------
/common/src/main/java/net/caffeinemc/mods/lithium/mixin/world/chunk_access/GenerationChunkHolderAccessor.java:
--------------------------------------------------------------------------------
1 | package net.caffeinemc.mods.lithium.mixin.world.chunk_access;
2 |
3 | import net.minecraft.server.level.ChunkResult;
4 | import net.minecraft.server.level.GenerationChunkHolder;
5 | import net.minecraft.world.level.chunk.ChunkAccess;
6 | import net.minecraft.world.level.chunk.status.ChunkStatus;
7 | import org.spongepowered.asm.mixin.Mixin;
8 | import org.spongepowered.asm.mixin.gen.Accessor;
9 | import org.spongepowered.asm.mixin.gen.Invoker;
10 |
11 | import java.util.concurrent.CompletableFuture;
12 | import java.util.concurrent.atomic.AtomicReferenceArray;
13 |
14 | @Mixin(GenerationChunkHolder.class)
15 | public interface GenerationChunkHolderAccessor {
16 |
17 | @Accessor("futures")
18 | AtomicReferenceArray>> lithium$getChunkFuturesByStatus();
19 |
20 | @Invoker("isStatusDisallowed")
21 | boolean invokeCannotBeLoaded(ChunkStatus status);
22 | }
23 |
--------------------------------------------------------------------------------
/common/src/main/java/net/caffeinemc/mods/lithium/common/util/POIRegistryEntries.java:
--------------------------------------------------------------------------------
1 | package net.caffeinemc.mods.lithium.common.util;
2 |
3 | import net.minecraft.core.Holder;
4 | import net.minecraft.world.entity.ai.village.poi.PoiType;
5 | import net.minecraft.world.entity.ai.village.poi.PoiTypes;
6 | import net.minecraft.world.level.block.BedBlock;
7 | import net.minecraft.world.level.block.Blocks;
8 | import net.minecraft.world.level.block.state.properties.BedPart;
9 |
10 | public class POIRegistryEntries {
11 | //Using a separate class, so the registry lookup happens after the registry is initialized
12 | public static final Holder NETHER_PORTAL_ENTRY = PoiTypes.forState(Blocks.NETHER_PORTAL.defaultBlockState()).orElseThrow(() -> new IllegalStateException("Nether portal poi type not found"));
13 | public static final Holder HOME_ENTRY = PoiTypes.forState(Blocks.RED_BED.defaultBlockState().setValue(BedBlock.PART, BedPart.HEAD)).orElseThrow(() -> new IllegalStateException("Home poi type not found"));
14 | }
15 |
--------------------------------------------------------------------------------
/common/src/main/java/net/caffeinemc/mods/lithium/mixin/alloc/enum_values/piston_handler/PistonStructureResolverMixin.java:
--------------------------------------------------------------------------------
1 | package net.caffeinemc.mods.lithium.mixin.alloc.enum_values.piston_handler;
2 |
3 | import net.caffeinemc.mods.lithium.common.util.DirectionConstants;
4 | import net.minecraft.core.Direction;
5 | import net.minecraft.world.level.block.piston.PistonStructureResolver;
6 | import org.spongepowered.asm.mixin.Mixin;
7 | import org.spongepowered.asm.mixin.injection.At;
8 | import org.spongepowered.asm.mixin.injection.Redirect;
9 |
10 | @Mixin(PistonStructureResolver.class)
11 | public class PistonStructureResolverMixin {
12 |
13 | @Redirect(
14 | method = "addBranchingBlocks(Lnet/minecraft/core/BlockPos;)Z",
15 | at = @At(
16 | value = "INVOKE",
17 | target = "Lnet/minecraft/core/Direction;values()[Lnet/minecraft/core/Direction;"
18 | )
19 | )
20 | private Direction[] removeAllocation() {
21 | return DirectionConstants.ALL;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE/new_feature.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug fix
3 | about: Use this template if you're creating a pull request which adds a feature or other enhancement
4 | title: ''
5 | labels: enhancement
6 | assignees: ''
7 |
8 | ---
9 |
10 | ### Preface
11 |
12 | Please read our [Contributor Guidelines](https://github.com/CaffeineMC/lithium-fabric/blob/1.17.x/dev/CONTRIBUTING.md)
13 | before submitting any pull requests to this repository.
14 |
15 | By submitting a pull request, you are indicating that you agree to
16 | the [Contributor License Agreement](https://github.com/CaffeineMC/lithium-fabric/blob/1.17.x/dev/CONTRIBUTING.md#contributor-license-agreement-cla)
17 | and that your code will be licensed irrecoverably under the GNU LGPLv3. If you do not agree to these terms, do not open
18 | a pull request.
19 |
20 | Please remove this section before submitting your pull request. Doing so indicates that you have read and acknowledged
21 | it.
22 |
23 | ### Proposed Changes
24 | Provide a detailed description of what your pull request changes.
25 |
--------------------------------------------------------------------------------
/common/src/main/java/net/caffeinemc/mods/lithium/common/services/Services.java:
--------------------------------------------------------------------------------
1 | package net.caffeinemc.mods.lithium.common.services;
2 |
3 | import net.caffeinemc.mods.lithium.common.LithiumMod;
4 |
5 | import java.util.ServiceLoader;
6 |
7 | public class Services {
8 | // This code is used to load a service for the current environment. Your implementation of the service must be defined
9 | // manually by including a text file in META-INF/services named with the fully qualified class name of the service.
10 | // Inside the file you should write the fully qualified class name of the implementation to load for the platform.
11 | public static T load(Class clazz) {
12 | final T loadedService = ServiceLoader.load(clazz, clazz.getClassLoader())
13 | .findFirst()
14 | .orElseThrow(() -> new NullPointerException("Failed to load service for " + clazz.getName()));
15 | LithiumMod.logger().debug("Loaded {} for service {}", loadedService, clazz);
16 | return loadedService;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/common/src/main/java/net/caffeinemc/mods/lithium/mixin/world/block_entity_ticking/sleeping/ServerLevelMixin.java:
--------------------------------------------------------------------------------
1 | package net.caffeinemc.mods.lithium.mixin.world.block_entity_ticking.sleeping;
2 |
3 | import net.minecraft.core.BlockPos;
4 | import net.minecraft.server.level.ServerLevel;
5 | import net.minecraft.world.level.block.entity.TickingBlockEntity;
6 | import org.spongepowered.asm.mixin.Mixin;
7 | import org.spongepowered.asm.mixin.injection.At;
8 | import org.spongepowered.asm.mixin.injection.Redirect;
9 |
10 | @Mixin(ServerLevel.class)
11 | public class ServerLevelMixin {
12 |
13 | @Redirect(
14 | method = "dumpBlockEntityTickers",
15 | at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/entity/TickingBlockEntity;getPos()Lnet/minecraft/core/BlockPos;")
16 | )
17 | private BlockPos getPosOrOrigin(TickingBlockEntity instance) {
18 | BlockPos pos = instance.getPos();
19 | if (pos == null) {
20 | return BlockPos.ZERO;
21 | }
22 | return pos;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/fabric/src/main/java/net/caffeinemc/mods/lithium/fabric/mixin/collections/poi_types/PoiTypesMixin.java:
--------------------------------------------------------------------------------
1 | package net.caffeinemc.mods.lithium.fabric.mixin.collections.poi_types;
2 |
3 | import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap;
4 | import net.minecraft.world.entity.ai.village.poi.PoiType;
5 | import net.minecraft.world.entity.ai.village.poi.PoiTypes;
6 | import net.minecraft.world.level.block.state.BlockState;
7 | import org.spongepowered.asm.mixin.Final;
8 | import org.spongepowered.asm.mixin.Mixin;
9 | import org.spongepowered.asm.mixin.Mutable;
10 | import org.spongepowered.asm.mixin.Shadow;
11 |
12 | import java.util.Map;
13 |
14 | /**
15 | * Replaces the backing map type with a faster collection type which uses reference equality.
16 | */
17 | @Mixin(PoiTypes.class)
18 | public class PoiTypesMixin {
19 | @Mutable
20 | @Shadow
21 | @Final
22 | private static Map TYPE_BY_STATE;
23 |
24 | static {
25 | TYPE_BY_STATE = new Reference2ReferenceOpenHashMap<>(TYPE_BY_STATE);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/common/src/main/java/net/caffeinemc/mods/lithium/mixin/alloc/entity_iteration/EntitySectionMixin.java:
--------------------------------------------------------------------------------
1 | package net.caffeinemc.mods.lithium.mixin.alloc.entity_iteration;
2 |
3 | import net.minecraft.util.ClassInstanceMultiMap;
4 | import net.minecraft.world.level.entity.EntitySection;
5 | import org.spongepowered.asm.mixin.Mixin;
6 | import org.spongepowered.asm.mixin.injection.At;
7 | import org.spongepowered.asm.mixin.injection.Redirect;
8 |
9 | import java.util.Iterator;
10 |
11 | @Mixin(EntitySection.class)
12 | public class EntitySectionMixin {
13 |
14 | @Redirect(
15 | method = "getEntities(Lnet/minecraft/world/phys/AABB;Lnet/minecraft/util/AbortableIterationConsumer;)Lnet/minecraft/util/AbortableIterationConsumer$Continuation;",
16 | at = @At(value = "INVOKE", target = "Lnet/minecraft/util/ClassInstanceMultiMap;iterator()Ljava/util/Iterator;")
17 | )
18 | private Iterator> directIterator(ClassInstanceMultiMap> instance) {
19 | return ((ClassInstanceMultiMapAccessor>) instance).getAllInstances().iterator();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/common/src/main/java/net/caffeinemc/mods/lithium/mixin/entity/inactive_navigations/HappyGhastMixin.java:
--------------------------------------------------------------------------------
1 | package net.caffeinemc.mods.lithium.mixin.entity.inactive_navigations;
2 |
3 | import net.caffeinemc.mods.lithium.common.entity.NavigatingEntity;
4 | import net.minecraft.world.entity.animal.happyghast.HappyGhast;
5 | import org.spongepowered.asm.mixin.Mixin;
6 | import org.spongepowered.asm.mixin.injection.At;
7 | import org.spongepowered.asm.mixin.injection.Inject;
8 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
9 |
10 | @Mixin(HappyGhast.class)
11 | public class HappyGhastMixin {
12 | @Inject(method = "adultGhastSetup()V", at = @At(value = "RETURN"))
13 | private void updateRegisteredNavigation(CallbackInfo ci) {
14 | ((NavigatingEntity) this).lithium$updateNavigationRegistration();
15 | }
16 |
17 | @Inject(method = "babyGhastSetup()V", at = @At(value = "RETURN"))
18 | private void updateRegisteredNavigation1(CallbackInfo ci) {
19 | ((NavigatingEntity) this).lithium$updateNavigationRegistration();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/common/src/main/java/net/caffeinemc/mods/lithium/mixin/world/block_entity_ticking/sleeping/LevelMixin.java:
--------------------------------------------------------------------------------
1 | package net.caffeinemc.mods.lithium.mixin.world.block_entity_ticking.sleeping;
2 |
3 | import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
4 | import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
5 | import net.minecraft.core.BlockPos;
6 | import net.minecraft.world.level.Level;
7 | import org.spongepowered.asm.mixin.Mixin;
8 | import org.spongepowered.asm.mixin.injection.At;
9 |
10 | @Mixin(Level.class)
11 | public class LevelMixin {
12 |
13 | @WrapOperation(
14 | method = "tickBlockEntities",
15 | at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;shouldTickBlocksAt(Lnet/minecraft/core/BlockPos;)Z"),
16 | require = 0
17 | )
18 | private boolean shouldTickBlockPosFilterNull(Level instance, BlockPos pos, Operation original) {
19 | if (pos == null) {
20 | return false;
21 | }
22 | return original.call(instance, pos);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/common/src/main/java/net/caffeinemc/mods/lithium/mixin/shapes/blockstate_cache/BlockMixin.java:
--------------------------------------------------------------------------------
1 | package net.caffeinemc.mods.lithium.mixin.shapes.blockstate_cache;
2 |
3 | import net.caffeinemc.mods.lithium.common.util.collections.Object2BooleanCacheTable;
4 | import net.minecraft.world.level.block.Block;
5 | import net.minecraft.world.phys.shapes.BooleanOp;
6 | import net.minecraft.world.phys.shapes.Shapes;
7 | import net.minecraft.world.phys.shapes.VoxelShape;
8 | import org.spongepowered.asm.mixin.Mixin;
9 | import org.spongepowered.asm.mixin.Overwrite;
10 |
11 | @Mixin(Block.class)
12 | public class BlockMixin {
13 | private static final Object2BooleanCacheTable FULL_CUBE_CACHE = new Object2BooleanCacheTable<>(
14 | 512,
15 | shape -> !Shapes.joinIsNotEmpty(Shapes.block(), shape, BooleanOp.NOT_SAME)
16 | );
17 |
18 | /**
19 | * @reason Use a faster cache implementation
20 | * @author gegy1000
21 | */
22 | @Overwrite
23 | public static boolean isShapeFullBlock(VoxelShape shape) {
24 | return FULL_CUBE_CACHE.get(shape);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/common/src/main/java/net/caffeinemc/mods/lithium/mixin/util/entity_section_position/EntitySectionStorageMixin.java:
--------------------------------------------------------------------------------
1 | package net.caffeinemc.mods.lithium.mixin.util.entity_section_position;
2 |
3 | import net.caffeinemc.mods.lithium.common.entity.PositionedEntityTrackingSection;
4 | import net.minecraft.world.level.entity.EntityAccess;
5 | import net.minecraft.world.level.entity.EntitySection;
6 | import net.minecraft.world.level.entity.EntitySectionStorage;
7 | import org.spongepowered.asm.mixin.Mixin;
8 | import org.spongepowered.asm.mixin.injection.At;
9 | import org.spongepowered.asm.mixin.injection.Inject;
10 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
11 |
12 | @Mixin(EntitySectionStorage.class)
13 | public class EntitySectionStorageMixin {
14 | @Inject(method = "createSection(J)Lnet/minecraft/world/level/entity/EntitySection;", at = @At("RETURN"))
15 | private void rememberPos(long sectionPos, CallbackInfoReturnable> cir) {
16 | ((PositionedEntityTrackingSection) cir.getReturnValue()).lithium$setPos(sectionPos);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/common/src/main/java/net/caffeinemc/mods/lithium/mixin/world/explosions/entity_raycast/ClipContextMixin.java:
--------------------------------------------------------------------------------
1 | package net.caffeinemc.mods.lithium.mixin.world.explosions.entity_raycast;
2 |
3 | import net.caffeinemc.mods.lithium.common.world.explosions.ClipContextAccess;
4 | import net.minecraft.world.level.ClipContext;
5 | import net.minecraft.world.phys.Vec3;
6 | import net.minecraft.world.phys.shapes.CollisionContext;
7 | import org.spongepowered.asm.mixin.Final;
8 | import org.spongepowered.asm.mixin.Mixin;
9 | import org.spongepowered.asm.mixin.Mutable;
10 | import org.spongepowered.asm.mixin.Shadow;
11 |
12 | @Mixin(ClipContext.class)
13 | public class ClipContextMixin implements ClipContextAccess {
14 | @Mutable
15 | @Shadow
16 | @Final
17 | private Vec3 from;
18 |
19 | @Shadow
20 | @Final
21 | private CollisionContext collisionContext;
22 |
23 | @Override
24 | public void lithium$setFrom(Vec3 from) {
25 | this.from = from;
26 | }
27 |
28 | @Override
29 | public CollisionContext lithium$getCollisionContext() {
30 | return this.collisionContext;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------