Invalidate capabilities that we attach to vanilla entities and TileEntities. Closes #5307

This commit is contained in:
LexManos 2019-02-06 22:55:17 -08:00
parent d930c8ae8b
commit 0b1b3c68fa
13 changed files with 139 additions and 53 deletions

View File

@ -35,7 +35,15 @@
}
public EntityType<?> func_200600_R() {
@@ -324,6 +327,7 @@
@@ -290,6 +293,7 @@
public void func_70106_y() {
this.field_70128_L = true;
+ this.invalidateCaps();
}
public void func_184174_b(boolean p_184174_1_) {
@@ -324,6 +328,7 @@
this.field_70165_t = p_70107_1_;
this.field_70163_u = p_70107_3_;
this.field_70161_v = p_70107_5_;
@ -43,7 +51,7 @@
float f = this.field_70130_N / 2.0F;
float f1 = this.field_70131_O;
this.func_174826_a(new AxisAlignedBB(p_70107_1_ - (double)f, p_70107_3_, p_70107_5_ - (double)f, p_70107_1_ + (double)f, p_70107_3_ + (double)f1, p_70107_5_ + (double)f));
@@ -794,6 +798,7 @@
@@ -794,6 +799,7 @@
this.field_70165_t = (axisalignedbb.field_72340_a + axisalignedbb.field_72336_d) / 2.0D;
this.field_70163_u = axisalignedbb.field_72338_b;
this.field_70161_v = (axisalignedbb.field_72339_c + axisalignedbb.field_72334_f) / 2.0D;
@ -51,7 +59,7 @@
}
protected SoundEvent func_184184_Z() {
@@ -845,7 +850,7 @@
@@ -845,7 +851,7 @@
protected void func_180429_a(BlockPos p_180429_1_, IBlockState p_180429_2_) {
if (!p_180429_2_.func_185904_a().func_76224_d()) {
@ -60,7 +68,7 @@
this.func_184185_a(soundtype.func_185844_d(), soundtype.func_185843_a() * 0.15F, soundtype.func_185847_b());
}
}
@@ -1040,6 +1045,7 @@
@@ -1040,6 +1046,7 @@
int k = MathHelper.func_76128_c(this.field_70161_v);
BlockPos blockpos = new BlockPos(i, j, k);
IBlockState iblockstate = this.field_70170_p.func_180495_p(blockpos);
@ -68,7 +76,7 @@
if (iblockstate.func_185901_i() != EnumBlockRenderType.INVISIBLE) {
this.field_70170_p.func_195594_a(new BlockParticleData(Particles.field_197611_d, iblockstate), this.field_70165_t + ((double)this.field_70146_Z.nextFloat() - 0.5D) * (double)this.field_70130_N, this.func_174813_aQ().field_72338_b + 0.1D, this.field_70161_v + ((double)this.field_70146_Z.nextFloat() - 0.5D) * (double)this.field_70130_N, -this.field_70159_w * 4.0D, 1.5D, -this.field_70179_y * 4.0D);
}
@@ -1053,7 +1059,7 @@
@@ -1053,7 +1060,7 @@
double d0 = this.field_70163_u + (double)this.func_70047_e();
BlockPos blockpos = new BlockPos(this.field_70165_t, d0, this.field_70161_v);
IFluidState ifluidstate = this.field_70170_p.func_204610_c(blockpos);
@ -77,7 +85,7 @@
}
}
@@ -1122,6 +1128,7 @@
@@ -1122,6 +1129,7 @@
this.field_70126_B -= 360.0F;
}
@ -85,7 +93,7 @@
this.func_70107_b(this.field_70165_t, this.field_70163_u, this.field_70161_v);
this.func_70101_b(p_70080_7_, p_70080_8_);
}
@@ -1370,6 +1377,7 @@
@@ -1370,6 +1378,7 @@
if (this.field_184238_ar) {
p_189511_1_.func_74757_a("Glowing", this.field_184238_ar);
}
@ -93,7 +101,7 @@
if (!this.field_184236_aF.isEmpty()) {
NBTTagList nbttaglist = new NBTTagList();
@@ -1381,6 +1389,9 @@
@@ -1381,6 +1390,9 @@
p_189511_1_.func_74782_a("Tags", nbttaglist);
}
@ -103,7 +111,7 @@
this.func_70014_b(p_189511_1_);
if (this.func_184207_aI()) {
NBTTagList nbttaglist1 = new NBTTagList();
@@ -1466,6 +1477,8 @@
@@ -1466,6 +1478,8 @@
this.func_174810_b(p_70020_1_.func_74767_n("Silent"));
this.func_189654_d(p_70020_1_.func_74767_n("NoGravity"));
this.func_184195_f(p_70020_1_.func_74767_n("Glowing"));
@ -112,7 +120,7 @@
if (p_70020_1_.func_150297_b("Tags", 9)) {
this.field_184236_aF.clear();
NBTTagList nbttaglist1 = p_70020_1_.func_150295_c("Tags", 8);
@@ -1546,6 +1559,8 @@
@@ -1546,6 +1560,8 @@
} else {
EntityItem entityitem = new EntityItem(this.field_70170_p, this.field_70165_t, this.field_70163_u + (double)p_70099_2_, this.field_70161_v, p_70099_1_);
entityitem.func_174869_p();
@ -121,7 +129,7 @@
this.field_70170_p.func_72838_d(entityitem);
return entityitem;
}
@@ -1595,6 +1610,7 @@
@@ -1595,6 +1611,7 @@
this.field_70159_w = 0.0D;
this.field_70181_x = 0.0D;
this.field_70179_y = 0.0D;
@ -129,7 +137,7 @@
this.func_70071_h_();
if (this.func_184218_aH()) {
entity.func_184232_k(this);
@@ -1636,6 +1652,7 @@
@@ -1636,6 +1653,7 @@
}
}
@ -137,7 +145,7 @@
if (p_184205_2_ || this.func_184228_n(p_184205_1_) && p_184205_1_.func_184219_q(this)) {
if (this.func_184218_aH()) {
this.func_184210_p();
@@ -1663,6 +1680,7 @@
@@ -1663,6 +1681,7 @@
public void func_184210_p() {
if (this.field_184239_as != null) {
Entity entity = this.field_184239_as;
@ -145,7 +153,7 @@
this.field_184239_as = null;
entity.func_184225_p(this);
}
@@ -1789,10 +1807,15 @@
@@ -1789,10 +1808,15 @@
return !this.func_184188_bt().isEmpty();
}
@ -161,7 +169,7 @@
public boolean func_70093_af() {
return this.func_70083_f(1);
}
@@ -2053,6 +2076,14 @@
@@ -2053,6 +2077,14 @@
@Nullable
public Entity func_184204_a(int p_184204_1_) {
@ -176,7 +184,7 @@
if (!this.field_70170_p.field_72995_K && !this.field_70128_L) {
this.field_70170_p.field_72984_F.func_76320_a("changeDimension");
MinecraftServer minecraftserver = this.func_184102_h();
@@ -2060,7 +2091,7 @@
@@ -2060,7 +2092,7 @@
WorldServer worldserver = minecraftserver.func_71218_a(i);
WorldServer worldserver1 = minecraftserver.func_71218_a(p_184204_1_);
this.field_71093_bK = p_184204_1_;
@ -185,7 +193,7 @@
worldserver1 = minecraftserver.func_200667_a(DimensionType.OVERWORLD);
this.field_71093_bK = 0;
}
@@ -2069,16 +2100,17 @@
@@ -2069,16 +2101,17 @@
this.field_70128_L = false;
this.field_70170_p.field_72984_F.func_76320_a("reposition");
BlockPos blockpos;
@ -208,7 +216,7 @@
d0 = MathHelper.func_151237_a(d0 * 8.0D, worldserver1.func_175723_af().func_177726_b() + 16.0D, worldserver1.func_175723_af().func_177728_d() - 16.0D);
d1 = MathHelper.func_151237_a(d1 * 8.0D, worldserver1.func_175723_af().func_177736_c() + 16.0D, worldserver1.func_175723_af().func_177733_e() - 16.0D);
}
@@ -2087,8 +2119,7 @@
@@ -2087,8 +2120,7 @@
d1 = (double)MathHelper.func_76125_a((int)d1, -29999872, 29999872);
float f = this.field_70177_z;
this.func_70012_b(d0, this.field_70163_u, d1, 90.0F, 0.0F);
@ -218,7 +226,7 @@
blockpos = new BlockPos(this);
}
@@ -2097,7 +2128,7 @@
@@ -2097,7 +2129,7 @@
Entity entity = this.func_200600_R().func_200721_a(worldserver1);
if (entity != null) {
entity.func_180432_n(this);
@ -227,7 +235,7 @@
BlockPos blockpos1 = worldserver1.func_205770_a(Heightmap.Type.MOTION_BLOCKING_NO_LEAVES, worldserver1.func_175694_M());
entity.func_174828_a(blockpos1, entity.field_70177_z, entity.field_70125_A);
} else {
@@ -2591,4 +2622,49 @@
@@ -2591,4 +2623,49 @@
public double func_212107_bY() {
return this.field_211517_W;
}
@ -259,7 +267,7 @@
+ && (this instanceof EntityPlayer || net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(field_70170_p, this))
+ && this.field_70130_N * this.field_70130_N * this.field_70131_O > 0.512F;
+ }
+
+
+ /* ================================== Forge Start =====================================*/
+ /**
+ * Internal use for keeping track of entities that are tracked by a world, to

View File

@ -369,7 +369,7 @@
this.field_184627_bm.func_77974_b(this.field_70170_p, this, this.func_184605_cv());
}
@@ -2346,4 +2406,53 @@
@@ -2346,4 +2406,60 @@
@OnlyIn(Dist.CLIENT)
public void func_191987_a(BlockPos p_191987_1_, boolean p_191987_2_) {
}
@ -415,11 +415,18 @@
+
+ @Override
+ public <T> net.minecraftforge.common.util.LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable EnumFacing facing) {
+ if (capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
+ if (!this.field_70128_L && capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
+ if (facing == null) return handlers[2].cast();
+ else if (facing.func_176740_k().func_200128_b()) return handlers[0].cast();
+ else if (facing.func_176740_k().func_176722_c()) return handlers[1].cast();
+ }
+ return super.getCapability(capability, facing);
+ }
+
+ @Override
+ public void func_70106_y() {
+ super.func_70106_y();
+ for (int x = 0; x < handlers.length; x++)
+ handlers[x].invalidate();
+ }
}

View File

@ -14,7 +14,15 @@
}
public void func_70106_y() {
@@ -163,6 +164,7 @@
@@ -131,6 +132,7 @@
}
super.func_70106_y();
+ itemHandler.invalidate();
}
public void func_184174_b(boolean p_184174_1_) {
@@ -163,6 +165,7 @@
}
public boolean func_184230_a(EntityPlayer p_184230_1_, EnumHand p_184230_2_) {
@ -22,7 +30,7 @@
if (!this.field_70170_p.field_72995_K) {
p_184230_1_.func_71007_a(this);
}
@@ -215,9 +217,9 @@
@@ -215,9 +218,9 @@
random = new Random(this.field_184291_d);
}
@ -34,7 +42,7 @@
}
loottable.func_186460_a(this, random, lootcontext$builder.func_186471_a());
@@ -238,4 +240,13 @@
@@ -238,4 +241,13 @@
public ResourceLocation func_184276_b() {
return this.field_184290_c;
}
@ -43,7 +51,7 @@
+
+ @Override
+ public <T> net.minecraftforge.common.util.LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable net.minecraft.util.EnumFacing facing) {
+ if (capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
+ if (!this.field_70128_L && capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
+ return itemHandler.cast();
+ return super.getCapability(capability, facing);
+ }

View File

@ -8,7 +8,7 @@
}
protected void func_110232_cE() {
@@ -960,4 +961,13 @@
@@ -960,4 +961,19 @@
return p_204210_2_;
}
@ -17,8 +17,14 @@
+
+ @Override
+ public <T> net.minecraftforge.common.util.LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable net.minecraft.util.EnumFacing facing) {
+ if (capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY && itemHandler != null)
+ if (!this.field_70128_L && capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY && itemHandler != null)
+ return itemHandler.cast();
+ return super.getCapability(capability, facing);
+ }
+
+ @Override
+ public void func_70106_y() {
+ super.func_70106_y();
+ itemHandler.invalidate();
+ }
}

View File

@ -61,7 +61,15 @@
public double func_145835_a(double p_145835_1_, double p_145835_3_, double p_145835_5_) {
double d0 = (double)this.field_174879_c.func_177958_n() + 0.5D - p_145835_1_;
double d1 = (double)this.field_174879_c.func_177956_o() + 0.5D - p_145835_3_;
@@ -179,4 +187,11 @@
@@ -138,6 +146,7 @@
public void func_145843_s() {
this.field_145846_f = true;
+ this.invalidateCaps();
}
public void func_145829_t() {
@@ -179,4 +188,11 @@
public TileEntityType<?> func_200662_C() {
return this.field_200663_e;
}

View File

@ -63,7 +63,7 @@
+
+ @Override
+ public <T> net.minecraftforge.common.util.LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable EnumFacing facing) {
+ if (facing != null && capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
+ if (!this.field_145846_f && facing != null && capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
+ if (facing == EnumFacing.UP)
+ return handlers[0].cast();
+ else if (facing == EnumFacing.DOWN)
@ -78,6 +78,6 @@
+ public void func_145843_s() {
+ super.func_145843_s();
+ for (int x = 0; x < handlers.length; x++)
+ handlers[x].invalidate();
+ handlers[x].invalidate();
+ }
}

View File

@ -17,7 +17,7 @@
TileEntity tileentity = p_195481_0_.func_175625_s(p_195481_1_);
if (tileentity instanceof TileEntityChest) {
return ((TileEntityChest)tileentity).field_145987_o;
@@ -235,4 +236,50 @@
@@ -235,4 +236,57 @@
p_199722_0_.func_199721_a(p_199722_1_.func_190576_q());
p_199722_1_.func_199721_a(nonnulllist);
}
@ -33,7 +33,7 @@
+
+ @Override
+ public <T> net.minecraftforge.common.util.LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> cap, EnumFacing side) {
+ if (cap == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
+ if (!this.field_145846_f && cap == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
+ if (this.chestHandler == null) {
+ this.chestHandler = net.minecraftforge.common.util.LazyOptional.of(this::createHandler);
+ }
@ -66,5 +66,12 @@
+ }
+ }
+ return new net.minecraftforge.items.wrapper.InvWrapper(this);
+ }
+
+ @Override
+ public void func_145843_s() {
+ super.func_145843_s();
+ if (chestHandler != null)
+ chestHandler.invalidate();
+ }
}

View File

@ -101,7 +101,7 @@
+
+ @Override
+ public <T> net.minecraftforge.common.util.LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable EnumFacing facing) {
+ if (facing != null && capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
+ if (!this.field_145846_f && facing != null && capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
+ if (facing == EnumFacing.UP)
+ return handlers[0].cast();
+ else if (facing == EnumFacing.DOWN)
@ -116,6 +116,6 @@
+ public void func_145843_s() {
+ super.func_145843_s();
+ for (int x = 0; x < handlers.length; x++)
+ handlers[x].invalidate();
+ handlers[x].invalidate();
+ }
}

View File

@ -1,6 +1,6 @@
--- a/net/minecraft/tileentity/TileEntityLockable.java
+++ b/net/minecraft/tileentity/TileEntityLockable.java
@@ -36,4 +36,17 @@
@@ -36,4 +36,23 @@
public void func_174892_a(LockCode p_174892_1_) {
this.field_174901_a = p_174892_1_;
}
@ -12,9 +12,15 @@
+
+ @javax.annotation.Nullable
+ public <T> net.minecraftforge.common.util.LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> cap, @javax.annotation.Nullable net.minecraft.util.EnumFacing side) {
+ if (cap == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY ) {
+ if (!this.field_145846_f && cap == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY ) {
+ return itemHandler.cast();
+ }
+ return super.getCapability(cap, side);
+ }
+
+ @Override
+ public void func_145843_s() {
+ super.func_145843_s();
+ itemHandler.invalidate();
+ }
}

View File

@ -52,18 +52,20 @@ public final class CapabilityDispatcher implements INBTSerializable<NBTTagCompou
private ICapabilityProvider[] caps;
private INBTSerializable<INBTBase>[] writers;
private String[] names;
private final List<Runnable> listeners;
public CapabilityDispatcher(Map<ResourceLocation, ICapabilityProvider> list)
public CapabilityDispatcher(Map<ResourceLocation, ICapabilityProvider> list, List<Runnable> listeners)
{
this(list, null);
this(list, listeners, null);
}
@SuppressWarnings("unchecked")
public CapabilityDispatcher(Map<ResourceLocation, ICapabilityProvider> list, @Nullable ICapabilityProvider parent)
public CapabilityDispatcher(Map<ResourceLocation, ICapabilityProvider> list, List<Runnable> listeners, @Nullable ICapabilityProvider parent)
{
List<ICapabilityProvider> lstCaps = Lists.newArrayList();
List<INBTSerializable<INBTBase>> lstWriters = Lists.newArrayList();
List<String> lstNames = Lists.newArrayList();
this.listeners = listeners;
if (parent != null) // Parents go first!
{
@ -134,4 +136,9 @@ public final class CapabilityDispatcher implements INBTSerializable<NBTTagCompou
if (this.writers.length == 0) return other.writers.length == 0;
return this.serializeNBT().equals(other.serializeNBT());
}
public void invalidate()
{
this.listeners.forEach(Runnable::run);
}
}

View File

@ -35,24 +35,25 @@ public abstract class CapabilityProvider<B extends CapabilityProvider<B>> implem
{
private final @Nonnull Class<B> baseClass;
private @Nullable CapabilityDispatcher capabilities;
private boolean valid = true;
protected CapabilityProvider(Class<B> baseClass)
{
this.baseClass = baseClass;
}
protected final void gatherCapabilities() { gatherCapabilities(null); }
protected final void gatherCapabilities(@Nullable ICapabilityProvider parent)
{
this.capabilities = ForgeEventFactory.gatherCapabilities(baseClass, this, parent);
}
protected final @Nullable CapabilityDispatcher getCapabilities()
{
return this.capabilities;
}
public final boolean areCapsCompatible(CapabilityProvider<B> other)
{
return areCapsCompatible(other.getCapabilities());
@ -71,23 +72,23 @@ public abstract class CapabilityProvider<B extends CapabilityProvider<B>> implem
{
return other.areCompatible(null);
}
}
}
else
{
return disp.areCompatible(other);
}
}
protected final @Nullable NBTTagCompound serializeCaps()
{
final CapabilityDispatcher disp = getCapabilities();
if (disp != null)
if (disp != null)
{
return disp.serializeNBT();
}
return null;
}
protected final void deserializeCaps(NBTTagCompound tag)
{
final CapabilityDispatcher disp = getCapabilities();
@ -97,11 +98,19 @@ public abstract class CapabilityProvider<B extends CapabilityProvider<B>> implem
}
}
protected void invalidateCaps()
{
this.valid = false;
final CapabilityDispatcher disp = getCapabilities();
if (disp != null)
disp.invalidate();
}
@Override
@Nonnull
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable EnumFacing side)
{
final CapabilityDispatcher disp = getCapabilities();
return disp == null ? LazyOptional.empty() : disp.getCapability(cap, side);
return !valid || disp == null ? LazyOptional.empty() : disp.getCapability(cap, side);
}
}

View File

@ -20,8 +20,10 @@
package net.minecraftforge.event;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import net.minecraft.util.ResourceLocation;
@ -40,6 +42,8 @@ public class AttachCapabilitiesEvent<T> extends GenericEvent<T>
private final T obj;
private final Map<ResourceLocation, ICapabilityProvider> caps = Maps.newLinkedHashMap();
private final Map<ResourceLocation, ICapabilityProvider> view = Collections.unmodifiableMap(caps);
private final List<Runnable> listeners = Lists.newArrayList();
private final List<Runnable> listenersView = Collections.unmodifiableList(listeners);
public AttachCapabilitiesEvent(Class<T> type, T obj)
{
@ -77,4 +81,20 @@ public class AttachCapabilitiesEvent<T> extends GenericEvent<T>
{
return view;
}
/**
* Adds a callback that is fired when the attacked object is invalidated.
* Such as a Entity/TileEntity being removed from world.
* All attached providers should invalidate all of their held capability instances.
*/
public void addListener(Runnable listener)
{
this.listeners.add(listener);
}
public List<Runnable> getListeners()
{
return this.listenersView;
}
}

View File

@ -569,7 +569,7 @@ public class ForgeEventFactory
private static CapabilityDispatcher gatherCapabilities(AttachCapabilitiesEvent<?> event, @Nullable ICapabilityProvider parent)
{
MinecraftForge.EVENT_BUS.post(event);
return event.getCapabilities().size() > 0 || parent != null ? new CapabilityDispatcher(event.getCapabilities(), parent) : null;
return event.getCapabilities().size() > 0 || parent != null ? new CapabilityDispatcher(event.getCapabilities(), event.getListeners(), parent) : null;
}
public static boolean fireSleepingLocationCheck(EntityPlayer player, BlockPos sleepingLocation)
@ -634,7 +634,7 @@ public class ForgeEventFactory
{
return MinecraftForge.EVENT_BUS.post(new ProjectileImpactEvent.Throwable(throwable, ray));
}
public static boolean onReplaceBiomeBlocks(IChunkGenerator<?> gen, IChunk chunk, IWorld world)
{
ChunkGeneratorEvent.ReplaceBiomeBlocks event = new ChunkGeneratorEvent.ReplaceBiomeBlocks(gen, chunk, world);