mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-12 08:17:35 +00:00
Invalidate capabilities that we attach to vanilla entities and TileEntities. Closes #5307
This commit is contained in:
1 parent
d930c8ae8b
commit
0b1b3c68fa
13 files changed
+139
-53
No files matched your search
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user