mirror of
https://github.com/YatopiaMC/Yatopia.git
synced 2024-11-29 14:15:43 +01:00
1218 lines
49 KiB
Diff
1218 lines
49 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: 2No2Name <50278648+2No2Name@users.noreply.github.com>
|
|
Date: Sun, 21 Feb 2021 21:34:18 -0500
|
|
Subject: [PATCH] lithium: skip ticking block entities that are doing nothing
|
|
|
|
|
|
diff --git a/src/main/java/me/jellysquid/mods/lithium/common/util/collections/ListeningList.java b/src/main/java/me/jellysquid/mods/lithium/common/util/collections/ListeningList.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..edcc9ec27cc7d8dc5bf04e1f70362b505742570c
|
|
--- /dev/null
|
|
+++ b/src/main/java/me/jellysquid/mods/lithium/common/util/collections/ListeningList.java
|
|
@@ -0,0 +1,255 @@
|
|
+package me.jellysquid.mods.lithium.common.util.collections;
|
|
+
|
|
+import org.jetbrains.annotations.NotNull;
|
|
+
|
|
+import java.util.*;
|
|
+import java.util.function.Consumer;
|
|
+import java.util.function.Predicate;
|
|
+import java.util.function.UnaryOperator;
|
|
+import java.util.stream.Stream;
|
|
+
|
|
+public class ListeningList<T> implements List<T> {
|
|
+ private final List<T> delegate;
|
|
+ private final Runnable changeCallback;
|
|
+
|
|
+ public ListeningList(List<T> delegate, Runnable changeCallback) {
|
|
+ this.delegate = delegate;
|
|
+ this.changeCallback = changeCallback;
|
|
+ }
|
|
+
|
|
+ private void onChange() {
|
|
+ this.changeCallback.run();
|
|
+ }
|
|
+
|
|
+
|
|
+ @Override
|
|
+ public int size() {
|
|
+ return this.delegate.size();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isEmpty() {
|
|
+ return this.delegate.isEmpty();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean contains(Object o) {
|
|
+ return this.delegate.contains(o);
|
|
+ }
|
|
+
|
|
+ @NotNull
|
|
+ @Override
|
|
+ public Iterator<T> iterator() {
|
|
+ return this.listIterator();
|
|
+ }
|
|
+
|
|
+ @NotNull
|
|
+ @Override
|
|
+ public Object[] toArray() {
|
|
+ return this.delegate.toArray();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void forEach(Consumer<? super T> consumer) {
|
|
+ this.delegate.forEach(consumer);
|
|
+ }
|
|
+
|
|
+ @NotNull
|
|
+ @Override
|
|
+ public <T1> T1[] toArray(@NotNull T1[] t1s) {
|
|
+ //noinspection SuspiciousToArrayCall
|
|
+ return this.delegate.toArray(t1s);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean add(T t) {
|
|
+ boolean add = this.delegate.add(t);
|
|
+ this.onChange();
|
|
+ //noinspection ConstantConditions
|
|
+ return add;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean remove(Object o) {
|
|
+ boolean remove = this.delegate.remove(o);
|
|
+ this.onChange();
|
|
+ return remove;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean containsAll(@NotNull Collection<?> collection) {
|
|
+ return this.delegate.containsAll(collection);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean addAll(@NotNull Collection<? extends T> collection) {
|
|
+ boolean addAll = this.delegate.addAll(collection);
|
|
+ this.onChange();
|
|
+ return addAll;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean addAll(int i, @NotNull Collection<? extends T> collection) {
|
|
+ boolean addAll = this.delegate.addAll(i, collection);
|
|
+ this.onChange();
|
|
+ return addAll;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean removeAll(@NotNull Collection<?> collection) {
|
|
+ boolean b = this.delegate.removeAll(collection);
|
|
+ this.onChange();
|
|
+ return b;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean removeIf(Predicate<? super T> predicate) {
|
|
+ boolean b = this.delegate.removeIf(predicate);
|
|
+ this.onChange();
|
|
+ return b;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean retainAll(@NotNull Collection<?> collection) {
|
|
+ boolean b = this.delegate.retainAll(collection);
|
|
+ this.onChange();
|
|
+ return b;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void replaceAll(UnaryOperator<T> unaryOperator) {
|
|
+ this.delegate.replaceAll( unaryOperator);
|
|
+ this.onChange();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void sort(Comparator<? super T> comparator) {
|
|
+ this.delegate.sort(comparator);
|
|
+ this.onChange();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void clear() {
|
|
+ this.delegate.clear();
|
|
+ this.onChange();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public T get(int i) {
|
|
+ return this.delegate.get(i);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public T set(int i, T t) {
|
|
+ T set = this.delegate.set(i, t);
|
|
+ this.onChange();
|
|
+ return set;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void add(int i, T t) {
|
|
+ this.delegate.add(i, t);
|
|
+ this.onChange();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public T remove(int i) {
|
|
+ T remove = this.delegate.remove(i);
|
|
+ this.onChange();
|
|
+ return remove;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int indexOf(Object o) {
|
|
+ return this.delegate.indexOf(o);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int lastIndexOf(Object o) {
|
|
+ return this.delegate.lastIndexOf(o);
|
|
+ }
|
|
+
|
|
+ @NotNull
|
|
+ @Override
|
|
+ public ListIterator<T> listIterator() {
|
|
+ return this.listIterator(0);
|
|
+ }
|
|
+
|
|
+ @NotNull
|
|
+ @Override
|
|
+ public ListIterator<T> listIterator(int i) {
|
|
+ return new ListIterator<T>() {
|
|
+ final ListIterator<T> itDelegate = ListeningList.this.delegate.listIterator(i);
|
|
+
|
|
+ @Override
|
|
+ public boolean hasNext() {
|
|
+ return this.itDelegate.hasNext();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public T next() {
|
|
+ return this.itDelegate.next();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean hasPrevious() {
|
|
+ return this.itDelegate.hasPrevious();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public T previous() {
|
|
+ return this.itDelegate.previous();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int nextIndex() {
|
|
+ return this.itDelegate.nextIndex();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int previousIndex() {
|
|
+ return this.itDelegate.previousIndex();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void remove() {
|
|
+ this.itDelegate.remove();
|
|
+ ListeningList.this.onChange();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void set(T t) {
|
|
+ this.itDelegate.set(t);
|
|
+ ListeningList.this.onChange();
|
|
+
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void add(T t) {
|
|
+ this.itDelegate.add(t);
|
|
+ ListeningList.this.onChange();
|
|
+ }
|
|
+ };
|
|
+ }
|
|
+
|
|
+ @NotNull
|
|
+ @Override
|
|
+ public List<T> subList(int i, int i1) {
|
|
+ throw new UnsupportedOperationException();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Spliterator<T> spliterator() {
|
|
+ return this.delegate.spliterator();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Stream<T> stream() {
|
|
+ return this.delegate.stream();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Stream<T> parallelStream() {
|
|
+ return this.delegate.parallelStream();
|
|
+ }
|
|
+}
|
|
\ No newline at end of file
|
|
diff --git a/src/main/java/me/jellysquid/mods/lithium/common/util/collections/MaskedTickingBlockEntityList.java b/src/main/java/me/jellysquid/mods/lithium/common/util/collections/MaskedTickingBlockEntityList.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..7f7e4810a9aca382d75862e56b0cf93157b54b92
|
|
--- /dev/null
|
|
+++ b/src/main/java/me/jellysquid/mods/lithium/common/util/collections/MaskedTickingBlockEntityList.java
|
|
@@ -0,0 +1,320 @@
|
|
+package me.jellysquid.mods.lithium.common.util.collections;
|
|
+
|
|
+import com.google.common.collect.Iterators;
|
|
+import it.unimi.dsi.fastutil.ints.IntArrayList;
|
|
+import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap;
|
|
+import it.unimi.dsi.fastutil.objects.ReferenceArrayList;
|
|
+import org.jetbrains.annotations.NotNull;
|
|
+
|
|
+import java.util.*;
|
|
+import java.util.function.Predicate;
|
|
+
|
|
+public class MaskedTickingBlockEntityList<T> implements List<T> {
|
|
+ private final Predicate<T> mayContain;
|
|
+
|
|
+ private final Reference2IntOpenHashMap<T> allElements2Index;
|
|
+ private final ReferenceArrayList<T> allElements;
|
|
+
|
|
+ private final IntArrayList filteredSuccessor;
|
|
+ private final BitSet filteredElementsMask;
|
|
+
|
|
+ private int firstRemovedIndex;
|
|
+
|
|
+ //Visualization of the internal datastructures
|
|
+ //indices: 0 1 2 3 4 5 6 7 8 9
|
|
+ //allElements: A B C D - F G H I J //E was fully removed, C,F,G,I were filtered away
|
|
+ //filteredMask: 1 1 0 1 0 0 0 1 0 1
|
|
+ //successor: 0 1 3 - 7 - - - 9 - - (index offset by 1, due to the first successor having to point to the first element)
|
|
+ //Removals from the allElements ArrayList are done by setting the value to null
|
|
+ //The successor list is used to iterate through the allElements ArrayList with an increasing index, but skipping long chains of null elements.
|
|
+ //The BitSet mask is used to find the predecessor and successor quickly (not asymptotically fast, but fast enough)
|
|
+
|
|
+ public MaskedTickingBlockEntityList(List<T> list, Predicate<T> mayContain) {
|
|
+ this.mayContain = mayContain;
|
|
+ this.allElements = new ReferenceArrayList<>();
|
|
+ this.allElements2Index = new Reference2IntOpenHashMap<>();
|
|
+ this.allElements2Index.defaultReturnValue(-1);
|
|
+ this.filteredSuccessor = new IntArrayList();
|
|
+ this.filteredElementsMask = new BitSet();
|
|
+ this.firstRemovedIndex = Integer.MAX_VALUE;
|
|
+
|
|
+ for (T t : list) {
|
|
+ if (this.mayContain.test(t)) {
|
|
+ int index = this.allElements.size();
|
|
+ this.allElements.add(t);
|
|
+ this.filteredElementsMask.set(index);
|
|
+ this.filteredSuccessor.add(index);
|
|
+ this.allElements2Index.put(t, index);
|
|
+ }
|
|
+ }
|
|
+ this.filteredSuccessor.add(-1);
|
|
+ }
|
|
+
|
|
+ public void setEntryVisible(T t, boolean value) {
|
|
+ this.setEntryVisible(this.allElements2Index.getOrDefault(t, -1), value);
|
|
+ }
|
|
+
|
|
+ public void setEntryVisible(int index, boolean value) {
|
|
+ //Visualization of the operations possible
|
|
+ //All: A B C D - F G H I J (- for null)
|
|
+ //filteredMask:1 1 0 1 0 0 0 1 0 1
|
|
+ //indices: 0 1 2 3 4 5 6 7 8 9
|
|
+ //successor: 0 1 3 - 7 - - - 9 - - (- for no successor)
|
|
+ //Set F visible:
|
|
+ //All: A B C D - F G H I J
|
|
+ //filteredMask:1 1 0 1 0 1 0 1 0 1 //set mask at F to 1
|
|
+ //indices: 0 1 2 3 4 5 6 7 8 9
|
|
+ //successor: 0 1 3 - 5 - 7 - 9 - - //update successor of predecessor to F and set F's successor to old successor of predecessor
|
|
+ //Set D filtered:
|
|
+ //All: A B C D - F G H I J
|
|
+ //Mask: 1 1 0 0 0 1 0 1 0 1 //set mask at D to 0
|
|
+ //indices: 0 1 2 3 4 5 6 7 8 9
|
|
+ //successor: 0 1 5 - - - 7 - 9 - - //update successor of predecessor to old successor of D and remove D's successor value
|
|
+
|
|
+ //These calls do not modify the size, they can't cause rehashing, they are safe to use during iteration
|
|
+ if (index == -1 || value == this.filteredElementsMask.get(index)) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ this.filteredElementsMask.set(index, value);
|
|
+ int predecessor = this.filteredElementsMask.previousSetBit(index - 1);
|
|
+ if (value) {
|
|
+ int successor = this.filteredSuccessor.getInt(predecessor + 1);
|
|
+ this.filteredSuccessor.set(predecessor + 1, index);
|
|
+ this.filteredSuccessor.set(index + 1, successor);
|
|
+ } else {
|
|
+ int successor = this.filteredSuccessor.getInt(index + 1);
|
|
+ this.filteredSuccessor.set(predecessor + 1, successor);
|
|
+ this.filteredSuccessor.set(index + 1, -2); //no successor as this element cannot be reached
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private void compact() {
|
|
+ int targetSize = this.size();
|
|
+ int newIndex = this.firstRemovedIndex - 1;
|
|
+ int lastVisible = this.filteredElementsMask.previousSetBit(newIndex);
|
|
+
|
|
+
|
|
+ for (int i = newIndex + 1; i < this.allElements.size(); i++) {
|
|
+ T t = this.allElements.get(i);
|
|
+ if (t == null) {
|
|
+ continue;
|
|
+ }
|
|
+ boolean visible = this.filteredElementsMask.get(i);
|
|
+ //shift all entries to the lower indices (filling the gaps created by remove() setting null)
|
|
+ newIndex++;
|
|
+ //i is guaranteed to not be smaller than newIndex, therefore we can write to the same collections
|
|
+
|
|
+ this.allElements.set(newIndex, t);
|
|
+ this.allElements2Index.put(t, newIndex);
|
|
+ this.filteredElementsMask.set(newIndex, visible);
|
|
+
|
|
+ //update the successor links
|
|
+ this.filteredSuccessor.set(newIndex + 1, -2); //no successor as there is no next entry yet
|
|
+ if (visible) {
|
|
+ this.filteredSuccessor.set(lastVisible + 1, newIndex);
|
|
+ lastVisible = newIndex;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (newIndex + 1 != targetSize) {
|
|
+ throw new IllegalStateException("Compaction ended up with incorrect size: Should be: " + targetSize + " but is: " + (newIndex + 1));
|
|
+ }
|
|
+
|
|
+ this.filteredSuccessor.set(lastVisible + 1, -1); //-1 means this was the last element
|
|
+ this.firstRemovedIndex = Integer.MAX_VALUE;
|
|
+
|
|
+ this.filteredSuccessor.removeElements(targetSize + 1, this.filteredSuccessor.size());
|
|
+ this.allElements.removeElements(targetSize, this.allElements.size());
|
|
+ this.filteredElementsMask.clear(targetSize, this.filteredElementsMask.size());
|
|
+
|
|
+ this.filteredSuccessor.trim(targetSize * 4);
|
|
+ this.allElements.trim(targetSize * 4);
|
|
+ this.allElements2Index.trim(targetSize * 4);
|
|
+ }
|
|
+
|
|
+ public Iterator<T> filteredIterator() {
|
|
+ return new Iterator<T>() {
|
|
+ int next = MaskedTickingBlockEntityList.this.filteredSuccessor.getInt(0);
|
|
+ T prev;
|
|
+
|
|
+ @Override
|
|
+ public boolean hasNext() {
|
|
+ return this.next != -1;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public T next() {
|
|
+ int next = this.next;
|
|
+ T prev = MaskedTickingBlockEntityList.this.allElements.get(next);
|
|
+ this.prev = prev;
|
|
+ this.next = MaskedTickingBlockEntityList.this.filteredSuccessor.getInt(next + 1);
|
|
+ return prev;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void remove() {
|
|
+ MaskedTickingBlockEntityList.this.remove(this.prev);
|
|
+ }
|
|
+ };
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int size() {
|
|
+ return this.allElements2Index.size();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isEmpty() {
|
|
+ return this.size() == 0;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean contains(Object o) {
|
|
+ //noinspection SuspiciousMethodCalls
|
|
+ return this.allElements2Index.containsKey(o);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public @NotNull Iterator<T> iterator() {
|
|
+ return Iterators.unmodifiableIterator(this.allElements2Index.keySet().iterator());
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Object[] toArray() {
|
|
+ return this.allElements2Index.keySet().toArray();
|
|
+ }
|
|
+
|
|
+ @NotNull
|
|
+ @Override
|
|
+ public <T1> T1[] toArray(@NotNull T1[] t1s) {
|
|
+ //noinspection SuspiciousToArrayCall
|
|
+ return this.allElements2Index.keySet().toArray(t1s);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean add(T t) {
|
|
+ int arraySize = this.allElements.size();
|
|
+ int invalidEntries = arraySize - this.size();
|
|
+ //Compaction is done during the add operation as it is guaranteed to not happen during iteration
|
|
+ if ((arraySize > 2048 && invalidEntries > (arraySize >> 1)) || arraySize >= Integer.MAX_VALUE - 1 && invalidEntries != 0) {
|
|
+ this.compact();
|
|
+ }
|
|
+
|
|
+ if (!this.mayContain.test(t)) {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ int index = this.allElements.size();
|
|
+ int i = this.allElements2Index.putIfAbsent(t, index);
|
|
+ if (i != -1) {
|
|
+ return false;
|
|
+ }
|
|
+ this.allElements.add(t);
|
|
+ this.filteredSuccessor.add(0);//increase size so setEntryVisible doesn't crash with indexOutOfBounds
|
|
+ this.setEntryVisible(index, true);
|
|
+
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean remove(Object o) {
|
|
+ int index = this.allElements2Index.removeInt(o);
|
|
+ if (index == -1) {
|
|
+ return false;
|
|
+ }
|
|
+ this.setEntryVisible(index, false);
|
|
+ this.allElements.set(index, null);
|
|
+ this.firstRemovedIndex = Math.min(this.firstRemovedIndex, index);
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean containsAll(@NotNull Collection<?> c) {
|
|
+ return this.allElements2Index.keySet().containsAll(c);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean addAll(@NotNull Collection<? extends T> c) {
|
|
+ boolean b = false;
|
|
+ for (T t : c) {
|
|
+ this.add(t);
|
|
+ b = true;
|
|
+ }
|
|
+ return b;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean addAll(int index, @NotNull Collection<? extends T> c) {
|
|
+ throw new UnsupportedOperationException();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean removeAll(@NotNull Collection<?> c) {
|
|
+ boolean b = false;
|
|
+ for (Object t : c) {
|
|
+ b |= this.remove(t);
|
|
+ }
|
|
+ return b;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean retainAll(@NotNull Collection<?> c) {
|
|
+ throw new UnsupportedOperationException();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void clear() {
|
|
+ this.allElements2Index.clear();
|
|
+ this.allElements.clear();
|
|
+ this.filteredSuccessor.clear();
|
|
+ this.filteredElementsMask.clear();
|
|
+ this.firstRemovedIndex = Integer.MAX_VALUE;
|
|
+ this.filteredSuccessor.add(-1);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public T get(int index) {
|
|
+ throw new UnsupportedOperationException();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public T set(int index, T element) {
|
|
+ throw new UnsupportedOperationException();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void add(int index, T element) {
|
|
+ throw new UnsupportedOperationException();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public T remove(int index) {
|
|
+ throw new UnsupportedOperationException();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int indexOf(Object o) {
|
|
+ throw new UnsupportedOperationException();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int lastIndexOf(Object o) {
|
|
+ throw new UnsupportedOperationException();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public @NotNull ListIterator<T> listIterator() {
|
|
+ throw new UnsupportedOperationException();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public @NotNull ListIterator<T> listIterator(int index) {
|
|
+ throw new UnsupportedOperationException();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public @NotNull List<T> subList(int fromIndex, int toIndex) {
|
|
+ throw new UnsupportedOperationException();
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/me/jellysquid/mods/lithium/common/world/blockentity/BlockEntitySleepTracker.java b/src/main/java/me/jellysquid/mods/lithium/common/world/blockentity/BlockEntitySleepTracker.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..c54e1e1f9c6b09022c0f20d5ea4d552bd3ceed55
|
|
--- /dev/null
|
|
+++ b/src/main/java/me/jellysquid/mods/lithium/common/world/blockentity/BlockEntitySleepTracker.java
|
|
@@ -0,0 +1,7 @@
|
|
+package me.jellysquid.mods.lithium.common.world.blockentity;
|
|
+
|
|
+import net.minecraft.world.level.block.entity.TileEntity;
|
|
+
|
|
+public interface BlockEntitySleepTracker {
|
|
+ void setAwake(TileEntity tileEntity, boolean needsTicking);
|
|
+}
|
|
\ No newline at end of file
|
|
diff --git a/src/main/java/me/jellysquid/mods/lithium/common/world/blockentity/SleepingBlockEntity.java b/src/main/java/me/jellysquid/mods/lithium/common/world/blockentity/SleepingBlockEntity.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..4e765ab19ffb300b6c810333b2dc797637ae5c1b
|
|
--- /dev/null
|
|
+++ b/src/main/java/me/jellysquid/mods/lithium/common/world/blockentity/SleepingBlockEntity.java
|
|
@@ -0,0 +1,7 @@
|
|
+package me.jellysquid.mods.lithium.common.world.blockentity;
|
|
+
|
|
+public interface SleepingBlockEntity {
|
|
+ default boolean canTickOnSide(boolean isClient) {
|
|
+ return true;
|
|
+ }
|
|
+}
|
|
\ No newline at end of file
|
|
diff --git a/src/main/java/net/minecraft/world/level/World.java b/src/main/java/net/minecraft/world/level/World.java
|
|
index a5dd3b71f9b96047826d01002dbad718c463500c..324342f57249be6a37d7ad10a326a71edcd2fa82 100644
|
|
--- a/src/main/java/net/minecraft/world/level/World.java
|
|
+++ b/src/main/java/net/minecraft/world/level/World.java
|
|
@@ -97,8 +97,11 @@ import org.bukkit.event.block.BlockPhysicsEvent;
|
|
// CraftBukkit end
|
|
|
|
import net.gegy1000.tictacs.NonBlockingWorldAccess; // Yatopia
|
|
+import me.jellysquid.mods.lithium.common.util.collections.MaskedTickingBlockEntityList; // Yatopia
|
|
+import me.jellysquid.mods.lithium.common.world.blockentity.BlockEntitySleepTracker; // Yatopia
|
|
+import me.jellysquid.mods.lithium.common.world.blockentity.SleepingBlockEntity; // Yatopia
|
|
|
|
-public abstract class World implements GeneratorAccess, AutoCloseable, NonBlockingWorldAccess { // Yatopia
|
|
+public abstract class World implements GeneratorAccess, AutoCloseable, NonBlockingWorldAccess, BlockEntitySleepTracker { // Yatopia
|
|
|
|
protected static final Logger LOGGER = LogManager.getLogger();
|
|
public static final Codec<ResourceKey<World>> f = MinecraftKey.a.xmap(ResourceKey.b(IRegistry.L), ResourceKey::a);
|
|
@@ -107,9 +110,17 @@ public abstract class World implements GeneratorAccess, AutoCloseable, NonBlocki
|
|
public static final ResourceKey<World> THE_END = ResourceKey.a(IRegistry.L, new MinecraftKey("the_end"));
|
|
private static final EnumDirection[] a = EnumDirection.values();
|
|
//public final List<TileEntity> tileEntityList = Lists.newArrayList(); // Paper - remove unused list
|
|
- public final List<TileEntity> tileEntityListTick = me.jellysquid.mods.lithium.common.util.collections.HashedList.wrapper(Lists.newArrayList()); // Yatopia
|
|
+ public List<TileEntity> tileEntityListTick = me.jellysquid.mods.lithium.common.util.collections.HashedList.wrapper(Lists.newArrayList()); // Yatopia
|
|
protected final List<TileEntity> tileEntityListPending = me.jellysquid.mods.lithium.common.util.collections.HashedList.wrapper(Lists.newArrayList()); // Yatopia
|
|
protected final java.util.Set<TileEntity> tileEntityListUnload = java.util.Collections.newSetFromMap(new java.util.IdentityHashMap<>()); // Airplane - use set with faster contains
|
|
+ // Yatopia start - lithium: skip ticking block entities that are doing nothing
|
|
+ private MaskedTickingBlockEntityList<TileEntity> tileEntityListTick$lithium;
|
|
+
|
|
+ @Override
|
|
+ public void setAwake(TileEntity tileEntity, boolean needsTicking) {
|
|
+ this.tileEntityListTick$lithium.setEntryVisible(tileEntity, needsTicking);
|
|
+ }
|
|
+ // Yatopia end
|
|
public final Thread serverThread;
|
|
private final boolean debugWorld;
|
|
private int d;
|
|
@@ -332,6 +343,8 @@ public abstract class World implements GeneratorAccess, AutoCloseable, NonBlocki
|
|
this.keepSpawnInMemory = this.paperConfig.keepSpawnInMemory; // Paper
|
|
this.entityLimiter = new org.spigotmc.TickLimiter(spigotConfig.entityMaxTickTime);
|
|
this.tileLimiter = new org.spigotmc.TickLimiter(spigotConfig.tileMaxTickTime);
|
|
+ this.tileEntityListTick$lithium = new MaskedTickingBlockEntityList<>(this.tileEntityListTick, blockEntity -> ((SleepingBlockEntity) blockEntity).canTickOnSide(false)); // Yatopia
|
|
+ this.tileEntityListTick = tileEntityListTick$lithium; // Yatopia
|
|
}
|
|
|
|
// Paper start
|
|
@@ -996,6 +1009,15 @@ public abstract class World implements GeneratorAccess, AutoCloseable, NonBlocki
|
|
|
|
}
|
|
|
|
+ // Yatopia start - lithium: skip ticking block entities that are doing nothing
|
|
+ public Iterator<TileEntity> getAwakeBlockEntities(List<TileEntity> list) {
|
|
+ if (list == this.tileEntityListTick && list instanceof MaskedTickingBlockEntityList) {
|
|
+ return ((MaskedTickingBlockEntityList<TileEntity>) list).filteredIterator();
|
|
+ }
|
|
+ return list.iterator();
|
|
+ }
|
|
+ // Yatopia end
|
|
+
|
|
public void tickBlockEntities() {
|
|
GameProfilerFiller gameprofilerfiller = this.getMethodProfiler();
|
|
|
|
@@ -1018,11 +1040,19 @@ public abstract class World implements GeneratorAccess, AutoCloseable, NonBlocki
|
|
|
|
this.tickingTileEntities = true;
|
|
// Spigot start
|
|
+ // Yatopia start - lithium: skip ticking block entities that are doing nothing
|
|
// Iterator iterator = this.tileEntityListTick.iterator();
|
|
+ Iterator iterator = getAwakeBlockEntities(this.tileEntityListTick);
|
|
+
|
|
int tilesThisCycle = 0;
|
|
+ while (iterator.hasNext()) {
|
|
+ TileEntity tileentity = (TileEntity) iterator.next();
|
|
+ /*
|
|
for (tileTickPosition = 0; tileTickPosition < tileEntityListTick.size(); tileTickPosition++) { // Paper - Disable tick limiters
|
|
tileTickPosition = (tileTickPosition < tileEntityListTick.size()) ? tileTickPosition : 0;
|
|
TileEntity tileentity = (TileEntity) this.tileEntityListTick.get(tileTickPosition);
|
|
+ */
|
|
+ // Yatopia end
|
|
// Spigot start
|
|
if (tileentity == null) {
|
|
getServer().getLogger().severe("Spigot has detected a null entity and has removed it, preventing a crash");
|
|
@@ -1060,8 +1090,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable, NonBlocki
|
|
throwable.printStackTrace();
|
|
getServer().getPluginManager().callEvent(new ServerExceptionEvent(new ServerInternalException(msg, throwable)));
|
|
// Paper end
|
|
- tilesThisCycle--;
|
|
- this.tileEntityListTick.remove(tileTickPosition--);
|
|
+ iterator.remove(); // Yatopia
|
|
continue;
|
|
// Paper end
|
|
// Spigot start
|
|
@@ -1074,8 +1103,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable, NonBlocki
|
|
|
|
if (tileentity.isRemoved()) {
|
|
// Spigot start
|
|
- tilesThisCycle--;
|
|
- this.tileEntityListTick.remove(tileTickPosition--);
|
|
+ iterator.remove(); // Yatopia
|
|
// Spigot end
|
|
//this.tileEntityList.remove(tileentity); // Paper - remove unused list
|
|
// Paper - prevent double chunk lookups
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/entity/TileEntity.java b/src/main/java/net/minecraft/world/level/block/entity/TileEntity.java
|
|
index 93d02ccb87c17404c55884f52ae40c7b7ddfb103..cc9e6b9e5f550f9e633ea124f3dd8cbcf0e43e12 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/entity/TileEntity.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/entity/TileEntity.java
|
|
@@ -26,8 +26,9 @@ import org.bukkit.inventory.InventoryHolder;
|
|
import org.spigotmc.CustomTimingsHandler; // Spigot
|
|
import co.aikar.timings.MinecraftTimings; // Paper
|
|
import co.aikar.timings.Timing; // Paper
|
|
+import me.jellysquid.mods.lithium.common.world.blockentity.SleepingBlockEntity;
|
|
|
|
-public abstract class TileEntity implements net.minecraft.server.KeyedObject { // Paper
|
|
+public abstract class TileEntity implements net.minecraft.server.KeyedObject, SleepingBlockEntity { // Paper // Yatopia
|
|
|
|
public Timing tickTimer = MinecraftTimings.getTileEntityTimings(this); // Paper
|
|
// CraftBukkit start - data containers
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/entity/TileEntityBeehive.java b/src/main/java/net/minecraft/world/level/block/entity/TileEntityBeehive.java
|
|
index cacef4349a8dba02c2faee77e30f7c938f3d31af..a1651a7155f7fe2f01882a1eee4fbb5a067e1b38 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/entity/TileEntityBeehive.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/entity/TileEntityBeehive.java
|
|
@@ -23,6 +23,9 @@ import net.minecraft.world.level.block.BlockBeehive;
|
|
import net.minecraft.world.level.block.BlockCampfire;
|
|
import net.minecraft.world.level.block.BlockFire;
|
|
import net.minecraft.world.level.block.state.IBlockData;
|
|
+import me.jellysquid.mods.lithium.common.util.collections.ListeningList;
|
|
+import me.jellysquid.mods.lithium.common.world.blockentity.BlockEntitySleepTracker;
|
|
+import java.util.ArrayList;
|
|
|
|
public class TileEntityBeehive extends TileEntity implements ITickable {
|
|
|
|
@@ -30,11 +33,24 @@ public class TileEntityBeehive extends TileEntity implements ITickable {
|
|
@Nullable
|
|
public BlockPosition flowerPos = null;
|
|
public int maxBees = 3; // CraftBukkit - allow setting max amount of bees a hive can hold
|
|
+ public boolean doInit = true; // Yatopia
|
|
+ public boolean isTicking = true; // Yatopia
|
|
|
|
public TileEntityBeehive() {
|
|
super(TileEntityTypes.BEEHIVE);
|
|
}
|
|
|
|
+ // Yatopia start - lithium: skip ticking block entities that are doing nothing
|
|
+ public void checkSleepState() {
|
|
+ if (this.world != null ) {
|
|
+ if ((this.bees.size() == 0) == this.isTicking) {
|
|
+ this.isTicking = !this.isTicking;
|
|
+ ((BlockEntitySleepTracker) this.world).setAwake(this, this.isTicking);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ // Yatopia end
|
|
+
|
|
@Override
|
|
public void update() {
|
|
if (this.d()) {
|
|
@@ -309,6 +325,12 @@ public class TileEntityBeehive extends TileEntity implements ITickable {
|
|
|
|
@Override
|
|
public void tick() {
|
|
+ // Yatopia start - lithium: skip ticking block entities that are doing nothing
|
|
+ if (this.doInit) {
|
|
+ this.doInit = false;
|
|
+ this.checkSleepState();
|
|
+ }
|
|
+ // Yatopia end
|
|
if (this.bees.size() == 0) { return; } // Yatopia - TE optimizations
|
|
if (!this.world.isClientSide) {
|
|
this.y();
|
|
@@ -329,6 +351,7 @@ public class TileEntityBeehive extends TileEntity implements ITickable {
|
|
@Override
|
|
public void load(IBlockData iblockdata, NBTTagCompound nbttagcompound) {
|
|
super.load(iblockdata, nbttagcompound);
|
|
+ this.checkSleepState(); // Yatopia
|
|
this.bees.clear();
|
|
NBTTagList nbttaglist = nbttagcompound.getList("Bees", 10);
|
|
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/entity/TileEntityBell.java b/src/main/java/net/minecraft/world/level/block/entity/TileEntityBell.java
|
|
index 83626417aa9a00096680851a9a14f52f84fc7887..9f37518ada98c8ce64d283b49a9e3a7b6ec9457f 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/entity/TileEntityBell.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/entity/TileEntityBell.java
|
|
@@ -21,6 +21,7 @@ import net.minecraft.world.entity.player.EntityHuman;
|
|
import net.minecraft.world.level.World;
|
|
import net.minecraft.world.phys.AxisAlignedBB;
|
|
import org.apache.commons.lang3.mutable.MutableInt;
|
|
+import me.jellysquid.mods.lithium.common.world.blockentity.BlockEntitySleepTracker;
|
|
|
|
public class TileEntityBell extends TileEntity implements ITickable {
|
|
|
|
@@ -31,6 +32,8 @@ public class TileEntityBell extends TileEntity implements ITickable {
|
|
private List<EntityLiving> h; private List<EntityLiving> getEntitiesAtRing() { return this.h; } // Paper - OBFHELPER
|
|
private boolean i; private boolean getShouldReveal() { return this.i; } // Paper - OBFHELPER
|
|
private int j;
|
|
+ public boolean ringing; // Yatopia
|
|
+ public boolean resonating; // Yatopia
|
|
|
|
public TileEntityBell() {
|
|
super(TileEntityTypes.BELL);
|
|
@@ -38,6 +41,11 @@ public class TileEntityBell extends TileEntity implements ITickable {
|
|
|
|
@Override
|
|
public boolean setProperty(int i, int j) {
|
|
+ // Yatopia start - lithium: skip ticking block entities that are doing nothing
|
|
+ if (!this.ringing && i == 1 && this.world != null) {
|
|
+ ((BlockEntitySleepTracker) this.world).setAwake(this, true);
|
|
+ }
|
|
+ // Yatopia end
|
|
if (i == 1) {
|
|
this.f();
|
|
this.j = 0;
|
|
@@ -82,6 +90,11 @@ public class TileEntityBell extends TileEntity implements ITickable {
|
|
}
|
|
}
|
|
|
|
+ // Yatopia start - lithium: skip ticking block entities that are doing nothing
|
|
+ if (!this.ringing && !this.resonating && this.world != null) {
|
|
+ ((BlockEntitySleepTracker)this.world).setAwake(this, false);
|
|
+ }
|
|
+ // Yatopia end
|
|
}
|
|
|
|
private void d() {
|
|
@@ -89,6 +102,11 @@ public class TileEntityBell extends TileEntity implements ITickable {
|
|
}
|
|
|
|
public void a(EnumDirection enumdirection) {
|
|
+ // Yatopia start - lithium: skip ticking block entities that are doing nothing
|
|
+ if (!this.ringing && this.world != null) {
|
|
+ ((BlockEntitySleepTracker)this.world).setAwake(this, true);
|
|
+ }
|
|
+ // Yatopia end
|
|
BlockPosition blockposition = this.getPosition();
|
|
|
|
this.c = enumdirection;
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/entity/TileEntityBrewingStand.java b/src/main/java/net/minecraft/world/level/block/entity/TileEntityBrewingStand.java
|
|
index 95ca7d9e1eadbe5cc5674ed7352c1ed4d707363d..b5d5f38e520bb5d7912cc86d8ee25858bbd0786b 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/entity/TileEntityBrewingStand.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/entity/TileEntityBrewingStand.java
|
|
@@ -34,6 +34,7 @@ import org.bukkit.event.inventory.BrewEvent;
|
|
import org.bukkit.event.inventory.BrewingStandFuelEvent;
|
|
import org.bukkit.inventory.InventoryHolder;
|
|
// CraftBukkit end
|
|
+import me.jellysquid.mods.lithium.common.world.blockentity.BlockEntitySleepTracker;
|
|
|
|
public class TileEntityBrewingStand extends TileEntityContainer implements IWorldInventory, ITickable {
|
|
|
|
@@ -50,6 +51,7 @@ public class TileEntityBrewingStand extends TileEntityContainer implements IWorl
|
|
private int lastTick = MinecraftServer.currentTick;
|
|
public List<HumanEntity> transaction = new java.util.ArrayList<HumanEntity>();
|
|
private int maxStack = 64;
|
|
+ public boolean isTicking = true; // Yatopia
|
|
|
|
public void onOpen(CraftHumanEntity who) {
|
|
transaction.add(who);
|
|
@@ -72,6 +74,17 @@ public class TileEntityBrewingStand extends TileEntityContainer implements IWorl
|
|
return maxStack;
|
|
}
|
|
|
|
+ // Yatopia start - lithium: skip ticking block entities that are doing nothing
|
|
+ @Override
|
|
+ public void update() {
|
|
+ super.update();
|
|
+ if (!this.isTicking && this.world != null) {
|
|
+ this.isTicking = true;
|
|
+ ((BlockEntitySleepTracker)this.world).setAwake(this, true);
|
|
+ }
|
|
+ }
|
|
+ // Yatopia end
|
|
+
|
|
public void setMaxStackSize(int size) {
|
|
maxStack = size;
|
|
}
|
|
@@ -141,6 +154,12 @@ public class TileEntityBrewingStand extends TileEntityContainer implements IWorl
|
|
|
|
@Override
|
|
public void tick() {
|
|
+ // Yatopia start - lithium: skip ticking block entities that are doing nothing
|
|
+ if (this.brewTime == 0 && this.world != null) {
|
|
+ this.isTicking = false;
|
|
+ ((BlockEntitySleepTracker)this.world).setAwake(this, false);
|
|
+ }
|
|
+ // Yatopia end
|
|
ItemStack itemstack = (ItemStack) this.items.get(4);
|
|
|
|
if (this.fuelLevel <= 0 && itemstack.getItem() == Items.BLAZE_POWDER) {
|
|
@@ -280,6 +299,12 @@ public class TileEntityBrewingStand extends TileEntityContainer implements IWorl
|
|
@Override
|
|
public void load(IBlockData iblockdata, NBTTagCompound nbttagcompound) {
|
|
super.load(iblockdata, nbttagcompound);
|
|
+ // Yatopia start - lithium: skip ticking block entities that are doing nothing
|
|
+ if (!this.isTicking && this.world != null) {
|
|
+ this.isTicking = true;
|
|
+ ((BlockEntitySleepTracker) this.world).setAwake(this, true);
|
|
+ }
|
|
+ // Yatopia end
|
|
this.items = NonNullList.a(this.getSize(), ItemStack.b);
|
|
ContainerUtil.b(nbttagcompound, this.items);
|
|
this.brewTime = nbttagcompound.getShort("BrewTime");
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/entity/TileEntityCampfire.java b/src/main/java/net/minecraft/world/level/block/entity/TileEntityCampfire.java
|
|
index 08759f461ec947c0d5655557f49d8717afee6f00..cdff01d4da417ef1be6238d3faaf464ee7884bd5 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/entity/TileEntityCampfire.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/entity/TileEntityCampfire.java
|
|
@@ -27,12 +27,18 @@ import org.bukkit.craftbukkit.block.CraftBlock;
|
|
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
|
import org.bukkit.event.block.BlockCookEvent;
|
|
// CraftBukkit end
|
|
+import net.minecraft.core.NonNullList;
|
|
+import me.jellysquid.mods.lithium.common.world.blockentity.BlockEntitySleepTracker;
|
|
|
|
public class TileEntityCampfire extends TileEntity implements Clearable, ITickable {
|
|
|
|
private final NonNullList<ItemStack> items;
|
|
public final int[] cookingTimes;
|
|
public final int[] cookingTotalTimes;
|
|
+ // Yatopia start - lithium: skip ticking block entities that are doing nothing
|
|
+ public boolean isTicking = true;
|
|
+ public boolean doInit = true;
|
|
+ // Yatopia end
|
|
|
|
public TileEntityCampfire() {
|
|
super(TileEntityTypes.CAMPFIRE);
|
|
@@ -41,8 +47,50 @@ public class TileEntityCampfire extends TileEntity implements Clearable, ITickab
|
|
this.cookingTotalTimes = new int[4];
|
|
}
|
|
|
|
+ // Yatopia start - lithium: skip ticking block entities that are doing nothing
|
|
+ @Override
|
|
+ public void update() {
|
|
+ super.update();
|
|
+ this.checkSleepState();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void invalidateBlockCache() {
|
|
+ super.invalidateBlockCache();
|
|
+ this.checkSleepState();
|
|
+ }
|
|
+
|
|
+ public void checkSleepState() {
|
|
+ if (this.world == null) {
|
|
+ return;
|
|
+ }
|
|
+ boolean shouldTick = false;
|
|
+ NonNullList<ItemStack> beingCooked = this.items;
|
|
+ for (int i = 0; i < beingCooked.size(); i++) {
|
|
+ ItemStack stack = beingCooked.get(i);
|
|
+ if (!stack.isEmpty()) {
|
|
+ if (this.cookingTimes[i] > 0 || this.getBlock().get(BlockCampfire.LIT)) {
|
|
+ shouldTick = true;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (shouldTick != this.isTicking) {
|
|
+ this.isTicking = shouldTick;
|
|
+ ((BlockEntitySleepTracker)this.world).setAwake(this, shouldTick);
|
|
+ }
|
|
+ }
|
|
+ // Yatopia end
|
|
+
|
|
@Override
|
|
public void tick() {
|
|
+ // Yatopia start - lithium: skip ticking block entities that are doing nothing
|
|
+ if (this.doInit) {
|
|
+ this.doInit = false;
|
|
+ this.checkSleepState();
|
|
+ }
|
|
+ // Yatopia end
|
|
boolean flag = (Boolean) this.getBlock().get(BlockCampfire.LIT);
|
|
boolean flag1 = this.world.isClientSide;
|
|
|
|
@@ -149,6 +197,7 @@ public class TileEntityCampfire extends TileEntity implements Clearable, ITickab
|
|
@Override
|
|
public void load(IBlockData iblockdata, NBTTagCompound nbttagcompound) {
|
|
super.load(iblockdata, nbttagcompound);
|
|
+ this.checkSleepState(); // Yatopia - lithium: skip ticking block entities that are doing nothing
|
|
this.items.clear();
|
|
ContainerUtil.b(nbttagcompound, this.items);
|
|
int[] aint;
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/entity/TileEntityChest.java b/src/main/java/net/minecraft/world/level/block/entity/TileEntityChest.java
|
|
index 324b752c70e0bd7ea06caa98ec15cdd4e6ea40ae..ebc4385e648e6205b1b6893e818b302a66f1cfea 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/entity/TileEntityChest.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/entity/TileEntityChest.java
|
|
@@ -33,14 +33,27 @@ import net.minecraft.world.level.block.Blocks;
|
|
import org.bukkit.craftbukkit.entity.CraftHumanEntity;
|
|
import org.bukkit.entity.HumanEntity;
|
|
// CraftBukkit end
|
|
+ import me.jellysquid.mods.lithium.common.world.blockentity.BlockEntitySleepTracker; // Yatopia
|
|
|
|
public class TileEntityChest extends TileEntityLootable { // Paper - Remove ITickable
|
|
|
|
private gg.airplane.structs.ItemListWithBitset items; // Airplane
|
|
protected float a;
|
|
+ private float getAnimationAngle() { return a; } // Yatopia - OBFHELPER
|
|
protected float b;
|
|
+ private float getLastAnimationAngle() { return b; } // Yatopia - OBFHELPER
|
|
public int viewingCount;
|
|
private int j;
|
|
+ private int ticksOpen = j; // Yatopia - OBFHELPER
|
|
+ private int lastTime; // Yatopia
|
|
+
|
|
+ // Yatopia start - lithium: skip ticking block entities that are doing nothing
|
|
+ public void checkWakeUp() {
|
|
+ if ((this.viewingCount != 0 || this.getAnimationAngle() != 0.0F || this.getLastAnimationAngle() != 0) && this.world != null) {
|
|
+ ((BlockEntitySleepTracker) this.world).setAwake(this, true);
|
|
+ }
|
|
+ }
|
|
+ // Yatopia end
|
|
|
|
// CraftBukkit start - add fields and methods
|
|
public List<HumanEntity> transaction = new java.util.ArrayList<HumanEntity>();
|
|
@@ -137,11 +150,27 @@ public class TileEntityChest extends TileEntityLootable { // Paper - Remove ITic
|
|
}
|
|
|
|
public void tick() {
|
|
+ // Yatopia start - lithium: skip ticking block entities that are doing nothing
|
|
+ // noinspection ConstantConditions
|
|
+ int time = (int) this.world.getTime();
|
|
+ // ticksOpen == 0 implies most likely that this is the first tick. We don't want to update the value then.
|
|
+ // overflow case is handled by not going to sleep when this.ticksOpen == 0
|
|
+ if (this.ticksOpen != 0) {
|
|
+ this.ticksOpen += time - this.lastTime - 1;
|
|
+ }
|
|
+ this.lastTime = time;
|
|
+ // Yatopia end
|
|
+
|
|
int i = this.position.getX();
|
|
int j = this.position.getY();
|
|
int k = this.position.getZ();
|
|
|
|
++this.j;
|
|
+ // Yatopia start - lithium: skip ticking block entities that are doing nothing
|
|
+ if (this.viewingCount == 0 && this.getAnimationAngle() == 0.0F && this.getLastAnimationAngle() == 0 && this.ticksOpen != 0 && this.world != null) {
|
|
+ ((BlockEntitySleepTracker) this.world).setAwake(this, false);
|
|
+ }
|
|
+ // Yatopia end
|
|
}
|
|
|
|
public void doOpenLogic() {
|
|
@@ -247,6 +276,7 @@ public class TileEntityChest extends TileEntityLootable { // Paper - Remove ITic
|
|
|
|
@Override
|
|
public boolean setProperty(int i, int j) {
|
|
+ this.checkWakeUp(); // Yatopia - lithium: skip ticking block entities that are doing nothing
|
|
if (i == 1) {
|
|
this.viewingCount = j;
|
|
return true;
|
|
@@ -278,7 +308,7 @@ public class TileEntityChest extends TileEntityLootable { // Paper - Remove ITic
|
|
// CraftBukkit end
|
|
this.onOpen();
|
|
}
|
|
-
|
|
+ this.checkWakeUp(); // Yatopia - lithium: skip ticking block entities that are doing nothing
|
|
}
|
|
|
|
@Override
|
|
@@ -299,6 +329,7 @@ public class TileEntityChest extends TileEntityLootable { // Paper - Remove ITic
|
|
// CraftBukkit end
|
|
this.onOpen();
|
|
}
|
|
+ this.checkWakeUp(); // Yatopia - lithium: skip ticking block entities that are doing nothing
|
|
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/entity/TileEntityEnchantTable.java b/src/main/java/net/minecraft/world/level/block/entity/TileEntityEnchantTable.java
|
|
index 4b1cb089355b455c6210f2df1af797cc363997cf..0049a675557cbc05e361c12e9fb84a38a3a21160 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/entity/TileEntityEnchantTable.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/entity/TileEntityEnchantTable.java
|
|
@@ -9,6 +9,7 @@ import net.minecraft.util.MathHelper;
|
|
import net.minecraft.world.INamableTileEntity;
|
|
import net.minecraft.world.entity.player.EntityHuman;
|
|
import net.minecraft.world.level.block.state.IBlockData;
|
|
+import me.jellysquid.mods.lithium.common.world.blockentity.BlockEntitySleepTracker;
|
|
|
|
public class TileEntityEnchantTable extends TileEntity implements INamableTileEntity, ITickable {
|
|
|
|
@@ -51,6 +52,7 @@ public class TileEntityEnchantTable extends TileEntity implements INamableTileEn
|
|
@Override
|
|
public void tick() {
|
|
if (!org.yatopiamc.yatopia.server.YatopiaConfig.shouldTickEnchantingTables) { return; } // Yatopia - TE optimizations
|
|
+ ((BlockEntitySleepTracker) this.world).setAwake(this, false); // Yatopia
|
|
this.j = this.i;
|
|
this.l = this.k;
|
|
EntityHuman entityhuman = this.world.a((double) this.position.getX() + 0.5D, (double) this.position.getY() + 0.5D, (double) this.position.getZ() + 0.5D, 3.0D, false);
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/entity/TileEntityFurnace.java b/src/main/java/net/minecraft/world/level/block/entity/TileEntityFurnace.java
|
|
index 20193ba36c62fdd40ae905d1cea4bfd6d6aebcd7..b0f1c4f1660f3485303f0148bbc06dce4181e6b2 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/entity/TileEntityFurnace.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/entity/TileEntityFurnace.java
|
|
@@ -51,9 +51,11 @@ import org.bukkit.event.inventory.FurnaceBurnEvent;
|
|
import org.bukkit.event.inventory.FurnaceExtractEvent;
|
|
import org.bukkit.event.inventory.FurnaceSmeltEvent;
|
|
// CraftBukkit end
|
|
+import me.jellysquid.mods.lithium.common.world.blockentity.BlockEntitySleepTracker;
|
|
|
|
public abstract class TileEntityFurnace extends TileEntityContainer implements IWorldInventory, RecipeHolder, AutoRecipeOutput, ITickable {
|
|
|
|
+ private boolean isTicking = true; // Yatopia
|
|
private static final int[] g = new int[]{0};
|
|
private static final int[] h = new int[]{2, 1};
|
|
private static final int[] i = new int[]{1};
|
|
@@ -195,6 +197,17 @@ public abstract class TileEntityFurnace extends TileEntityContainer implements I
|
|
private int maxStack = MAX_STACK;
|
|
public List<HumanEntity> transaction = new java.util.ArrayList<HumanEntity>();
|
|
|
|
+ // Yatopia start - lithium: skip ticking block entities that are doing nothing
|
|
+ @Override
|
|
+ public void update() {
|
|
+ super.update();
|
|
+ if (!this.isTicking && this.world != null) {
|
|
+ this.isTicking = true;
|
|
+ ((BlockEntitySleepTracker) this.world).setAwake(this, true);
|
|
+ }
|
|
+ }
|
|
+ // Yatopia end
|
|
+
|
|
public List<ItemStack> getContents() {
|
|
return this.items;
|
|
}
|
|
@@ -257,6 +270,12 @@ public abstract class TileEntityFurnace extends TileEntityContainer implements I
|
|
@Override
|
|
public void load(IBlockData iblockdata, NBTTagCompound nbttagcompound) {
|
|
super.load(iblockdata, nbttagcompound);
|
|
+ // Yatopia start - lithium: skip ticking block entities that are doing nothing
|
|
+ if (!this.isTicking && this.world != null) {
|
|
+ this.isTicking = true;
|
|
+ ((BlockEntitySleepTracker)this.world).setAwake(this, true);
|
|
+ }
|
|
+ // Yatopia end
|
|
this.items = NonNullList.a(this.getSize(), ItemStack.b);
|
|
ContainerUtil.b(nbttagcompound, this.items);
|
|
this.burnTime = nbttagcompound.getShort("BurnTime");
|
|
@@ -369,7 +388,12 @@ public abstract class TileEntityFurnace extends TileEntityContainer implements I
|
|
if (flag1) {
|
|
this.update();
|
|
}
|
|
-
|
|
+ // Yatopia start - lithium: skip ticking block entities that are doing nothing
|
|
+ if (!this.isTicking && this.world != null) {
|
|
+ this.isTicking = true;
|
|
+ ((BlockEntitySleepTracker)this.world).setAwake(this, true);
|
|
+ }
|
|
+ // Yatopia end
|
|
}
|
|
|
|
protected boolean canBurn(@Nullable IRecipe<?> irecipe) {
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/entity/TileEntityShulkerBox.java b/src/main/java/net/minecraft/world/level/block/entity/TileEntityShulkerBox.java
|
|
index c1a90eb01689b8b91200ba49d58360d5ea2004c4..8095740f1848443e87fd52c14d19dabb00a3ecd4 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/entity/TileEntityShulkerBox.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/entity/TileEntityShulkerBox.java
|
|
@@ -33,6 +33,7 @@ import net.minecraft.world.phys.shapes.VoxelShapes;
|
|
import org.bukkit.craftbukkit.entity.CraftHumanEntity;
|
|
import org.bukkit.entity.HumanEntity;
|
|
// CraftBukkit end
|
|
+import me.jellysquid.mods.lithium.common.world.blockentity.BlockEntitySleepTracker;
|
|
|
|
public class TileEntityShulkerBox extends TileEntityLootable implements IWorldInventory, ITickable {
|
|
|
|
@@ -41,7 +42,9 @@ public class TileEntityShulkerBox extends TileEntityLootable implements IWorldIn
|
|
public int viewingCount;
|
|
private TileEntityShulkerBox.AnimationPhase i;
|
|
private float j;
|
|
+ public float animationProgress = j; // Yatopia - OBFHELPER
|
|
private float k;
|
|
+ public float prevAnimationProgress = k; // Yatopia - OBFHELPER
|
|
@Nullable
|
|
private EnumColor l;
|
|
private boolean m;
|
|
@@ -96,6 +99,11 @@ public class TileEntityShulkerBox extends TileEntityLootable implements IWorldIn
|
|
this.m();
|
|
}
|
|
|
|
+ // Yatopia start - lithium: skip ticking block entities that are doing nothing
|
|
+ if (this.getAnimationPhase() == TileEntityShulkerBox.AnimationPhase.CLOSED && this.prevAnimationProgress == 0f && this.animationProgress == 0f && this.world != null) {
|
|
+ ((BlockEntitySleepTracker) this.world).setAwake(this, false);
|
|
+ }
|
|
+ // Yatopia end
|
|
}
|
|
|
|
protected void h() {
|
|
@@ -127,6 +135,7 @@ public class TileEntityShulkerBox extends TileEntityLootable implements IWorldIn
|
|
|
|
}
|
|
|
|
+ public TileEntityShulkerBox.AnimationPhase getAnimationPhase() {return this.j(); } // Yatopia - OBFHELPER
|
|
public TileEntityShulkerBox.AnimationPhase j() {
|
|
return this.i;
|
|
}
|
|
@@ -209,6 +218,7 @@ public class TileEntityShulkerBox extends TileEntityLootable implements IWorldIn
|
|
|
|
@Override
|
|
public boolean setProperty(int i, int j) {
|
|
+ if (this.world != null && i == 1) ((BlockEntitySleepTracker) this.world).setAwake(this, true); // Yatopia
|
|
if (i == 1) {
|
|
this.viewingCount = j;
|
|
if (j == 0) {
|