Skip to content

Commit

Permalink
Update to 1.20.5pre-1
Browse files Browse the repository at this point in the history
  • Loading branch information
2No2Name committed Apr 11, 2024
1 parent 84a7a04 commit 389fc66
Show file tree
Hide file tree
Showing 52 changed files with 287 additions and 1,023 deletions.
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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<String> fabricApiModulesCompileOnly = [
"fabric-transfer-api-v1"
Expand Down
9 changes: 4 additions & 5 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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
36 changes: 0 additions & 36 deletions lithium-mixin-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand All @@ -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)];
Expand All @@ -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;
}
}

Expand Down Expand Up @@ -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;
Expand All @@ -128,7 +128,7 @@ public static PathNodeType getNodeTypeFromNeighbors(BlockView world, BlockPos.Mu
}
}

return type;
return fallback;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package me.jellysquid.mods.lithium.common.ai.raid;

import net.minecraft.item.ItemStack;

public interface OminousBannerCache {
ItemStack lithium$getCachedOminousBanner();
}
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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<S extends Entity> extends SectionedEntityMovementTracker<Entity, S> {
Expand All @@ -18,21 +18,19 @@ public SectionedItemEntityMovementTracker(WorldSectionBox worldSectionBox, Class
super(worldSectionBox, clazz);
}

public static <S extends Entity> SectionedItemEntityMovementTracker<S> registerAt(ServerWorld world, Box encompassingBox, Class<S> clazz) {
public static <S extends Entity> SectionedItemEntityMovementTracker<S> registerAt(ServerWorld world, Box interactionArea, Class<S> clazz) {
MovementTrackerCache cache = (MovementTrackerCache) ((ServerEntityManagerAccessor<?>) ((ServerWorldAccessor) world).getEntityManager()).getCache();

WorldSectionBox worldSectionBox = WorldSectionBox.entityAccessBox(world, encompassingBox);
WorldSectionBox worldSectionBox = WorldSectionBox.entityAccessBox(world, interactionArea);
SectionedItemEntityMovementTracker<S> tracker = new SectionedItemEntityMovementTracker<>(worldSectionBox, clazz);
tracker = cache.lithium$deduplicate(tracker);

tracker.register(world);
return tracker;
}

public List<S> getEntities(Box[] areas) {
int numBoxes = areas.length - 1;
BucketedList<S> entities = new BucketedList<>(numBoxes);
Box encompassingBox = areas[numBoxes];
public List<S> getEntities(Box interactionArea) {
ArrayList<S> entities = new ArrayList<>();
for (int sectionIndex = 0; sectionIndex < this.sortedSections.size(); sectionIndex++) {
if (this.sectionVisible[sectionIndex]) {
//noinspection unchecked
Expand All @@ -41,16 +39,8 @@ public List<S> 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);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ private <S extends EntityLike, T extends LivingEntity> void updateRange(NearbyEn
this.range = updatedRange;

//noinspection unchecked
SectionedEntityCache<S> entityCache = ((ServerEntityManagerAccessor<S>)((ServerWorldAccessor)tracker.getEntity().getWorld()).getEntityManager()).getCache();
SectionedEntityCache<S> entityCache = ((ServerEntityManagerAccessor<S>) ((ServerWorldAccessor) tracker.getEntity().getWorld()).getEntityManager()).getCache();
ChunkSectionPos chunkPos = ChunkSectionPos.from(tracker.getEntity().getBlockPos());

this.updateChunkRegistrations(entityCache, chunkPos, this.range, chunkPos, updatedRange);
Expand Down
Original file line number Diff line number Diff line change
@@ -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) {
Expand All @@ -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()
Expand All @@ -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);
Expand Down
Loading

0 comments on commit 389fc66

Please sign in to comment.