Move some changes to mixins
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
package io.akarin.server.mixin.optimization;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import net.minecraft.server.Block;
|
||||
import net.minecraft.server.BlockChest;
|
||||
import net.minecraft.server.BlockPosition;
|
||||
import net.minecraft.server.EnumDirection;
|
||||
import net.minecraft.server.IBlockData;
|
||||
import net.minecraft.server.Material;
|
||||
import net.minecraft.server.World;
|
||||
|
||||
@Mixin(value = BlockChest.class, remap = false)
|
||||
public abstract class MixinBlockChest extends Block {
|
||||
protected MixinBlockChest(Material material) {
|
||||
super(material);
|
||||
}
|
||||
@Shadow public abstract IBlockData e(World world, BlockPosition blockposition, IBlockData iblockdata);
|
||||
@Overwrite
|
||||
public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata) {
|
||||
//((BlockChest)(Object)this).e(world, blockposition, iblockdata);
|
||||
e(world, blockposition, iblockdata);
|
||||
Iterator<EnumDirection> iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
EnumDirection enumdirection = iterator.next();
|
||||
BlockPosition blockposition1 = blockposition.shift(enumdirection);
|
||||
// NeonPaper start - Dont load chunks for chests
|
||||
final IBlockData iblockdata1 = world.isLoaded(blockposition1) ? world.getType(blockposition1) : null;
|
||||
if (iblockdata1 == null) {
|
||||
continue;
|
||||
}
|
||||
// NeonPaper end
|
||||
|
||||
if (iblockdata1.getBlock() == this) {
|
||||
//((BlockChest)(Object)this).e(world, blockposition1, iblockdata1);
|
||||
e(world, blockposition1, iblockdata1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package io.akarin.server.mixin.optimization;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import net.minecraft.server.Container;
|
||||
import net.minecraft.server.ContainerHorse;
|
||||
import net.minecraft.server.Entity;
|
||||
import net.minecraft.server.EntityHorseAbstract;
|
||||
import net.minecraft.server.EntityHuman;
|
||||
import net.minecraft.server.IInventory;
|
||||
|
||||
@Mixin(value = ContainerHorse.class, remap = false)
|
||||
public abstract class MixinContainerHorse extends Container {
|
||||
@Shadow private IInventory a;
|
||||
@Shadow private EntityHorseAbstract f;
|
||||
|
||||
@Overwrite
|
||||
public boolean canUse(EntityHuman entityhuman) {
|
||||
return this.a.a(entityhuman) && this.f.isAlive() && this.f.valid && this.f.g((Entity) entityhuman) < 8.0F; // NeonPaper! - Fix MC-161754
|
||||
}
|
||||
}
|
||||
@@ -1,21 +1,30 @@
|
||||
package net.minecraft.server;
|
||||
package io.akarin.server.mixin.optimization;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import org.bukkit.event.player.PlayerShearEntityEvent; // CraftBukkit
|
||||
import org.bukkit.event.player.PlayerShearEntityEvent;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
|
||||
public class EntityMushroomCow extends EntityCow {
|
||||
import net.minecraft.server.Blocks;
|
||||
import net.minecraft.server.EntityCow;
|
||||
import net.minecraft.server.EntityHuman;
|
||||
import net.minecraft.server.EntityItem;
|
||||
import net.minecraft.server.EntityMushroomCow;
|
||||
import net.minecraft.server.EnumHand;
|
||||
import net.minecraft.server.EnumParticle;
|
||||
import net.minecraft.server.ItemStack;
|
||||
import net.minecraft.server.Items;
|
||||
import net.minecraft.server.SoundEffects;
|
||||
import net.minecraft.server.World;
|
||||
|
||||
public EntityMushroomCow(World world) {
|
||||
super(world);
|
||||
this.setSize(0.9F, 1.4F);
|
||||
this.bA = Blocks.MYCELIUM;
|
||||
}
|
||||
@Mixin(value = EntityMushroomCow.class, remap = false)
|
||||
public abstract class MixinEntityMushroomCow extends EntityCow {
|
||||
|
||||
public static void c(DataConverterManager dataconvertermanager) {
|
||||
EntityInsentient.a(dataconvertermanager, EntityMushroomCow.class);
|
||||
}
|
||||
public MixinEntityMushroomCow(World world) {
|
||||
super(world);
|
||||
}
|
||||
|
||||
public boolean a(EntityHuman entityhuman, EnumHand enumhand) {
|
||||
@Overwrite
|
||||
public boolean a(EntityHuman entityhuman, EnumHand enumhand) {
|
||||
ItemStack itemstack = entityhuman.b(enumhand);
|
||||
|
||||
if (itemstack.getItem() == Items.BOWL && this.getAge() >= 0 && !entityhuman.abilities.canInstantlyBuild) {
|
||||
@@ -65,20 +74,4 @@ public class EntityMushroomCow extends EntityCow {
|
||||
}
|
||||
}
|
||||
|
||||
public EntityMushroomCow c(EntityAgeable entityageable) {
|
||||
return new EntityMushroomCow(this.world);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected MinecraftKey J() {
|
||||
return LootTables.M;
|
||||
}
|
||||
|
||||
public EntityCow b(EntityAgeable entityageable) {
|
||||
return this.c(entityageable);
|
||||
}
|
||||
|
||||
public EntityAgeable createChild(EntityAgeable entityageable) {
|
||||
return this.c(entityageable);
|
||||
}
|
||||
}
|
||||
@@ -1,58 +1,68 @@
|
||||
package net.minecraft.server;
|
||||
package io.akarin.server.mixin.optimization;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.event.CraftEventFactory;
|
||||
import org.bukkit.event.block.BlockExplodeEvent;
|
||||
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
||||
import net.minecraft.server.AxisAlignedBB;
|
||||
import net.minecraft.server.Block;
|
||||
import net.minecraft.server.BlockPosition;
|
||||
import net.minecraft.server.Blocks;
|
||||
import net.minecraft.server.Chunk;
|
||||
import net.minecraft.server.ChunkSection;
|
||||
import net.minecraft.server.DamageSource;
|
||||
import net.minecraft.server.EnchantmentProtection;
|
||||
import net.minecraft.server.Entity;
|
||||
import net.minecraft.server.EntityFallingBlock;
|
||||
import net.minecraft.server.EntityHuman;
|
||||
import net.minecraft.server.EntityLiving;
|
||||
import net.minecraft.server.EntityTNTPrimed;
|
||||
import net.minecraft.server.EnumParticle;
|
||||
import net.minecraft.server.Explosion;
|
||||
import net.minecraft.server.IBlockData;
|
||||
import net.minecraft.server.Material;
|
||||
import net.minecraft.server.MathHelper;
|
||||
import net.minecraft.server.SoundCategory;
|
||||
import net.minecraft.server.SoundEffects;
|
||||
import net.minecraft.server.Vec3D;
|
||||
import net.minecraft.server.World;
|
||||
import net.minecraft.server.IEntitySelector;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
// CraftBukkit start
|
||||
import org.bukkit.craftbukkit.event.CraftEventFactory;
|
||||
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.event.block.BlockExplodeEvent;
|
||||
// CraftBukkit end
|
||||
|
||||
public class Explosion {
|
||||
|
||||
private final boolean a;
|
||||
private final boolean b;
|
||||
private final Random c = new Random();
|
||||
private final World world;
|
||||
private final double posX;
|
||||
private final double posY;
|
||||
private final double posZ;
|
||||
public final Entity source;
|
||||
private final float size;
|
||||
private final ArrayList<BlockPosition> blocks = Lists.newArrayList();
|
||||
private final Map<EntityHuman, Vec3D> k = Maps.newHashMap();
|
||||
public boolean wasCanceled = false; // CraftBukkit - add field
|
||||
|
||||
// Dionysus start
|
||||
@Mixin(value = Explosion.class, remap = false)
|
||||
public abstract class MixinExplosion {
|
||||
@Shadow private boolean a;
|
||||
@Shadow private boolean b;
|
||||
@Shadow private Random c = new Random();
|
||||
@Shadow private World world;
|
||||
@Shadow private double posX;
|
||||
@Shadow private double posY;
|
||||
@Shadow private double posZ;
|
||||
@Shadow public Entity source;
|
||||
@Shadow private float size;
|
||||
@Shadow private Map<EntityHuman, Vec3D> k;
|
||||
@Shadow public boolean wasCanceled = false; // CraftBukkit - add field
|
||||
@Shadow private List<BlockPosition> blocks;
|
||||
private final BlockPosition.MutableBlockPosition cachedPos = new BlockPosition.MutableBlockPosition();
|
||||
// The chunk coordinate of the most recently stepped through block.
|
||||
private int prevChunkX = Integer.MIN_VALUE;
|
||||
private int prevChunkZ = Integer.MIN_VALUE;
|
||||
|
||||
// The chunk belonging to prevChunkPos.
|
||||
private Chunk prevChunk;
|
||||
|
||||
private static final com.google.common.base.Predicate<Entity> hitPredicate = entity -> IEntitySelector.d.apply(entity) && !entity.dead; // Dionysus - Paper - don't hit dead entities
|
||||
// Dionysus end
|
||||
|
||||
public Explosion(World world, Entity entity, double d0, double d1, double d2, float f, boolean flag, boolean flag1) {
|
||||
this.world = world;
|
||||
this.source = entity;
|
||||
this.size = (float) Math.max(f, 0.0); // CraftBukkit - clamp bad values
|
||||
this.posX = d0;
|
||||
this.posY = d1;
|
||||
this.posZ = d2;
|
||||
this.a = flag;
|
||||
this.b = flag1;
|
||||
}
|
||||
|
||||
@Overwrite
|
||||
public void a() {
|
||||
// CraftBukkit start
|
||||
if (this.size < 0.1F) {
|
||||
@@ -94,9 +104,9 @@ public class Explosion {
|
||||
// We can now iterate back over the set of positions we modified and re-build BlockPos objects from them
|
||||
// This will only allocate as many objects as there are in the set, where otherwise we would allocate them
|
||||
// each step of a every ray.
|
||||
blocks.ensureCapacity(touched.size());
|
||||
((ArrayList<BlockPosition>)this.blocks).ensureCapacity(touched.size());
|
||||
for (Long longPos : touched) {
|
||||
blocks.add(BlockPosition.fromLong(longPos));
|
||||
this.blocks.add(BlockPosition.fromLong(longPos));
|
||||
}
|
||||
float f3 = this.size * 2.0F;
|
||||
|
||||
@@ -133,7 +143,7 @@ public class Explosion {
|
||||
// entity.damageEntity(DamageSource.explosion(this), (float) ((int) ((d13 * d13 + d13) / 2.0D * 7.0D * (double) f3 + 1.0D)));
|
||||
CraftEventFactory.entityDamage = source;
|
||||
entity.forceExplosionKnockback = false;
|
||||
boolean wasDamaged = entity.damageEntity(DamageSource.explosion(this), (float) ((int) ((d13 * d13 + d13) / 2.0D * 7.0D * (double) f3 + 1.0D)));
|
||||
boolean wasDamaged = entity.damageEntity(DamageSource.explosion((Explosion)(Object)this), (float) ((int) ((d13 * d13 + d13) / 2.0D * 7.0D * (double) f3 + 1.0D)));
|
||||
CraftEventFactory.entityDamage = null;
|
||||
if (!wasDamaged && !(entity instanceof EntityTNTPrimed || entity instanceof EntityFallingBlock) && !entity.forceExplosionKnockback) {
|
||||
continue;
|
||||
@@ -161,7 +171,6 @@ public class Explosion {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void performRayCast(Random random, double vecX, double vecY, double vecZ, LongOpenHashSet touched) {
|
||||
double dist = Math.sqrt((vecX * vecX) + (vecY * vecY) + (vecZ * vecZ));
|
||||
|
||||
@@ -214,7 +223,6 @@ public class Explosion {
|
||||
stepZ += normZ;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called for every step made by a ray being cast by an explosion.
|
||||
*
|
||||
@@ -231,7 +239,7 @@ public class Explosion {
|
||||
// Early-exit if the y-coordinate is out of bounds.
|
||||
if (cachedPos.isInvalidYLocation()) {
|
||||
if (iblockdata.getMaterial() != Material.AIR) {
|
||||
float blastResistance = this.source != null ? this.source.a(this, this.world, cachedPos, iblockdata) : iblockdata.getBlock().a((Entity) null);
|
||||
float blastResistance = this.source != null ? this.source.a((Explosion)(Object)this, this.world, cachedPos, iblockdata) : iblockdata.getBlock().a((Entity) null);
|
||||
return (blastResistance + 0.3F) * 0.3F;
|
||||
}
|
||||
return 0.0F;
|
||||
@@ -268,7 +276,7 @@ public class Explosion {
|
||||
// If the block state is air, it cannot have fluid or any kind of resistance, so just leave
|
||||
if (blockState.getBlock() != Blocks.AIR) {
|
||||
// Get the explosion resistance like vanilla
|
||||
blastResistance = Optional.of(this.source != null ? this.source.a(this, this.world, cachedPos, iblockdata) : iblockdata.getBlock().a((Entity) null));
|
||||
blastResistance = Optional.of(this.source != null ? this.source.a((Explosion)(Object)this, this.world, cachedPos, iblockdata) : iblockdata.getBlock().a((Entity) null));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -282,16 +290,14 @@ public class Explosion {
|
||||
// of positions to destroy
|
||||
float reducedStrength = strength - totalResistance;
|
||||
if (reducedStrength > 0.0F && (this.a || iblockdata.getMaterial() != Material.AIR)) {
|
||||
if ((this.source == null || this.source.a(this, this.world, cachedPos, iblockdata, reducedStrength)) && cachedPos.getY() < 256 && cachedPos.getY() >= 0) {
|
||||
if ((this.source == null || this.source.a((Explosion)(Object)this, this.world, cachedPos, iblockdata, reducedStrength)) && cachedPos.getY() < 256 && cachedPos.getY() >= 0) {
|
||||
touched.add(cachedPos.asLong());
|
||||
}
|
||||
}
|
||||
|
||||
return totalResistance;
|
||||
}
|
||||
// Dionysus end
|
||||
|
||||
|
||||
@Overwrite
|
||||
public void a(boolean flag) {
|
||||
this.world.a((EntityHuman) null, this.posX, this.posY, this.posZ, SoundEffects.bV, SoundCategory.BLOCKS, 4.0F, (1.0F + (this.world.random.nextFloat() - this.world.random.nextFloat()) * 0.2F) * 0.7F);
|
||||
if (this.size >= 2.0F && this.b) {
|
||||
@@ -300,7 +306,7 @@ public class Explosion {
|
||||
this.world.addParticle(EnumParticle.EXPLOSION_LARGE, this.posX, this.posY, this.posZ, 1.0D, 0.0D, 0.0D);
|
||||
}
|
||||
|
||||
Iterator iterator;
|
||||
Iterator<BlockPosition> iterator;
|
||||
BlockPosition blockposition;
|
||||
|
||||
if (this.b) {
|
||||
@@ -338,7 +344,7 @@ public class Explosion {
|
||||
|
||||
this.blocks.clear();
|
||||
|
||||
this.blocks.ensureCapacity(bukkitBlocks.size());
|
||||
((ArrayList<BlockPosition>)this.blocks).ensureCapacity(bukkitBlocks.size());
|
||||
for (org.bukkit.block.Block bblock : bukkitBlocks) {
|
||||
BlockPosition coords = new BlockPosition(bblock.getX(), bblock.getY(), bblock.getZ());
|
||||
blocks.add(coords);
|
||||
@@ -380,13 +386,13 @@ public class Explosion {
|
||||
}
|
||||
|
||||
if (iblockdata.getMaterial() != Material.AIR) {
|
||||
if (block.a(this)) {
|
||||
if (block.a((Explosion)(Object)this)) {
|
||||
// CraftBukkit - add yield
|
||||
block.dropNaturally(this.world, blockposition, this.world.getType(blockposition), yield, 0);
|
||||
}
|
||||
|
||||
this.world.setTypeAndData(blockposition, Blocks.AIR.getBlockData(), 3);
|
||||
block.wasExploded(this.world, blockposition, this);
|
||||
block.wasExploded(this.world, blockposition, (Explosion)(Object)this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -398,7 +404,7 @@ public class Explosion {
|
||||
blockposition = (BlockPosition) iterator.next();
|
||||
if (this.world.getType(blockposition).getMaterial() == Material.AIR && this.world.getType(blockposition.down()).b() && this.c.nextInt(3) == 0) {
|
||||
// CraftBukkit start - Ignition by explosion
|
||||
if (!CraftEventFactory.callBlockIgniteEvent(this.world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this).isCancelled()) {
|
||||
if (!CraftEventFactory.callBlockIgniteEvent(this.world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), (Explosion)(Object)this).isCancelled()) {
|
||||
this.world.setTypeUpdate(blockposition, Blocks.FIRE.getBlockData());
|
||||
}
|
||||
// CraftBukkit end
|
||||
@@ -407,98 +413,14 @@ public class Explosion {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Map<EntityHuman, Vec3D> b() {
|
||||
return this.k;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public EntityLiving getSource() {
|
||||
// CraftBukkit start - obtain Fireball shooter for explosion tracking
|
||||
return this.source == null ? null : (this.source instanceof EntityTNTPrimed ? ((EntityTNTPrimed) this.source).getSource() : (this.source instanceof EntityLiving ? (EntityLiving) this.source : (this.source instanceof EntityFireball ? ((EntityFireball) this.source).shooter : null)));
|
||||
// CraftBukkit end
|
||||
}
|
||||
|
||||
public void clearBlocks() {
|
||||
this.blocks.clear();
|
||||
}
|
||||
|
||||
public List<BlockPosition> getBlocks() {
|
||||
return this.blocks;
|
||||
}
|
||||
|
||||
// Paper start - Optimize explosions
|
||||
private float getBlockDensity(Vec3D vec3d, AxisAlignedBB aabb) {
|
||||
if (!this.world.paperConfig.optimizeExplosions) {
|
||||
return this.world.a(vec3d, aabb);
|
||||
}
|
||||
CacheKey key = new CacheKey(this, aabb);
|
||||
return this.world.explosionDensityCache.computeIfAbsent(key, k1 -> this.world.a(vec3d, aabb));
|
||||
}
|
||||
|
||||
static class CacheKey {
|
||||
private final World world;
|
||||
private final double posX, posY, posZ;
|
||||
private final double minX, minY, minZ;
|
||||
private final double maxX, maxY, maxZ;
|
||||
|
||||
public CacheKey(Explosion explosion, AxisAlignedBB aabb) {
|
||||
this.world = explosion.world;
|
||||
this.posX = explosion.posX;
|
||||
this.posY = explosion.posY;
|
||||
this.posZ = explosion.posZ;
|
||||
this.minX = aabb.a;
|
||||
this.minY = aabb.b;
|
||||
this.minZ = aabb.c;
|
||||
this.maxX = aabb.d;
|
||||
this.maxY = aabb.e;
|
||||
this.maxZ = aabb.f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
CacheKey cacheKey = (CacheKey) o;
|
||||
|
||||
if (Double.compare(cacheKey.posX, posX) != 0) return false;
|
||||
if (Double.compare(cacheKey.posY, posY) != 0) return false;
|
||||
if (Double.compare(cacheKey.posZ, posZ) != 0) return false;
|
||||
if (Double.compare(cacheKey.minX, minX) != 0) return false;
|
||||
if (Double.compare(cacheKey.minY, minY) != 0) return false;
|
||||
if (Double.compare(cacheKey.minZ, minZ) != 0) return false;
|
||||
if (Double.compare(cacheKey.maxX, maxX) != 0) return false;
|
||||
if (Double.compare(cacheKey.maxY, maxY) != 0) return false;
|
||||
if (Double.compare(cacheKey.maxZ, maxZ) != 0) return false;
|
||||
return world.equals(cacheKey.world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result;
|
||||
long temp;
|
||||
result = world.hashCode();
|
||||
temp = Double.doubleToLongBits(posX);
|
||||
result = 31 * result + (int) (temp ^ (temp >>> 32));
|
||||
temp = Double.doubleToLongBits(posY);
|
||||
result = 31 * result + (int) (temp ^ (temp >>> 32));
|
||||
temp = Double.doubleToLongBits(posZ);
|
||||
result = 31 * result + (int) (temp ^ (temp >>> 32));
|
||||
temp = Double.doubleToLongBits(minX);
|
||||
result = 31 * result + (int) (temp ^ (temp >>> 32));
|
||||
temp = Double.doubleToLongBits(minY);
|
||||
result = 31 * result + (int) (temp ^ (temp >>> 32));
|
||||
temp = Double.doubleToLongBits(minZ);
|
||||
result = 31 * result + (int) (temp ^ (temp >>> 32));
|
||||
temp = Double.doubleToLongBits(maxX);
|
||||
result = 31 * result + (int) (temp ^ (temp >>> 32));
|
||||
temp = Double.doubleToLongBits(maxY);
|
||||
result = 31 * result + (int) (temp ^ (temp >>> 32));
|
||||
temp = Double.doubleToLongBits(maxZ);
|
||||
result = 31 * result + (int) (temp ^ (temp >>> 32));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@Shadow protected abstract float getBlockDensity(Vec3D vec3d, AxisAlignedBB aabb);
|
||||
//private float getBlockDensity(Vec3D vec3d, AxisAlignedBB aabb) {
|
||||
//if (!this.world.paperConfig.optimizeExplosions) {
|
||||
// return this.world.a(vec3d, aabb);
|
||||
//}
|
||||
//CacheKey key = new CacheKey((Explosion)(Object)this, aabb);
|
||||
//return this.world.explosionDensityCache.computeIfAbsent(key, k1 -> this.world.a(vec3d, aabb));
|
||||
//}
|
||||
// Paper end
|
||||
// Dionysus end
|
||||
}
|
||||
@@ -1,479 +0,0 @@
|
||||
package net.minecraft.server;
|
||||
|
||||
import java.util.Iterator;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class BlockChest extends BlockTileEntity {
|
||||
|
||||
public static final BlockStateDirection FACING = BlockFacingHorizontal.FACING;
|
||||
protected static final AxisAlignedBB b = new AxisAlignedBB(0.0625D, 0.0D, 0.0D, 0.9375D, 0.875D, 0.9375D);
|
||||
protected static final AxisAlignedBB c = new AxisAlignedBB(0.0625D, 0.0D, 0.0625D, 0.9375D, 0.875D, 1.0D);
|
||||
protected static final AxisAlignedBB d = new AxisAlignedBB(0.0D, 0.0D, 0.0625D, 0.9375D, 0.875D, 0.9375D);
|
||||
protected static final AxisAlignedBB e = new AxisAlignedBB(0.0625D, 0.0D, 0.0625D, 1.0D, 0.875D, 0.9375D);
|
||||
protected static final AxisAlignedBB f = new AxisAlignedBB(0.0625D, 0.0D, 0.0625D, 0.9375D, 0.875D, 0.9375D);
|
||||
public final BlockChest.Type g;
|
||||
|
||||
protected BlockChest(BlockChest.Type blockchest_type) {
|
||||
super(Material.WOOD);
|
||||
this.w(this.blockStateList.getBlockData().set(BlockChest.FACING, EnumDirection.NORTH));
|
||||
this.g = blockchest_type;
|
||||
this.a(blockchest_type == BlockChest.Type.TRAP ? CreativeModeTab.d : CreativeModeTab.c);
|
||||
}
|
||||
|
||||
public boolean b(IBlockData iblockdata) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean c(IBlockData iblockdata) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public EnumRenderType a(IBlockData iblockdata) {
|
||||
return EnumRenderType.ENTITYBLOCK_ANIMATED;
|
||||
}
|
||||
|
||||
public AxisAlignedBB b(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) {
|
||||
return iblockaccess.getType(blockposition.north()).getBlock() == this ? BlockChest.b : (iblockaccess.getType(blockposition.south()).getBlock() == this ? BlockChest.c : (iblockaccess.getType(blockposition.west()).getBlock() == this ? BlockChest.d : (iblockaccess.getType(blockposition.east()).getBlock() == this ? BlockChest.e : BlockChest.f)));
|
||||
}
|
||||
|
||||
public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata) {
|
||||
this.e(world, blockposition, iblockdata);
|
||||
Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
EnumDirection enumdirection = (EnumDirection) iterator.next();
|
||||
BlockPosition blockposition1 = blockposition.shift(enumdirection);
|
||||
// NeonPaper start - Dont load chunks for chests
|
||||
final IBlockData iblockdata1 = world.isLoaded(blockposition1) ? world.getType(blockposition1) : null;
|
||||
if (iblockdata1 == null) {
|
||||
continue;
|
||||
}
|
||||
// NeonPaper end
|
||||
|
||||
if (iblockdata1.getBlock() == this) {
|
||||
this.e(world, blockposition1, iblockdata1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public IBlockData getPlacedState(World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2, int i, EntityLiving entityliving) {
|
||||
return this.getBlockData().set(BlockChest.FACING, entityliving.getDirection());
|
||||
}
|
||||
|
||||
public void postPlace(World world, BlockPosition blockposition, IBlockData iblockdata, EntityLiving entityliving, ItemStack itemstack) {
|
||||
EnumDirection enumdirection = EnumDirection.fromType2(MathHelper.floor((double) (entityliving.yaw * 4.0F / 360.0F) + 0.5D) & 3).opposite();
|
||||
|
||||
iblockdata = iblockdata.set(BlockChest.FACING, enumdirection);
|
||||
BlockPosition blockposition1 = blockposition.north();
|
||||
BlockPosition blockposition2 = blockposition.south();
|
||||
BlockPosition blockposition3 = blockposition.west();
|
||||
BlockPosition blockposition4 = blockposition.east();
|
||||
boolean flag = this == world.getType(blockposition1).getBlock();
|
||||
boolean flag1 = this == world.getType(blockposition2).getBlock();
|
||||
boolean flag2 = this == world.getType(blockposition3).getBlock();
|
||||
boolean flag3 = this == world.getType(blockposition4).getBlock();
|
||||
|
||||
if (!flag && !flag1 && !flag2 && !flag3) {
|
||||
world.setTypeAndData(blockposition, iblockdata, 3);
|
||||
} else if (enumdirection.k() == EnumDirection.EnumAxis.X && (flag || flag1)) {
|
||||
if (flag) {
|
||||
world.setTypeAndData(blockposition1, iblockdata, 3);
|
||||
} else {
|
||||
world.setTypeAndData(blockposition2, iblockdata, 3);
|
||||
}
|
||||
|
||||
world.setTypeAndData(blockposition, iblockdata, 3);
|
||||
} else if (enumdirection.k() == EnumDirection.EnumAxis.Z && (flag2 || flag3)) {
|
||||
if (flag2) {
|
||||
world.setTypeAndData(blockposition3, iblockdata, 3);
|
||||
} else {
|
||||
world.setTypeAndData(blockposition4, iblockdata, 3);
|
||||
}
|
||||
|
||||
world.setTypeAndData(blockposition, iblockdata, 3);
|
||||
}
|
||||
|
||||
if (itemstack.hasName()) {
|
||||
TileEntity tileentity = world.getTileEntity(blockposition);
|
||||
|
||||
if (tileentity instanceof TileEntityChest) {
|
||||
((TileEntityChest) tileentity).setCustomName(itemstack.getName());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public IBlockData e(World world, BlockPosition blockposition, IBlockData iblockdata) {
|
||||
if (world.isClientSide) {
|
||||
return iblockdata;
|
||||
} else {
|
||||
IBlockData iblockdata1 = world.getType(blockposition.north());
|
||||
IBlockData iblockdata2 = world.getType(blockposition.south());
|
||||
IBlockData iblockdata3 = world.getType(blockposition.west());
|
||||
IBlockData iblockdata4 = world.getType(blockposition.east());
|
||||
EnumDirection enumdirection = (EnumDirection) iblockdata.get(BlockChest.FACING);
|
||||
|
||||
if (iblockdata1.getBlock() != this && iblockdata2.getBlock() != this) {
|
||||
boolean flag = iblockdata1.b();
|
||||
boolean flag1 = iblockdata2.b();
|
||||
|
||||
if (iblockdata3.getBlock() == this || iblockdata4.getBlock() == this) {
|
||||
BlockPosition blockposition1 = iblockdata3.getBlock() == this ? blockposition.west() : blockposition.east();
|
||||
IBlockData iblockdata5 = world.getType(blockposition1.north());
|
||||
IBlockData iblockdata6 = world.getType(blockposition1.south());
|
||||
|
||||
enumdirection = EnumDirection.SOUTH;
|
||||
EnumDirection enumdirection1;
|
||||
|
||||
if (iblockdata3.getBlock() == this) {
|
||||
enumdirection1 = (EnumDirection) iblockdata3.get(BlockChest.FACING);
|
||||
} else {
|
||||
enumdirection1 = (EnumDirection) iblockdata4.get(BlockChest.FACING);
|
||||
}
|
||||
|
||||
if (enumdirection1 == EnumDirection.NORTH) {
|
||||
enumdirection = EnumDirection.NORTH;
|
||||
}
|
||||
|
||||
if ((flag || iblockdata5.b()) && !flag1 && !iblockdata6.b()) {
|
||||
enumdirection = EnumDirection.SOUTH;
|
||||
}
|
||||
|
||||
if ((flag1 || iblockdata6.b()) && !flag && !iblockdata5.b()) {
|
||||
enumdirection = EnumDirection.NORTH;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
BlockPosition blockposition2 = iblockdata1.getBlock() == this ? blockposition.north() : blockposition.south();
|
||||
IBlockData iblockdata7 = world.getType(blockposition2.west());
|
||||
IBlockData iblockdata8 = world.getType(blockposition2.east());
|
||||
|
||||
enumdirection = EnumDirection.EAST;
|
||||
EnumDirection enumdirection2;
|
||||
|
||||
if (iblockdata1.getBlock() == this) {
|
||||
enumdirection2 = (EnumDirection) iblockdata1.get(BlockChest.FACING);
|
||||
} else {
|
||||
enumdirection2 = (EnumDirection) iblockdata2.get(BlockChest.FACING);
|
||||
}
|
||||
|
||||
if (enumdirection2 == EnumDirection.WEST) {
|
||||
enumdirection = EnumDirection.WEST;
|
||||
}
|
||||
|
||||
if ((iblockdata3.b() || iblockdata7.b()) && !iblockdata4.b() && !iblockdata8.b()) {
|
||||
enumdirection = EnumDirection.EAST;
|
||||
}
|
||||
|
||||
if ((iblockdata4.b() || iblockdata8.b()) && !iblockdata3.b() && !iblockdata7.b()) {
|
||||
enumdirection = EnumDirection.WEST;
|
||||
}
|
||||
}
|
||||
|
||||
iblockdata = iblockdata.set(BlockChest.FACING, enumdirection);
|
||||
world.setTypeAndData(blockposition, iblockdata, 3);
|
||||
return iblockdata;
|
||||
}
|
||||
}
|
||||
|
||||
public IBlockData f(World world, BlockPosition blockposition, IBlockData iblockdata) {
|
||||
EnumDirection enumdirection = null;
|
||||
Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
EnumDirection enumdirection1 = (EnumDirection) iterator.next();
|
||||
IBlockData iblockdata1 = world.getType(blockposition.shift(enumdirection1));
|
||||
|
||||
if (iblockdata1.getBlock() == this) {
|
||||
return iblockdata;
|
||||
}
|
||||
|
||||
if (iblockdata1.b()) {
|
||||
if (enumdirection != null) {
|
||||
enumdirection = null;
|
||||
break;
|
||||
}
|
||||
|
||||
enumdirection = enumdirection1;
|
||||
}
|
||||
}
|
||||
|
||||
if (enumdirection != null) {
|
||||
return iblockdata.set(BlockChest.FACING, enumdirection.opposite());
|
||||
} else {
|
||||
EnumDirection enumdirection2 = (EnumDirection) iblockdata.get(BlockChest.FACING);
|
||||
|
||||
if (world.getType(blockposition.shift(enumdirection2)).b()) {
|
||||
enumdirection2 = enumdirection2.opposite();
|
||||
}
|
||||
|
||||
if (world.getType(blockposition.shift(enumdirection2)).b()) {
|
||||
enumdirection2 = enumdirection2.e();
|
||||
}
|
||||
|
||||
if (world.getType(blockposition.shift(enumdirection2)).b()) {
|
||||
enumdirection2 = enumdirection2.opposite();
|
||||
}
|
||||
|
||||
return iblockdata.set(BlockChest.FACING, enumdirection2);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canPlace(World world, BlockPosition blockposition) {
|
||||
int i = 0;
|
||||
BlockPosition blockposition1 = blockposition.west();
|
||||
BlockPosition blockposition2 = blockposition.east();
|
||||
BlockPosition blockposition3 = blockposition.north();
|
||||
BlockPosition blockposition4 = blockposition.south();
|
||||
|
||||
if (world.getType(blockposition1).getBlock() == this) {
|
||||
if (this.d(world, blockposition1)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
if (world.getType(blockposition2).getBlock() == this) {
|
||||
if (this.d(world, blockposition2)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
if (world.getType(blockposition3).getBlock() == this) {
|
||||
if (this.d(world, blockposition3)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
if (world.getType(blockposition4).getBlock() == this) {
|
||||
if (this.d(world, blockposition4)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
return i <= 1;
|
||||
}
|
||||
|
||||
private boolean d(World world, BlockPosition blockposition) {
|
||||
if (world.getType(blockposition).getBlock() != this) {
|
||||
return false;
|
||||
} else {
|
||||
Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator();
|
||||
|
||||
EnumDirection enumdirection;
|
||||
|
||||
do {
|
||||
if (!iterator.hasNext()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
enumdirection = (EnumDirection) iterator.next();
|
||||
} while (world.getType(blockposition.shift(enumdirection)).getBlock() != this);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1) {
|
||||
super.a(iblockdata, world, blockposition, block, blockposition1);
|
||||
TileEntity tileentity = world.getTileEntity(blockposition);
|
||||
|
||||
if (tileentity instanceof TileEntityChest) {
|
||||
tileentity.invalidateBlockCache();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void remove(World world, BlockPosition blockposition, IBlockData iblockdata) {
|
||||
TileEntity tileentity = world.getTileEntity(blockposition);
|
||||
|
||||
if (tileentity instanceof IInventory) {
|
||||
InventoryUtils.dropInventory(world, blockposition, (IInventory) tileentity);
|
||||
world.updateAdjacentComparators(blockposition, this);
|
||||
}
|
||||
|
||||
super.remove(world, blockposition, iblockdata);
|
||||
}
|
||||
|
||||
public boolean interact(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman, EnumHand enumhand, EnumDirection enumdirection, float f, float f1, float f2) {
|
||||
if (world.isClientSide) {
|
||||
return true;
|
||||
} else {
|
||||
ITileInventory itileinventory = this.getInventory(world, blockposition);
|
||||
|
||||
if (itileinventory != null) {
|
||||
entityhuman.openContainer(itileinventory);
|
||||
if (this.g == BlockChest.Type.BASIC) {
|
||||
entityhuman.b(StatisticList.aa);
|
||||
} else if (this.g == BlockChest.Type.TRAP) {
|
||||
entityhuman.b(StatisticList.U);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ITileInventory getInventory(World world, BlockPosition blockposition) {
|
||||
return this.a(world, blockposition, false);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ITileInventory a(World world, BlockPosition blockposition, boolean flag) {
|
||||
TileEntity tileentity = world.getTileEntity(blockposition);
|
||||
|
||||
if (!(tileentity instanceof TileEntityChest)) {
|
||||
return null;
|
||||
} else {
|
||||
Object object = (TileEntityChest) tileentity;
|
||||
|
||||
if (!flag && this.e(world, blockposition)) {
|
||||
return null;
|
||||
} else {
|
||||
Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
EnumDirection enumdirection = (EnumDirection) iterator.next();
|
||||
BlockPosition blockposition1 = blockposition.shift(enumdirection);
|
||||
// Paper start - don't load chunks if the other side of the chest is in unloaded chunk
|
||||
final IBlockData type = world.getTypeIfLoaded(blockposition1); // Paper
|
||||
if (type == null) {
|
||||
continue;
|
||||
}
|
||||
Block block = type.getBlock();
|
||||
// Paper end
|
||||
|
||||
if (block == this) {
|
||||
if (!flag && this.e(world, blockposition1)) { // Paper - check for allowBlocked flag - MC-99321
|
||||
return null;
|
||||
}
|
||||
|
||||
TileEntity tileentity1 = world.getTileEntity(blockposition1);
|
||||
|
||||
if (tileentity1 instanceof TileEntityChest) {
|
||||
if (enumdirection != EnumDirection.WEST && enumdirection != EnumDirection.NORTH) {
|
||||
object = new InventoryLargeChest("container.chestDouble", (ITileInventory) object, (TileEntityChest) tileentity1);
|
||||
} else {
|
||||
object = new InventoryLargeChest("container.chestDouble", (TileEntityChest) tileentity1, (ITileInventory) object);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (ITileInventory) object;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public TileEntity a(World world, int i) {
|
||||
return new TileEntityChest();
|
||||
}
|
||||
|
||||
public boolean isPowerSource(IBlockData iblockdata) {
|
||||
return this.g == BlockChest.Type.TRAP;
|
||||
}
|
||||
|
||||
public int b(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) {
|
||||
if (!iblockdata.m()) {
|
||||
return 0;
|
||||
} else {
|
||||
int i = 0;
|
||||
TileEntity tileentity = iblockaccess.getTileEntity(blockposition);
|
||||
|
||||
if (tileentity instanceof TileEntityChest) {
|
||||
i = ((TileEntityChest) tileentity).l;
|
||||
}
|
||||
|
||||
return MathHelper.clamp(i, 0, 15);
|
||||
}
|
||||
}
|
||||
|
||||
public int c(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) {
|
||||
return enumdirection == EnumDirection.UP ? iblockdata.a(iblockaccess, blockposition, enumdirection) : 0;
|
||||
}
|
||||
|
||||
private boolean e(World world, BlockPosition blockposition) {
|
||||
return this.i(world, blockposition) || this.j(world, blockposition);
|
||||
}
|
||||
|
||||
private boolean i(World world, BlockPosition blockposition) {
|
||||
return world.getType(blockposition.up()).l();
|
||||
}
|
||||
|
||||
private boolean j(World world, BlockPosition blockposition) {
|
||||
// Paper start - Option ti dsiable chest cat detection
|
||||
if (world.paperConfig.disableChestCatDetection) {
|
||||
return false;
|
||||
}
|
||||
// Paper end
|
||||
Iterator iterator = world.a(EntityOcelot.class, new AxisAlignedBB((double) blockposition.getX(), (double) (blockposition.getY() + 1), (double) blockposition.getZ(), (double) (blockposition.getX() + 1), (double) (blockposition.getY() + 2), (double) (blockposition.getZ() + 1))).iterator();
|
||||
|
||||
EntityOcelot entityocelot;
|
||||
|
||||
do {
|
||||
if (!iterator.hasNext()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Entity entity = (Entity) iterator.next();
|
||||
|
||||
entityocelot = (EntityOcelot) entity;
|
||||
} while (!entityocelot.isSitting());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isComplexRedstone(IBlockData iblockdata) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int c(IBlockData iblockdata, World world, BlockPosition blockposition) {
|
||||
return Container.b((IInventory) this.getInventory(world, blockposition));
|
||||
}
|
||||
|
||||
public IBlockData fromLegacyData(int i) {
|
||||
EnumDirection enumdirection = EnumDirection.fromType1(i);
|
||||
|
||||
if (enumdirection.k() == EnumDirection.EnumAxis.Y) {
|
||||
enumdirection = EnumDirection.NORTH;
|
||||
}
|
||||
|
||||
return this.getBlockData().set(BlockChest.FACING, enumdirection);
|
||||
}
|
||||
|
||||
public int toLegacyData(IBlockData iblockdata) {
|
||||
return ((EnumDirection) iblockdata.get(BlockChest.FACING)).a();
|
||||
}
|
||||
|
||||
public IBlockData a(IBlockData iblockdata, EnumBlockRotation enumblockrotation) {
|
||||
return iblockdata.set(BlockChest.FACING, enumblockrotation.a((EnumDirection) iblockdata.get(BlockChest.FACING)));
|
||||
}
|
||||
|
||||
public IBlockData a(IBlockData iblockdata, EnumBlockMirror enumblockmirror) {
|
||||
return iblockdata.a(enumblockmirror.a((EnumDirection) iblockdata.get(BlockChest.FACING)));
|
||||
}
|
||||
|
||||
protected BlockStateList getStateList() {
|
||||
return new BlockStateList(this, new IBlockState[] { BlockChest.FACING});
|
||||
}
|
||||
|
||||
public EnumBlockFaceShape a(IBlockAccess iblockaccess, IBlockData iblockdata, BlockPosition blockposition, EnumDirection enumdirection) {
|
||||
return EnumBlockFaceShape.UNDEFINED;
|
||||
}
|
||||
|
||||
public static enum Type {
|
||||
|
||||
BASIC, TRAP;
|
||||
|
||||
private Type() {}
|
||||
}
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
package net.minecraft.server;
|
||||
|
||||
// CraftBukkit start
|
||||
import org.bukkit.craftbukkit.inventory.CraftInventoryView;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
// CraftBukkit end
|
||||
|
||||
public class ContainerHorse extends Container {
|
||||
|
||||
private final IInventory a;
|
||||
private final EntityHorseAbstract f;
|
||||
|
||||
// CraftBukkit start
|
||||
org.bukkit.craftbukkit.inventory.CraftInventoryView bukkitEntity;
|
||||
PlayerInventory player;
|
||||
|
||||
@Override
|
||||
public InventoryView getBukkitView() {
|
||||
if (bukkitEntity != null) {
|
||||
return bukkitEntity;
|
||||
}
|
||||
|
||||
return bukkitEntity = new CraftInventoryView(player.player.getBukkitEntity(), a.getOwner().getInventory(), this);
|
||||
}
|
||||
|
||||
public ContainerHorse(IInventory iinventory, final IInventory iinventory1, final EntityHorseAbstract entityhorseabstract, EntityHuman entityhuman) {
|
||||
player = (PlayerInventory) iinventory;
|
||||
// CraftBukkit end
|
||||
this.a = iinventory1;
|
||||
this.f = entityhorseabstract;
|
||||
boolean flag = true;
|
||||
|
||||
iinventory1.startOpen(entityhuman);
|
||||
boolean flag1 = true;
|
||||
|
||||
this.a(new Slot(iinventory1, 0, 8, 18) {
|
||||
public boolean isAllowed(ItemStack itemstack) {
|
||||
return itemstack.getItem() == Items.SADDLE && !this.hasItem() && entityhorseabstract.dF();
|
||||
}
|
||||
});
|
||||
this.a(new Slot(iinventory1, 1, 8, 36) {
|
||||
public boolean isAllowed(ItemStack itemstack) {
|
||||
return entityhorseabstract.f(itemstack);
|
||||
}
|
||||
|
||||
public int getMaxStackSize() {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
int i;
|
||||
int j;
|
||||
|
||||
if (entityhorseabstract instanceof EntityHorseChestedAbstract && ((EntityHorseChestedAbstract) entityhorseabstract).isCarryingChest()) {
|
||||
for (i = 0; i < 3; ++i) {
|
||||
for (j = 0; j < ((EntityHorseChestedAbstract) entityhorseabstract).dt(); ++j) {
|
||||
this.a(new Slot(iinventory1, 2 + j + i * ((EntityHorseChestedAbstract) entityhorseabstract).dt(), 80 + j * 18, 18 + i * 18));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; ++i) {
|
||||
for (j = 0; j < 9; ++j) {
|
||||
this.a(new Slot(iinventory, j + i * 9 + 9, 8 + j * 18, 102 + i * 18 + -18));
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 9; ++i) {
|
||||
this.a(new Slot(iinventory, i, 8 + i * 18, 142));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean canUse(EntityHuman entityhuman) {
|
||||
return this.a.a(entityhuman) && this.f.isAlive() && this.f.valid && this.f.g((Entity) entityhuman) < 8.0F; // NeonPaper! - Fix MC-161754
|
||||
}
|
||||
|
||||
public ItemStack shiftClick(EntityHuman entityhuman, int i) {
|
||||
ItemStack itemstack = ItemStack.a;
|
||||
Slot slot = (Slot) this.slots.get(i);
|
||||
|
||||
if (slot != null && slot.hasItem()) {
|
||||
ItemStack itemstack1 = slot.getItem();
|
||||
|
||||
itemstack = itemstack1.cloneItemStack();
|
||||
if (i < this.a.getSize()) {
|
||||
if (!this.a(itemstack1, this.a.getSize(), this.slots.size(), true)) {
|
||||
return ItemStack.a;
|
||||
}
|
||||
} else if (this.getSlot(1).isAllowed(itemstack1) && !this.getSlot(1).hasItem()) {
|
||||
if (!this.a(itemstack1, 1, 2, false)) {
|
||||
return ItemStack.a;
|
||||
}
|
||||
} else if (this.getSlot(0).isAllowed(itemstack1)) {
|
||||
if (!this.a(itemstack1, 0, 1, false)) {
|
||||
return ItemStack.a;
|
||||
}
|
||||
} else if (this.a.getSize() <= 2 || !this.a(itemstack1, 2, this.a.getSize(), false)) {
|
||||
return ItemStack.a;
|
||||
}
|
||||
|
||||
if (itemstack1.isEmpty()) {
|
||||
slot.set(ItemStack.a);
|
||||
} else {
|
||||
slot.f();
|
||||
}
|
||||
}
|
||||
|
||||
return itemstack;
|
||||
}
|
||||
|
||||
public void b(EntityHuman entityhuman) {
|
||||
super.b(entityhuman);
|
||||
this.a.closeContainer(entityhuman);
|
||||
}
|
||||
}
|
||||
@@ -38,6 +38,10 @@
|
||||
"optimization.MixinEntityHorseAbstract",
|
||||
"optimization.MixinEntityTameableAnimal",
|
||||
"optimization.MixinPersistentCollection",
|
||||
"optimization.MixinTileEntityEnchantTable"
|
||||
"optimization.MixinTileEntityEnchantTable",
|
||||
"optimization.MixinBlockChest",
|
||||
"optimization.MixinEntityMushroomCow",
|
||||
"optimization.MixinContainerHorse",
|
||||
"optimization.MixinExplosion"
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user