The missing optimizations

This commit is contained in:
tr7zw 2020-06-27 20:02:39 +02:00
parent 3977242dcf
commit 05a6f94b72
5 changed files with 865 additions and 0 deletions

View File

@ -0,0 +1,211 @@
From 25534c1f9b7f6fc7d0394851f278a520d738ad11 Mon Sep 17 00:00:00 2001
From: tr7zw <tr7zw@live.de>
Date: Tue, 12 May 2020 00:38:31 +0200
Subject: [PATCH] lithium MixinBiome
---
.../common/util/collections/HashedList.java | 168 ++++++++++++++++++
.../java/net/minecraft/server/BiomeBase.java | 4 +-
2 files changed, 171 insertions(+), 1 deletion(-)
create mode 100644 src/main/java/me/jellysquid/mods/lithium/common/util/collections/HashedList.java
diff --git a/src/main/java/me/jellysquid/mods/lithium/common/util/collections/HashedList.java b/src/main/java/me/jellysquid/mods/lithium/common/util/collections/HashedList.java
new file mode 100644
index 000000000..a2e3e96e1
--- /dev/null
+++ b/src/main/java/me/jellysquid/mods/lithium/common/util/collections/HashedList.java
@@ -0,0 +1,168 @@
+package me.jellysquid.mods.lithium.common.util.collections;
+
+import it.unimi.dsi.fastutil.objects.ObjectArraySet;
+
+import java.util.*;
+
+/**
+ * Wraps a {@link List} with a hash table which provides O(1) lookups for {@link Collection#contains(Object)}.
+ *
+ * @see https://github.com/jellysquid3/lithium-fabric/blob/1.16.x/fabric/src/main/java/me/jellysquid/mods/lithium/common/util/collections/HashedList.java
+ */
+public class HashedList<T> implements List<T> {
+ private final List<T> list;
+ private final Set<T> set;
+
+ private HashedList(List<T> list, Set<T> set) {
+ this.list = list;
+ this.set = set;
+ }
+
+ @Override
+ public int size() {
+ return this.list.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return this.list.isEmpty();
+ }
+
+ @Override
+ public boolean contains(Object o) {
+ return this.set.contains(o);
+ }
+
+ @Override
+ public Iterator<T> iterator() {
+ return this.list.iterator();
+ }
+
+ @Override
+ public Object[] toArray() {
+ return this.list.toArray();
+ }
+
+ @Override
+ public <T1> T1[] toArray(T1[] a) {
+ return this.list.toArray(a);
+ }
+
+ @Override
+ public boolean add(T t) {
+ this.set.add(t);
+
+ return this.list.add(t);
+ }
+
+ @Override
+ public boolean remove(Object o) {
+ this.set.remove(o);
+
+ return this.list.remove(o);
+ }
+
+ @Override
+ public boolean containsAll(Collection<?> c) {
+ return this.set.containsAll(c);
+ }
+
+ @Override
+ public boolean addAll(Collection<? extends T> c) {
+ this.set.addAll(c);
+
+ return this.list.addAll(c);
+ }
+
+ @Override
+ public boolean addAll(int index, Collection<? extends T> c) {
+ this.set.addAll(c);
+
+ return this.list.addAll(index, c);
+ }
+
+ @Override
+ public boolean removeAll(Collection<?> c) {
+ this.set.removeAll(c);
+
+ return this.list.removeAll(c);
+ }
+
+ @Override
+ public boolean retainAll(Collection<?> c) {
+ this.set.retainAll(c);
+
+ return this.list.retainAll(c);
+ }
+
+ @Override
+ public void clear() {
+ this.set.clear();
+ this.list.clear();
+ }
+
+ @Override
+ public T get(int index) {
+ return this.list.get(index);
+ }
+
+ @Override
+ public T set(int index, T element) {
+ T prev = this.list.set(index, element);
+
+ if (prev != null) {
+ this.set.remove(prev);
+ }
+
+ this.set.add(element);
+
+ return prev;
+ }
+
+ @Override
+ public void add(int index, T element) {
+ this.set.add(element);
+
+ this.list.add(index, element);
+ }
+
+ @Override
+ public T remove(int index) {
+ T prev = this.list.remove(index);
+
+ if (prev != null) {
+ this.set.remove(prev);
+ }
+
+ return prev;
+ }
+
+ @Override
+ public int indexOf(Object o) {
+ return this.list.indexOf(o);
+ }
+
+ @Override
+ public int lastIndexOf(Object o) {
+ return this.list.lastIndexOf(o);
+ }
+
+ @Override
+ public ListIterator<T> listIterator() {
+ return this.list.listIterator();
+ }
+
+ @Override
+ public ListIterator<T> listIterator(int index) {
+ return this.list.listIterator(index);
+ }
+
+ @Override
+ public List<T> subList(int fromIndex, int toIndex) {
+ return this.list.subList(fromIndex, toIndex);
+ }
+
+ public static <T> HashedList<T> wrapper(List<T> list) {
+ return new HashedList<>(list, new ObjectArraySet<>(list));
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/net/minecraft/server/BiomeBase.java b/src/main/java/net/minecraft/server/BiomeBase.java
index 798d84795..897e56f0c 100644
--- a/src/main/java/net/minecraft/server/BiomeBase.java
+++ b/src/main/java/net/minecraft/server/BiomeBase.java
@@ -7,6 +7,8 @@ import com.google.common.collect.Sets;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import it.unimi.dsi.fastutil.longs.Long2FloatLinkedOpenHashMap;
+import me.jellysquid.mods.lithium.common.util.collections.HashedList;
+
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
@@ -139,7 +141,7 @@ public class BiomeBase {
for (j = 0; j < i; ++j) {
EnumCreatureType enumcreaturetype = aenumcreaturetype[j];
- this.v.put(enumcreaturetype, new MobList()); // Paper
+ this.v.put(enumcreaturetype, HashedList.wrapper(new MobList())); // Paper // YAPFA lithium change
}
} else {
--
2.25.1.windows.1

View File

@ -0,0 +1,41 @@
From 86be96f8ba8285729813e2e397c762b4123c1357 Mon Sep 17 00:00:00 2001
From: tr7zw <tr7zw@live.de>
Date: Tue, 16 Jun 2020 17:29:20 +0200
Subject: [PATCH] Item stuck sleep config
---
src/main/java/de/tr7zw/yapfa/YapfaConfig.java | 5 +++++
src/main/java/net/minecraft/server/EntityItem.java | 2 +-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/main/java/de/tr7zw/yapfa/YapfaConfig.java b/src/main/java/de/tr7zw/yapfa/YapfaConfig.java
index 716b2dea9..a158e9dc8 100644
--- a/src/main/java/de/tr7zw/yapfa/YapfaConfig.java
+++ b/src/main/java/de/tr7zw/yapfa/YapfaConfig.java
@@ -216,4 +216,9 @@ public class YapfaConfig {
pistonPushLimit = getInt("settings.pistonPushLimit", 12);
}
+ public static int itemStuckSleepTicks = 1;
+ private static void itemStuckSleepTicks() {
+ itemStuckSleepTicks = getInt("settings.itemStuckSleepTicks", 1);
+ }
+
}
\ No newline at end of file
diff --git a/src/main/java/net/minecraft/server/EntityItem.java b/src/main/java/net/minecraft/server/EntityItem.java
index a7860cb4d..6c320dca0 100644
--- a/src/main/java/net/minecraft/server/EntityItem.java
+++ b/src/main/java/net/minecraft/server/EntityItem.java
@@ -81,7 +81,7 @@ public class EntityItem extends Entity {
if (this.world.isClientSide) {
this.noclip = false;
- } else {
+ } else if(!this.onGround || this.noclip || this.ticksLived % de.tr7zw.yapfa.YapfaConfig.itemStuckSleepTicks == 0) { // YAPFA
this.noclip = !this.world.getCubes(this);
if (this.noclip) {
this.k(this.locX(), (this.getBoundingBox().minY + this.getBoundingBox().maxY) / 2.0D, this.locZ());
--
2.25.1.windows.1

View File

@ -0,0 +1,194 @@
From 41a6bfdd6dc58410f9b3e347f4e7b8c1b787cd4e Mon Sep 17 00:00:00 2001
From: tr7zw <tr7zw@live.de>
Date: Fri, 19 Jun 2020 19:21:35 +0200
Subject: [PATCH] Option for simpler Villagers
Option to extremly simplefy the villager AI.
---
src/main/java/de/tr7zw/yapfa/YapfaConfig.java | 10 +++
.../net/minecraft/server/EntityVillager.java | 83 ++++++++++++++++++-
2 files changed, 92 insertions(+), 1 deletion(-)
diff --git a/src/main/java/de/tr7zw/yapfa/YapfaConfig.java b/src/main/java/de/tr7zw/yapfa/YapfaConfig.java
index a158e9dc8..aea46527b 100644
--- a/src/main/java/de/tr7zw/yapfa/YapfaConfig.java
+++ b/src/main/java/de/tr7zw/yapfa/YapfaConfig.java
@@ -221,4 +221,14 @@ public class YapfaConfig {
itemStuckSleepTicks = getInt("settings.itemStuckSleepTicks", 1);
}
+ public static boolean simplerVillagerBehavior = false;
+ private static void simplerVillagerBehavior() {
+ simplerVillagerBehavior = getBoolean("settings.villager.simplerVillagerBehavior", false);
+ }
+
+ public static boolean villagersHideAtNight = false;
+ private static void villagersHideAtNight() {
+ villagersHideAtNight = getBoolean("settings.villager.villagersHideAtNight", false);
+ }
+
}
\ No newline at end of file
diff --git a/src/main/java/net/minecraft/server/EntityVillager.java b/src/main/java/net/minecraft/server/EntityVillager.java
index bf019043a..5db697b66 100644
--- a/src/main/java/net/minecraft/server/EntityVillager.java
+++ b/src/main/java/net/minecraft/server/EntityVillager.java
@@ -7,6 +7,8 @@ import com.mojang.datafixers.util.Pair;
import com.mojang.serialization.DataResult;
import com.mojang.serialization.Dynamic;
import com.mojang.serialization.DynamicOps;
+
+import de.tr7zw.yapfa.YapfaConfig;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import java.util.Collection;
import java.util.Iterator;
@@ -30,7 +32,9 @@ import org.bukkit.event.entity.VillagerReplenishTradeEvent;
// CraftBukkit end
public class EntityVillager extends EntityVillagerAbstract implements ReputationHandler, VillagerDataHolder {
-
+
+ //YAPFA
+ private boolean simplerVillagerBehavior = YapfaConfig.simplerVillagerBehavior; //get this during villager creation so a reloaded config doesn't get them into an invalid state
private static final DataWatcherObject<VillagerData> by = DataWatcher.a(EntityVillager.class, DataWatcherRegistry.q);
public static final Map<Item, Integer> bw = ImmutableMap.of(Items.BREAD, 4, Items.POTATO, 1, Items.CARROT, 1, Items.BEETROOT, 1);
private static final Set<Item> bz = ImmutableSet.of(Items.BREAD, Items.POTATO, Items.CARROT, Items.WHEAT, Items.WHEAT_SEEDS, Items.BEETROOT, new Item[]{Items.BEETROOT_SEEDS});
@@ -66,12 +70,49 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation
public EntityVillager(EntityTypes<? extends EntityVillager> entitytypes, World world, VillagerType villagertype) {
super(entitytypes, world);
this.bF = new Reputation();
+ if(!simplerVillagerBehavior) {
((Navigation) this.getNavigation()).a(true);
this.getNavigation().d(true);
+ }else {
+ initPathfinder();
+ }
this.setCanPickupLoot(true);
this.setVillagerData(this.getVillagerData().withType(villagertype).withProfession(VillagerProfession.NONE));
}
+ //YAPFA start
+ @Override
+ protected void initPathfinder() {
+ if(!simplerVillagerBehavior)return;
+ this.goalSelector.a(0, new PathfinderGoalFloat(this));
+ if(YapfaConfig.villagersHideAtNight) {
+ this.goalSelector.a(0, new PathfinderGoalUseItem<>(this, PotionUtil.a(new ItemStack(Items.POTION), Potions.INVISIBILITY), SoundEffects.ENTITY_WANDERING_TRADER_DISAPPEARED, (entityvillagertrader) -> {
+ return !this.world.isDay() && !entityvillagertrader.isInvisible();
+ }));
+ this.goalSelector.a(0, new PathfinderGoalUseItem<>(this, new ItemStack(Items.MILK_BUCKET), SoundEffects.ENTITY_WANDERING_TRADER_REAPPEARED, (entityvillagertrader) -> {
+ return this.world.isDay() && entityvillagertrader.isInvisible();
+ }));
+ }
+ this.goalSelector.a(1, new PathfinderGoalTradeWithPlayer(this));
+ this.goalSelector.a(1, new PathfinderGoalAvoidTarget<>(this, EntityZombie.class, 8.0F, 0.5D, 0.5D));
+ this.goalSelector.a(1, new PathfinderGoalAvoidTarget<>(this, EntityEvoker.class, 12.0F, 0.5D, 0.5D));
+ this.goalSelector.a(1, new PathfinderGoalAvoidTarget<>(this, EntityVindicator.class, 8.0F, 0.5D, 0.5D));
+ this.goalSelector.a(1, new PathfinderGoalAvoidTarget<>(this, EntityVex.class, 8.0F, 0.5D, 0.5D));
+ this.goalSelector.a(1, new PathfinderGoalAvoidTarget<>(this, EntityPillager.class, 15.0F, 0.5D, 0.5D));
+ this.goalSelector.a(1, new PathfinderGoalAvoidTarget<>(this, EntityIllagerIllusioner.class, 12.0F, 0.5D, 0.5D));
+ this.goalSelector.a(1, new PathfinderGoalPanic(this, 0.5D));
+ this.goalSelector.a(1, new PathfinderGoalLookAtTradingPlayer(this));
+ this.goalSelector.a(2, new PathfinderGoalStrollVillageGolem(this, 0.6D));
+ this.goalSelector.a(3, new PathfinderGoalMoveThroughVillage(this, 0.6D, false, 4, () -> {
+ return false;
+ }));
+ this.goalSelector.a(4, new PathfinderGoalMoveTowardsRestriction(this, 0.35D));
+ this.goalSelector.a(8, new PathfinderGoalRandomStrollLand(this, 0.35D));
+ this.goalSelector.a(9, new PathfinderGoalInteract(this, EntityHuman.class, 3.0F, 1.0F));
+ this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityInsentient.class, 8.0F));
+ }
+ //YAPFA end
+
@Override
public BehaviorController<EntityVillager> getBehaviorController() {
return (BehaviorController<EntityVillager>) super.getBehaviorController(); // CraftBukkit - decompile error
@@ -84,6 +125,7 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation
@Override
protected BehaviorController<?> a(Dynamic<?> dynamic) {
+ if(simplerVillagerBehavior)return super.a(dynamic); //YAPFA Don't use behaviorcontroller for simple Villagers
BehaviorController<EntityVillager> behaviorcontroller = this.cJ().a(dynamic);
this.a(behaviorcontroller);
@@ -162,10 +204,43 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation
}
// Spigot End
+ // YAPFA start
+ private VillagerProfession getRandomProfession() {
+ int type = random.nextInt(13);
+ switch(type) {
+ case 0: return VillagerProfession.ARMORER;
+ case 1: return VillagerProfession.BUTCHER;
+ case 2: return VillagerProfession.CARTOGRAPHER;
+ case 3: return VillagerProfession.CLERIC;
+ case 4: return VillagerProfession.FARMER;
+ case 5: return VillagerProfession.FISHERMAN;
+ case 6: return VillagerProfession.FLETCHER;
+ case 7: return VillagerProfession.LEATHERWORKER;
+ case 8: return VillagerProfession.LIBRARIAN;
+ case 9: return VillagerProfession.MASON;
+ case 10: return VillagerProfession.SHEPHERD;
+ case 11: return VillagerProfession.TOOLSMITH;
+ case 12: return VillagerProfession.WEAPONSMITH;
+ default: return VillagerProfession.FARMER;
+ }
+ }
+
+ // YAPFA end
+
@Override
protected void mobTick() { mobTick(false); }
protected void mobTick(boolean inactive) {
+ // YAPFA start
+ if(simplerVillagerBehavior && this.getVillagerData().getProfession() == VillagerProfession.NONE)
+ this.setVillagerData(this.getVillagerData().withProfession(getRandomProfession()));
+ if(simplerVillagerBehavior) {
+ if (canRefresh()) {
+ restUses();
+ }
+ }
+ // YAPFA end
this.world.getMethodProfiler().enter("villagerBrain");
+ if(!simplerVillagerBehavior) // YAPFA
if (!inactive) this.getBehaviorController().a((WorldServer) this.world, this); // CraftBukkit - decompile error // Paper
if (this.bM) {
this.bM = false;
@@ -296,6 +371,8 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation
return true;
}
+ public void restUses() {fb();} // YAPFA obf helper
+
public void fb() {
this.fp();
Iterator iterator = this.getOffers().iterator();
@@ -330,6 +407,8 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation
return this.bK == 0 || this.bK < 2 && this.world.getTime() > this.bJ + 2400L;
}
+ public boolean canRefresh() {return fc();} // YAPFA obf helper
+
public boolean fc() {
long i = this.bJ + 12000L;
long j = this.world.getTime();
@@ -577,6 +656,7 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation
}
private void a(Entity entity) {
+ if(simplerVillagerBehavior)return; // YAPFA
if (this.world instanceof WorldServer) {
Optional<List<EntityLiving>> optional = this.bn.getMemory(MemoryModuleType.VISIBLE_MOBS);
@@ -593,6 +673,7 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation
}
public void a(MemoryModuleType<GlobalPos> memorymoduletype) {
+ if(simplerVillagerBehavior)return; // YAPFA
if (this.world instanceof WorldServer) {
MinecraftServer minecraftserver = ((WorldServer) this.world).getMinecraftServer();
--
2.25.1.windows.1

View File

@ -0,0 +1,89 @@
From 40fa0bc6f6838a9bb268864cc02a03b6c1e7e4d8 Mon Sep 17 00:00:00 2001
From: tr7zw <tr7zw@live.de>
Date: Thu, 25 Jun 2020 23:40:12 +0200
Subject: [PATCH] Heavily optimize furnance fuel and recipe lookups
---
.../net/minecraft/server/CraftingManager.java | 19 +++++++++++++++-
.../minecraft/server/TileEntityFurnace.java | 22 +++++++++++++++++++
2 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/src/main/java/net/minecraft/server/CraftingManager.java b/src/main/java/net/minecraft/server/CraftingManager.java
index f27c7041c..384cb3c62 100644
--- a/src/main/java/net/minecraft/server/CraftingManager.java
+++ b/src/main/java/net/minecraft/server/CraftingManager.java
@@ -89,7 +89,24 @@ public class CraftingManager extends ResourceDataJson {
}).findFirst();
c0.setCurrentRecipe(recipe.orElse(null)); // CraftBukkit - Clear recipe when no recipe is found
// CraftBukkit end
- return recipe;
+ // YAPFA start
+ if(c0.getCurrentRecipe() != null) {
+ Optional<T> optional = recipes.a(c0.getCurrentRecipe(), world, c0);
+ if(optional.isPresent()) {
+ c0.setCurrentRecipe(optional.get());
+ return optional;
+ }
+ }
+ for(IRecipe<C> rep : this.a(recipes)) {
+ Optional<T> optional = recipes.a(rep, world, c0);
+ if(optional.isPresent()) {
+ c0.setCurrentRecipe(optional.get());
+ return optional;
+ }
+ }
+ c0.setCurrentRecipe(null); // CraftBukkit - Clear recipe when no recipe is found
+ return Optional.empty();
+ // YAPFA end
}
public <C extends IInventory, T extends IRecipe<C>> List<T> a(Recipes<T> recipes) {
diff --git a/src/main/java/net/minecraft/server/TileEntityFurnace.java b/src/main/java/net/minecraft/server/TileEntityFurnace.java
index 59aa2f8a7..7b1d20d39 100644
--- a/src/main/java/net/minecraft/server/TileEntityFurnace.java
+++ b/src/main/java/net/minecraft/server/TileEntityFurnace.java
@@ -99,7 +99,13 @@ public abstract class TileEntityFurnace extends TileEntityContainer implements I
this.c = recipes;
}
+ //YAPFA
+ private static Map<Item, Integer> cachedFuelMap = null;
+
public static Map<Item, Integer> f() {
+ if(cachedFuelMap != null) {
+ return cachedFuelMap; // YAPFA
+ }
Map<Item, Integer> map = Maps.newLinkedHashMap();
a(map, (IMaterial) Items.LAVA_BUCKET, 20000);
@@ -162,6 +168,7 @@ public abstract class TileEntityFurnace extends TileEntityContainer implements I
a(map, (IMaterial) Blocks.FLETCHING_TABLE, 300);
a(map, (IMaterial) Blocks.SMITHING_TABLE, 300);
a(map, (IMaterial) Blocks.COMPOSTER, 300);
+ cachedFuelMap = map; // YAPFA
return map;
}
@@ -613,4 +620,19 @@ public abstract class TileEntityFurnace extends TileEntityContainer implements I
}
}
+
+ // YAPFA start
+ private IRecipe cachedRecipe = null;
+ @Override
+ public IRecipe getCurrentRecipe() {
+ return cachedRecipe;
+ }
+ @Override
+ public void setCurrentRecipe(IRecipe recipe) {
+ cachedRecipe = recipe;
+ }
+
+
+ // YAPFA end
+
}
--
2.25.1.windows.1

View File

@ -0,0 +1,330 @@
From 920e25115ab67f8faed683ea741742f81a933bb4 Mon Sep 17 00:00:00 2001
From: tr7zw <tr7zw@live.de>
Date: Fri, 26 Jun 2020 01:11:47 +0200
Subject: [PATCH] Optimize Hopper logic
---
.../net/minecraft/server/BlockHopper.java | 230 ++++++++++++++++++
.../minecraft/server/TileEntityHopper.java | 36 ++-
2 files changed, 262 insertions(+), 4 deletions(-)
create mode 100644 src/main/java/net/minecraft/server/BlockHopper.java
diff --git a/src/main/java/net/minecraft/server/BlockHopper.java b/src/main/java/net/minecraft/server/BlockHopper.java
new file mode 100644
index 000000000..31ee358f8
--- /dev/null
+++ b/src/main/java/net/minecraft/server/BlockHopper.java
@@ -0,0 +1,230 @@
+package net.minecraft.server;
+
+import java.util.OptionalInt;
+import net.minecraft.server.Block;
+import net.minecraft.server.BlockActionContext;
+import net.minecraft.server.BlockBase;
+import net.minecraft.server.BlockPosition;
+import net.minecraft.server.BlockProperties;
+import net.minecraft.server.BlockStateBoolean;
+import net.minecraft.server.BlockStateDirection;
+import net.minecraft.server.BlockStateList;
+import net.minecraft.server.BlockTileEntity;
+import net.minecraft.server.Container;
+import net.minecraft.server.Entity;
+import net.minecraft.server.EntityHuman;
+import net.minecraft.server.EntityLiving;
+import net.minecraft.server.EnumBlockMirror;
+import net.minecraft.server.EnumBlockRotation;
+import net.minecraft.server.EnumDirection;
+import net.minecraft.server.EnumHand;
+import net.minecraft.server.EnumInteractionResult;
+import net.minecraft.server.EnumRenderType;
+import net.minecraft.server.IBlockAccess;
+import net.minecraft.server.IBlockData;
+import net.minecraft.server.IBlockDataHolder;
+import net.minecraft.server.IBlockState;
+import net.minecraft.server.IChatBaseComponent;
+import net.minecraft.server.IHopper;
+import net.minecraft.server.IInventory;
+import net.minecraft.server.ITileInventory;
+import net.minecraft.server.InventoryUtils;
+import net.minecraft.server.ItemStack;
+import net.minecraft.server.MinecraftKey;
+import net.minecraft.server.MovingObjectPositionBlock;
+import net.minecraft.server.OperatorBoolean;
+import net.minecraft.server.PathMode;
+import net.minecraft.server.StatisticList;
+import net.minecraft.server.TileEntity;
+import net.minecraft.server.TileEntityHopper;
+import net.minecraft.server.VoxelShape;
+import net.minecraft.server.VoxelShapeCollision;
+import net.minecraft.server.VoxelShapes;
+import net.minecraft.server.World;
+
+public class BlockHopper extends BlockTileEntity {
+ public static final BlockStateDirection FACING = BlockProperties.N;
+ public static final BlockStateBoolean ENABLED = BlockProperties.f;
+ private static final VoxelShape c = Block.a((double) 0.0, (double) 10.0, (double) 0.0, (double) 16.0, (double) 16.0,
+ (double) 16.0);
+ private static final VoxelShape d = Block.a((double) 4.0, (double) 4.0, (double) 4.0, (double) 12.0, (double) 10.0,
+ (double) 12.0);
+ private static final VoxelShape e = VoxelShapes.a((VoxelShape) d, (VoxelShape) c);
+ private static final VoxelShape f = VoxelShapes.a((VoxelShape) e, (VoxelShape) IHopper.a,
+ (OperatorBoolean) OperatorBoolean.ONLY_FIRST);
+ private static final VoxelShape g = VoxelShapes.a((VoxelShape) f,
+ (VoxelShape) Block.a((double) 6.0, (double) 0.0, (double) 6.0, (double) 10.0, (double) 4.0, (double) 10.0));
+ private static final VoxelShape h = VoxelShapes.a((VoxelShape) f, (VoxelShape) Block.a((double) 12.0, (double) 4.0,
+ (double) 6.0, (double) 16.0, (double) 8.0, (double) 10.0));
+ private static final VoxelShape i = VoxelShapes.a((VoxelShape) f,
+ (VoxelShape) Block.a((double) 6.0, (double) 4.0, (double) 0.0, (double) 10.0, (double) 8.0, (double) 4.0));
+ private static final VoxelShape j = VoxelShapes.a((VoxelShape) f, (VoxelShape) Block.a((double) 6.0, (double) 4.0,
+ (double) 12.0, (double) 10.0, (double) 8.0, (double) 16.0));
+ private static final VoxelShape k = VoxelShapes.a((VoxelShape) f,
+ (VoxelShape) Block.a((double) 0.0, (double) 4.0, (double) 6.0, (double) 4.0, (double) 8.0, (double) 10.0));
+ private static final VoxelShape o = IHopper.a;
+ private static final VoxelShape p = VoxelShapes.a((VoxelShape) IHopper.a, (VoxelShape) Block.a((double) 12.0,
+ (double) 8.0, (double) 6.0, (double) 16.0, (double) 10.0, (double) 10.0));
+ private static final VoxelShape q = VoxelShapes.a((VoxelShape) IHopper.a,
+ (VoxelShape) Block.a((double) 6.0, (double) 8.0, (double) 0.0, (double) 10.0, (double) 10.0, (double) 4.0));
+ private static final VoxelShape r = VoxelShapes.a((VoxelShape) IHopper.a, (VoxelShape) Block.a((double) 6.0,
+ (double) 8.0, (double) 12.0, (double) 10.0, (double) 10.0, (double) 16.0));
+ private static final VoxelShape s = VoxelShapes.a((VoxelShape) IHopper.a,
+ (VoxelShape) Block.a((double) 0.0, (double) 8.0, (double) 6.0, (double) 4.0, (double) 10.0, (double) 10.0));
+
+ public BlockHopper(BlockBase.Info var0) {
+ super(var0);
+ this.j((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set((IBlockState) FACING,
+ (Comparable) EnumDirection.DOWN)).set((IBlockState) ENABLED, (Comparable) Boolean.valueOf(true)));
+ }
+
+ public VoxelShape b(IBlockData var0, IBlockAccess var1, BlockPosition var2, VoxelShapeCollision var3) {
+ switch ((EnumDirection) var0.get((IBlockState) FACING)) {
+ case DOWN : {
+ return g;
+ }
+ case NORTH : {
+ return i;
+ }
+ case SOUTH : {
+ return j;
+ }
+ case WEST : {
+ return k;
+ }
+ case EAST : {
+ return h;
+ }
+ }
+ return f;
+ }
+
+ public VoxelShape a_(IBlockData var0, IBlockAccess var1, BlockPosition var2) {
+ switch ((EnumDirection) var0.get((IBlockState) FACING)) {
+ case DOWN : {
+ return o;
+ }
+ case NORTH : {
+ return q;
+ }
+ case SOUTH : {
+ return r;
+ }
+ case WEST : {
+ return s;
+ }
+ case EAST : {
+ return p;
+ }
+ }
+ return IHopper.a;
+ }
+
+ public IBlockData getPlacedState(BlockActionContext var0) {
+ EnumDirection var1;
+ return (IBlockData) ((IBlockData) this.getBlockData().set((IBlockState) FACING,
+ (Comparable) ((var1 = var0.getClickedFace().opposite()).n() == EnumDirection.EnumAxis.Y
+ ? EnumDirection.DOWN
+ : var1))).set((IBlockState) ENABLED, (Comparable) Boolean.valueOf(true));
+ }
+
+ public TileEntity createTile(IBlockAccess var0) {
+ return new TileEntityHopper();
+ }
+
+ public void postPlace(World var0, BlockPosition var1, IBlockData var2, EntityLiving var3, ItemStack var4) {
+ TileEntity var5;
+ if (var4.hasName() && (var5 = var0.getTileEntity(var1)) instanceof TileEntityHopper) {
+ ((TileEntityHopper) var5).setCustomName(var4.getName());
+ }
+ }
+
+ public void onPlace(IBlockData var0, World var1, BlockPosition var2, IBlockData var3, boolean var4) {
+ if (var3.a(var0.getBlock())) {
+ return;
+ }
+ this.a(var1, var2, var0);
+ }
+
+ public EnumInteractionResult interact(IBlockData var0, World var1, BlockPosition var2, EntityHuman var3,
+ EnumHand var4, MovingObjectPositionBlock var5) {
+ if (var1.isClientSide) {
+ return EnumInteractionResult.SUCCESS;
+ }
+ TileEntity var6 = var1.getTileEntity(var2);
+ if (var6 instanceof TileEntityHopper) {
+ var3.openContainer((ITileInventory) ((TileEntityHopper) var6));
+ var3.a(StatisticList.INSPECT_HOPPER);
+ }
+ return EnumInteractionResult.CONSUME;
+ }
+
+ public void doPhysics(IBlockData var0, World var1, BlockPosition var2, Block var3, BlockPosition var4,
+ boolean var5) {
+ this.a(var1, var2, var0);
+ //YAPFA start
+ TileEntity tileEntity = var1.getTileEntity(var2);
+ if (tileEntity instanceof TileEntityHopper) {
+ ((TileEntityHopper)tileEntity).flushCaches();
+ }
+ // YAPFA end
+ }
+
+ private void a(World var0, BlockPosition var1, IBlockData var2) {
+ boolean var3;
+ boolean bl = var3 = !var0.isBlockIndirectlyPowered(var1);
+ if (var3 != (Boolean) var2.get((IBlockState) ENABLED)) {
+ var0.setTypeAndData(var1, (IBlockData) var2.set((IBlockState) ENABLED, (Comparable) Boolean.valueOf(var3)),
+ 4);
+ }
+ }
+
+ public void remove(IBlockData var0, World var1, BlockPosition var2, IBlockData var3, boolean var4) {
+ if (var0.a(var3.getBlock())) {
+ return;
+ }
+ TileEntity var5 = var1.getTileEntity(var2);
+ if (var5 instanceof TileEntityHopper) {
+ InventoryUtils.dropInventory((World) var1, (BlockPosition) var2, (IInventory) ((TileEntityHopper) var5));
+ var1.updateAdjacentComparators(var2, (Block) this);
+ }
+ super.remove(var0, var1, var2, var3, var4);
+ }
+
+ public EnumRenderType b(IBlockData var0) {
+ return EnumRenderType.MODEL;
+ }
+
+ public boolean isComplexRedstone(IBlockData var0) {
+ return true;
+ }
+
+ public int a(IBlockData var0, World var1, BlockPosition var2) {
+ return Container.a((TileEntity) var1.getTileEntity(var2));
+ }
+
+ public IBlockData a(IBlockData var0, EnumBlockRotation var1) {
+ return (IBlockData) var0.set((IBlockState) FACING,
+ (Comparable) var1.a((EnumDirection) var0.get((IBlockState) FACING)));
+ }
+
+ public IBlockData a(IBlockData var0, EnumBlockMirror var1) {
+ return var0.a(var1.a((EnumDirection) var0.get((IBlockState) FACING)));
+ }
+
+ protected void a(BlockStateList.a<Block, IBlockData> var0) {
+ var0.a(new IBlockState[]{FACING, ENABLED});
+ }
+
+ public void a(IBlockData var0, World var1, BlockPosition var2, Entity var3) {
+ TileEntity var4 = var1.getTileEntity(var2);
+ if (var4 instanceof TileEntityHopper) {
+ ((TileEntityHopper) var4).a(var3);
+ }
+ }
+
+ public boolean a(IBlockData var0, IBlockAccess var1, BlockPosition var2, PathMode var3) {
+ return false;
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/net/minecraft/server/TileEntityHopper.java b/src/main/java/net/minecraft/server/TileEntityHopper.java
index 728c829c1..42bd33197 100644
--- a/src/main/java/net/minecraft/server/TileEntityHopper.java
+++ b/src/main/java/net/minecraft/server/TileEntityHopper.java
@@ -2,6 +2,7 @@ package net.minecraft.server;
import java.util.Iterator;
import java.util.List;
+import java.util.Optional;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@@ -611,14 +612,28 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
@Nullable
private IInventory l() {
+ if(this.cachedPush != null)return this.cachedPush;
EnumDirection enumdirection = (EnumDirection) this.getBlock().get(BlockHopper.FACING);
- return b(this.getWorld(), this.position.shift(enumdirection));
+ this.cachedPush = b(this.getWorld(), this.position.shift(enumdirection));
+ return this.cachedPush;
}
@Nullable
public static IInventory b(IHopper ihopper) {
- return a(ihopper.getWorld(), ihopper.x(), ihopper.z() + 1.0D, ihopper.A());
+ //YAPFA start
+ if(ihopper instanceof TileEntityHopper) {
+ TileEntityHopper hopper = (TileEntityHopper) ihopper;
+ if(hopper.cachedAbove != null) {
+ return hopper.cachedAbove;
+ }
+ IInventory inv = a(ihopper.getWorld(), ihopper.x(), ihopper.z() + 1.0D, ihopper.A());
+ hopper.cachedAbove = inv;
+ return inv;
+ } else {
+ return a(ihopper.getWorld(), ihopper.x(), ihopper.z() + 1.0D, ihopper.A());
+ }
+ //YAPFA end
}
public static List<EntityItem> c(IHopper ihopper) {
@@ -658,7 +673,7 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
}
}
}
-
+
if (object == null && (!optimizeEntities || !org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(block).isOccluding())) { // Paper
List<Entity> list = world.getEntities((Entity) null, new AxisAlignedBB(d0 - 0.5D, d1 - 0.5D, d2 - 0.5D, d0 + 0.5D, d1 + 0.5D, d2 + 0.5D), IEntitySelector.d);
@@ -666,7 +681,7 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
object = (IInventory) list.get(world.random.nextInt(list.size()));
}
}
-
+
return (IInventory) object;
}
@@ -728,4 +743,17 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
protected Container createContainer(int i, PlayerInventory playerinventory) {
return new ContainerHopper(i, playerinventory, this);
}
+
+ // YAPFA start
+
+ private IInventory cachedAbove = null;
+ private IInventory cachedPush = null;
+
+ public void flushCaches() {
+ cachedAbove = null;
+ cachedPush = null;
+ }
+
+ // YAPFA end
+
}
--
2.25.1.windows.1