mojang why
This commit is contained in:
@@ -0,0 +1,192 @@
|
||||
package net.gensokyoreimagined.nitori.common.world.scheduler;
|
||||
|
||||
// ChunkTickSchedulerMixin needs this
|
||||
|
||||
|
||||
|
||||
//import it.unimi.dsi.fastutil.HashCommon;
|
||||
//import net.minecraft.world.ticks.ScheduledTick;
|
||||
//
|
||||
//import java.util.*;
|
||||
//
|
||||
//public class OrderedTickQueue<T> extends AbstractQueue<ScheduledTick<T>> {
|
||||
// private static final int INITIAL_CAPACITY = 16;
|
||||
// private static final Comparator<ScheduledTick<?>> COMPARATOR = Comparator.comparingLong(ScheduledTick::subTickOrder);
|
||||
//
|
||||
// private ScheduledTick<T>[] arr;
|
||||
//
|
||||
// private int lastIndexExclusive;
|
||||
// private int firstIndex;
|
||||
//
|
||||
// private long currentMaxSubTickOrder = Long.MIN_VALUE;
|
||||
// private boolean isSorted;
|
||||
// private ScheduledTick<T> unsortedPeekResult;
|
||||
//
|
||||
// @SuppressWarnings("unchecked")
|
||||
// public OrderedTickQueue(int capacity) {
|
||||
// this.arr = (ScheduledTick<T>[]) new ScheduledTick[capacity];
|
||||
// this.lastIndexExclusive = 0;
|
||||
// this.isSorted = true;
|
||||
// this.unsortedPeekResult = null;
|
||||
// this.firstIndex = 0;
|
||||
// }
|
||||
//
|
||||
// public OrderedTickQueue() {
|
||||
// this(INITIAL_CAPACITY);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void clear() {
|
||||
// Arrays.fill(this.arr, null);
|
||||
// this.lastIndexExclusive = 0;
|
||||
// this.firstIndex = 0;
|
||||
// this.currentMaxSubTickOrder = Long.MIN_VALUE;
|
||||
// this.isSorted = true;
|
||||
// this.unsortedPeekResult = null;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public Iterator<ScheduledTick<T>> iterator() {
|
||||
// if (this.isEmpty()) {
|
||||
// return Collections.emptyIterator();
|
||||
// }
|
||||
// this.sort();
|
||||
// return new Iterator<>() {
|
||||
// int nextIndex = OrderedTickQueue.this.firstIndex;
|
||||
//
|
||||
// @Override
|
||||
// public boolean hasNext() {
|
||||
// return this.nextIndex < OrderedTickQueue.this.lastIndexExclusive;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public ScheduledTick<T> next() {
|
||||
// return OrderedTickQueue.this.arr[this.nextIndex++];
|
||||
// }
|
||||
// };
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public ScheduledTick<T> poll() {
|
||||
// if (this.isEmpty()) {
|
||||
// return null;
|
||||
// }
|
||||
// if (!this.isSorted) {
|
||||
// this.sort();
|
||||
// }
|
||||
// ScheduledTick<T> nextTick;
|
||||
// int polledIndex = this.firstIndex++;
|
||||
// ScheduledTick<T>[] ticks = this.arr;
|
||||
// nextTick = ticks[polledIndex];
|
||||
// ticks[polledIndex] = null;
|
||||
// return nextTick;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public ScheduledTick<T> peek() {
|
||||
// if (!this.isSorted) {
|
||||
// return this.unsortedPeekResult;
|
||||
// } else if (this.lastIndexExclusive > this.firstIndex) {
|
||||
// return this.getTickAtIndex(this.firstIndex);
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// public boolean offer(ScheduledTick<T> tick) {
|
||||
// if (this.lastIndexExclusive >= this.arr.length) {
|
||||
// //todo remove consumed elements first
|
||||
// this.arr = copyArray(this.arr, HashCommon.nextPowerOfTwo(this.arr.length + 1));
|
||||
// }
|
||||
// if (tick.subTickOrder() <= this.currentMaxSubTickOrder) {
|
||||
// //Set to unsorted instead of slowing down the insertion
|
||||
// //This is rare but may happen in bulk
|
||||
// //Sorting later needs O(n*log(n)) time, but it only needs to happen when unordered insertion needs to happen
|
||||
// //Therefore it is better than n times log(n) time of the PriorityQueue that happens on ordered insertion too
|
||||
// ScheduledTick<T> firstTick = this.isSorted ? this.size() > 0 ? this.arr[this.firstIndex] : null : this.unsortedPeekResult;
|
||||
// this.isSorted = false;
|
||||
// this.unsortedPeekResult = firstTick == null || tick.subTickOrder() < firstTick.subTickOrder() ? tick : firstTick;
|
||||
// } else {
|
||||
// this.currentMaxSubTickOrder = tick.subTickOrder();
|
||||
// }
|
||||
// this.arr[this.lastIndexExclusive++] = tick;
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// public int size() {
|
||||
// return this.lastIndexExclusive - this.firstIndex;
|
||||
// }
|
||||
//
|
||||
// private void handleCompaction(int size) {
|
||||
// // Only compact the array if it is less than 50% filled
|
||||
// if (this.arr.length > INITIAL_CAPACITY && size < this.arr.length / 2) {
|
||||
// this.arr = copyArray(this.arr, size);
|
||||
// } else {
|
||||
// // Fill the unused array elements with nulls to release our references to the elements in it
|
||||
// Arrays.fill(this.arr, size, this.arr.length, null);
|
||||
// }
|
||||
//
|
||||
// this.firstIndex = 0;
|
||||
// this.lastIndexExclusive = size;
|
||||
//
|
||||
// if (size == 0 || !this.isSorted) {
|
||||
// this.currentMaxSubTickOrder = Long.MIN_VALUE;
|
||||
// } else {
|
||||
// ScheduledTick<T> tick = this.arr[size - 1];
|
||||
// this.currentMaxSubTickOrder = tick == null ? Long.MIN_VALUE : tick.subTickOrder();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public void sort() {
|
||||
// if (this.isSorted) {
|
||||
// return;
|
||||
// }
|
||||
// this.removeNullsAndConsumed();
|
||||
// Arrays.sort(this.arr, this.firstIndex, this.lastIndexExclusive, COMPARATOR);
|
||||
// this.isSorted = true;
|
||||
// this.unsortedPeekResult = null;
|
||||
// }
|
||||
//
|
||||
// public void removeNullsAndConsumed() {
|
||||
// int src = this.firstIndex;
|
||||
// int dst = 0;
|
||||
// while (src < this.lastIndexExclusive) {
|
||||
// ScheduledTick<T> ScheduledTick = this.arr[src];
|
||||
// if (ScheduledTick != null) {
|
||||
// this.arr[dst] = ScheduledTick;
|
||||
// dst++;
|
||||
// }
|
||||
// src++;
|
||||
// }
|
||||
// this.handleCompaction(dst);
|
||||
// }
|
||||
//
|
||||
// public ScheduledTick<T> getTickAtIndex(int index) {
|
||||
// if (!this.isSorted) {
|
||||
// throw new IllegalStateException("Unexpected access on unsorted queue!");
|
||||
// }
|
||||
// return this.arr[index];
|
||||
// }
|
||||
//
|
||||
// public void setTickAtIndex(int index, ScheduledTick<T> tick) {
|
||||
// if (!this.isSorted) {
|
||||
// throw new IllegalStateException("Unexpected access on unsorted queue!");
|
||||
// }
|
||||
// this.arr[index] = tick;
|
||||
// }
|
||||
//
|
||||
// @SuppressWarnings("unchecked")
|
||||
// private static <T> ScheduledTick<T>[] copyArray(ScheduledTick<T>[] src, int size) {
|
||||
// final ScheduledTick<T>[] copy = new ScheduledTick[Math.max(INITIAL_CAPACITY, size)];
|
||||
//
|
||||
// if (size != 0) {
|
||||
// System.arraycopy(src, 0, copy, 0, Math.min(src.length, size));
|
||||
// }
|
||||
//
|
||||
// return copy;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean isEmpty() {
|
||||
// return this.lastIndexExclusive <= this.firstIndex;
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,39 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.alloc.biome_temprature_leak;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
import it.unimi.dsi.fastutil.longs.Long2FloatLinkedOpenHashMap;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Mixin(Biome.class)
|
||||
public abstract class Biome_threadLocalMixin {
|
||||
|
||||
/*
|
||||
* Not only do I absolutely hate this garbage cache, cause it barely works at all.
|
||||
* HOW did nobody at mojang notice that this thread local was not static, how on earth is a non-static private
|
||||
* value suppose to run on multiple threads at the same time.
|
||||
* So now its static so that it actually works like its suppose to, and you don't need to declare a billion of them
|
||||
*
|
||||
* This is a significant performance boost & reduces a lot of memory usage
|
||||
*/
|
||||
|
||||
private static ThreadLocal<Long2FloatLinkedOpenHashMap> memoryLeakFix$betterTempCache;
|
||||
|
||||
@WrapOperation(
|
||||
method = "<init>",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Ljava/lang/ThreadLocal;withInitial(Ljava/util/function/Supplier;)Ljava/lang/ThreadLocal;"
|
||||
)
|
||||
)
|
||||
private ThreadLocal<Long2FloatLinkedOpenHashMap> memoryLeakFix$useStaticThreadLocal(Supplier<?> supplier, Operation<ThreadLocal<Long2FloatLinkedOpenHashMap>> original) {
|
||||
if (memoryLeakFix$betterTempCache == null) {
|
||||
memoryLeakFix$betterTempCache = original.call(supplier);
|
||||
}
|
||||
return memoryLeakFix$betterTempCache;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,294 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.world.tick_scheduler;
|
||||
|
||||
//TODO: Make this work with paper
|
||||
|
||||
|
||||
//import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
//import it.unimi.dsi.fastutil.longs.Long2ReferenceAVLTreeMap;
|
||||
//import it.unimi.dsi.fastutil.objects.ObjectIterator;
|
||||
//import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap;
|
||||
//import net.gensokyoreimagined.nitori.common.world.scheduler.OrderedTickQueue;
|
||||
//import net.minecraft.nbt.ListTag;
|
||||
//import net.minecraft.core.BlockPos;
|
||||
//import net.minecraft.world.ticks.LevelChunkTicks;
|
||||
//import net.minecraft.world.ticks.ScheduledTick;
|
||||
//import net.minecraft.world.ticks.SavedTick;
|
||||
//import net.minecraft.world.ticks.TickPriority;
|
||||
//import org.jetbrains.annotations.Nullable;
|
||||
//import org.spongepowered.asm.mixin.*;
|
||||
//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.Collection;
|
||||
//import java.util.List;
|
||||
//import java.util.Queue;
|
||||
//import java.util.Set;
|
||||
//import java.util.function.BiConsumer;
|
||||
//import java.util.function.Function;
|
||||
//import java.util.function.Predicate;
|
||||
//import java.util.stream.Stream;
|
||||
//
|
||||
//@Mixin(LevelChunkTicks.class)
|
||||
//public class ChunkTickSchedulerMixin<T> {
|
||||
// private static volatile Reference2IntOpenHashMap<Object> TYPE_2_INDEX;
|
||||
//
|
||||
// static {
|
||||
// TYPE_2_INDEX = new Reference2IntOpenHashMap<>();
|
||||
// TYPE_2_INDEX.defaultReturnValue(-1);
|
||||
// }
|
||||
//
|
||||
// private final Long2ReferenceAVLTreeMap<OrderedTickQueue<T>> tickQueuesByTimeAndPriority = new Long2ReferenceAVLTreeMap<>();
|
||||
// private OrderedTickQueue<T> nextTickQueue;
|
||||
// private final IntOpenHashSet allTicks = new IntOpenHashSet();
|
||||
//
|
||||
// @Shadow
|
||||
// private @Nullable BiConsumer<LevelChunkTicks<T>, ScheduledTick<T>> onTickAdded;
|
||||
//
|
||||
// @Mutable
|
||||
// @Shadow
|
||||
// @Final
|
||||
// private Set<ScheduledTick<?>> ticksPerPosition;
|
||||
//
|
||||
// @Shadow
|
||||
// private @Nullable List<SavedTick<T>> pendingTicks;
|
||||
//
|
||||
// @Mutable
|
||||
// @Shadow
|
||||
// @Final
|
||||
// private Queue<ScheduledTick<T>> tickQueue;
|
||||
//
|
||||
// // Paper start - add dirty flag
|
||||
// private boolean dirty;
|
||||
// private long lastSaved = Long.MIN_VALUE;
|
||||
//
|
||||
// public boolean isDirty(final long tick) {
|
||||
// return this.dirty || (!this.tickQueue.isEmpty() && tick != this.lastSaved);
|
||||
// }
|
||||
//
|
||||
// public void clearDirty() {
|
||||
// this.dirty = false;
|
||||
// }
|
||||
// // Paper end - add dirty flag
|
||||
//
|
||||
// @Inject(
|
||||
// method = {"<init>()V", "<init>(Ljava/util/List;)V"},
|
||||
// at = @At("RETURN")
|
||||
// )
|
||||
// private void reinit(CallbackInfo ci) {
|
||||
// //Remove replaced collections
|
||||
// if (this.pendingTicks != null) {
|
||||
// for (SavedTick<?> orderedTick : this.pendingTicks) {
|
||||
// this.allTicks.add(tickToInt(orderedTick.pos(), orderedTick.type()));
|
||||
// }
|
||||
// }
|
||||
// this.ticksPerPosition = null;
|
||||
// this.tickQueue = null;
|
||||
// }
|
||||
//
|
||||
// private static int tickToInt(BlockPos pos, Object type) {
|
||||
// //Y coordinate is 12 bits (BlockPos.toLong)
|
||||
// //X and Z coordinate is 4 bits each (This scheduler is for a single chunk)
|
||||
// //20 bits are in use for pos
|
||||
// //12 bits remaining for the type, so up to 4096 different tickable blocks/fluids (not block states) -> can upgrade to long if needed
|
||||
// int typeIndex = TYPE_2_INDEX.getInt(type);
|
||||
// if (typeIndex == -1) {
|
||||
// typeIndex = fixMissingType2Index(type);
|
||||
// }
|
||||
//
|
||||
// int ret = ((pos.getX() & 0xF) << 16) | ((pos.getY() & (0xfff)) << 4) | (pos.getZ() & 0xF);
|
||||
// ret |= typeIndex << 20;
|
||||
// return ret;
|
||||
// }
|
||||
//
|
||||
// //This method must be synchronized, otherwise type->int assignments can be overwritten and therefore change
|
||||
// //Uses clone and volatile store to ensure only fully initialized maps are used, all threads share the same mapping
|
||||
// private static synchronized int fixMissingType2Index(Object type) {
|
||||
// //check again, other thread might have replaced the collection
|
||||
// int typeIndex = TYPE_2_INDEX.getInt(type);
|
||||
// if (typeIndex == -1) {
|
||||
// Reference2IntOpenHashMap<Object> clonedType2Index = TYPE_2_INDEX.clone();
|
||||
// clonedType2Index.put(type, typeIndex = clonedType2Index.size());
|
||||
// TYPE_2_INDEX = clonedType2Index;
|
||||
// if (typeIndex >= 4096) {
|
||||
// throw new IllegalStateException("Lithium Tick Scheduler assumes at most 4096 different block types that receive scheduled ticks exist! Add mixin.world.tick_scheduler=false to the lithium properties/config to disable the optimization!");
|
||||
// }
|
||||
// }
|
||||
// return typeIndex;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @author 2No2Name
|
||||
// * @reason use faster collections
|
||||
// */
|
||||
// @Overwrite
|
||||
// public void schedule(ScheduledTick<T> orderedTick) {
|
||||
// int intTick = tickToInt(orderedTick.pos(), orderedTick.type());
|
||||
// if (this.allTicks.add(intTick)) {
|
||||
// this.dirty = true; // Paper - add dirty flag
|
||||
// this.scheduleUnchecked(orderedTick);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Computes a timestamped key including the tick's priority
|
||||
// // Keys can be sorted in descending order to find what should be executed first
|
||||
// // 60 time bits, 4 priority bits
|
||||
// private static long getBucketKey(long time, TickPriority priority) {
|
||||
// //using priority.ordinal() as is not negative instead of priority.index
|
||||
// return (time << 4L) | (priority.ordinal() & 15);
|
||||
// }
|
||||
//
|
||||
// private void updateNextTickQueue(boolean checkEmpty) {
|
||||
// if (checkEmpty && this.nextTickQueue != null && this.nextTickQueue.isEmpty()) {
|
||||
// OrderedTickQueue<T> removed = this.tickQueuesByTimeAndPriority.remove(this.tickQueuesByTimeAndPriority.firstLongKey());
|
||||
// if (removed != this.nextTickQueue) {
|
||||
// throw new IllegalStateException("Next tick queue doesn't have the lowest key!");
|
||||
// }
|
||||
// }
|
||||
// if (this.tickQueuesByTimeAndPriority.isEmpty()) {
|
||||
// this.nextTickQueue = null;
|
||||
// return;
|
||||
// }
|
||||
// long firstKey = this.tickQueuesByTimeAndPriority.firstLongKey();
|
||||
// this.nextTickQueue = this.tickQueuesByTimeAndPriority.get(firstKey);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @author 2No2Name
|
||||
// * @reason use faster collections
|
||||
// */
|
||||
// @Overwrite
|
||||
// @Nullable
|
||||
// public ScheduledTick<T> peek() {
|
||||
// if (this.nextTickQueue == null) {
|
||||
// return null;
|
||||
// }
|
||||
// return this.nextTickQueue.peek();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @author 2No2Name
|
||||
// * @reason use faster collections
|
||||
// */
|
||||
// @Overwrite
|
||||
// @Nullable
|
||||
// public ScheduledTick<T> poll() {
|
||||
// ScheduledTick<T> ScheduledTick = this.nextTickQueue.poll();
|
||||
// if (ScheduledTick != null) {
|
||||
// if (this.nextTickQueue.isEmpty()) {
|
||||
// this.updateNextTickQueue(true);
|
||||
// }
|
||||
// this.allTicks.remove(tickToInt(ScheduledTick.pos(), ScheduledTick.type()));
|
||||
// this.dirty = true; // Paper - add dirty flag
|
||||
// return ScheduledTick;
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// private void scheduleUnchecked(ScheduledTick<T> orderedTick) {
|
||||
// OrderedTickQueue<T> tickQueue = this.tickQueuesByTimeAndPriority.computeIfAbsent(getBucketKey(orderedTick.triggerTick(), orderedTick.priority()), key -> new OrderedTickQueue<>());
|
||||
// if (tickQueue.isEmpty()) {
|
||||
// this.updateNextTickQueue(false);
|
||||
// }
|
||||
// tickQueue.offer(orderedTick);
|
||||
//
|
||||
// if (this.onTickAdded != null) {
|
||||
// //noinspection unchecked
|
||||
// this.onTickAdded.accept((LevelChunkTicks<T>) (Object) this, orderedTick);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @author 2No2Name
|
||||
// * @reason use faster collections
|
||||
// */
|
||||
// @Overwrite
|
||||
// public boolean hasScheduledTick(BlockPos pos, T type) {
|
||||
// return this.allTicks.contains(tickToInt(pos, type));
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @author 2No2Name
|
||||
// * @reason use faster collections
|
||||
// */
|
||||
// @Overwrite
|
||||
// public void removeIf(Predicate<ScheduledTick<T>> predicate) {
|
||||
// for (ObjectIterator<OrderedTickQueue<T>> tickQueueIterator = this.tickQueuesByTimeAndPriority.values().iterator(); tickQueueIterator.hasNext(); ) {
|
||||
// OrderedTickQueue<T> nextTickQueue = tickQueueIterator.next();
|
||||
// nextTickQueue.sort();
|
||||
// boolean removed = false;
|
||||
// for (int i = 0; i < nextTickQueue.size(); i++) {
|
||||
// ScheduledTick<T> nextTick = nextTickQueue.getTickAtIndex(i);
|
||||
// if (predicate.test(nextTick)) {
|
||||
// nextTickQueue.setTickAtIndex(i, null);
|
||||
// this.allTicks.remove(tickToInt(nextTick.pos(), nextTick.type()));
|
||||
// removed = true;
|
||||
// }
|
||||
// }
|
||||
// if (removed) {
|
||||
// nextTickQueue.removeNullsAndConsumed();
|
||||
// }
|
||||
// if (nextTickQueue.isEmpty()) {
|
||||
// tickQueueIterator.remove();
|
||||
// }
|
||||
// }
|
||||
// this.updateNextTickQueue(false);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @author 2No2Name
|
||||
// * @reason use faster collections
|
||||
// */
|
||||
// @Overwrite
|
||||
// public Stream<ScheduledTick<T>> getAll() {
|
||||
// return this.tickQueuesByTimeAndPriority.values().stream().flatMap(Collection::stream);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// /**
|
||||
// * @author 2No2Name
|
||||
// * @reason not use unused field
|
||||
// */
|
||||
// @Overwrite
|
||||
// public int count() {
|
||||
// return this.allTicks.size();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @author 2No2Name
|
||||
// * @reason not use unused field
|
||||
// */
|
||||
// @Overwrite
|
||||
// public ListTag save(long l, Function<T, String> function) {
|
||||
// this.lastSaved = l;
|
||||
// ListTag ListTag = new ListTag();
|
||||
// if (this.pendingTicks != null) {
|
||||
// for (SavedTick<T> tick : this.pendingTicks) {
|
||||
// ListTag.add(tick.save(function));
|
||||
// }
|
||||
// }
|
||||
// for (OrderedTickQueue<T> nextTickQueue : this.tickQueuesByTimeAndPriority.values()) {
|
||||
// for (ScheduledTick<T> orderedTick : nextTickQueue) {
|
||||
// ListTag.add(SavedTick.saveTick(orderedTick, function, l));
|
||||
// }
|
||||
// }
|
||||
// return ListTag;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// /**
|
||||
// * @author 2No2Name
|
||||
// * @reason use our datastructures
|
||||
// */
|
||||
// @Overwrite
|
||||
// public void unpack(long time) {
|
||||
// if (this.pendingTicks != null) {
|
||||
// int i = -this.pendingTicks.size();
|
||||
// for (SavedTick<T> tick : this.pendingTicks) {
|
||||
// this.scheduleUnchecked(tick.unpack(time, i++));
|
||||
// }
|
||||
// }
|
||||
// this.pendingTicks = null;
|
||||
// }
|
||||
//}
|
||||
@@ -31,6 +31,7 @@
|
||||
"alloc.composter.ComposterMixin$ComposterBlockComposterInventoryMixin",
|
||||
"alloc.composter.ComposterMixin$ComposterBlockDummyInventoryMixin",
|
||||
"alloc.composter.ComposterMixin$ComposterBlockFullComposterInventoryMixin",
|
||||
"alloc.biome_temprature_leak.Biome_threadLocalMixin",
|
||||
"cached_hashcode.BlockNeighborGroupMixin",
|
||||
"collections.attributes.AttributeContainerMixin",
|
||||
"collections.block_entity_tickers.WorldChunkMixin",
|
||||
|
||||
Reference in New Issue
Block a user