mirror of
https://github.com/Ellpeck/NaturesAura.git
synced 2024-11-23 04:08:34 +01:00
greatly increase effect powder performance
This commit is contained in:
parent
299eb72ec0
commit
f48ebebc1a
8 changed files with 98 additions and 34 deletions
|
@ -28,6 +28,7 @@ import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.SoundCategory;
|
import net.minecraft.util.SoundCategory;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.chunk.Chunk;
|
import net.minecraft.world.chunk.Chunk;
|
||||||
import net.minecraft.world.chunk.IChunkProvider;
|
import net.minecraft.world.chunk.IChunkProvider;
|
||||||
|
@ -323,4 +324,8 @@ public final class Helper {
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static AxisAlignedBB aabb(Vec3d pos) {
|
||||||
|
return new AxisAlignedBB(pos.x, pos.y, pos.z, pos.x, pos.y, pos.z);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,11 @@ import baubles.api.BaublesApi;
|
||||||
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
|
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
|
||||||
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
|
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
|
||||||
import de.ellpeck.naturesaura.api.aura.container.IAuraContainer;
|
import de.ellpeck.naturesaura.api.aura.container.IAuraContainer;
|
||||||
|
import de.ellpeck.naturesaura.api.misc.IWorldData;
|
||||||
import de.ellpeck.naturesaura.api.multiblock.IMultiblock;
|
import de.ellpeck.naturesaura.api.multiblock.IMultiblock;
|
||||||
import de.ellpeck.naturesaura.blocks.multi.Multiblock;
|
import de.ellpeck.naturesaura.blocks.multi.Multiblock;
|
||||||
import de.ellpeck.naturesaura.compat.Compat;
|
import de.ellpeck.naturesaura.compat.Compat;
|
||||||
import de.ellpeck.naturesaura.entities.EntityEffectInhibitor;
|
import de.ellpeck.naturesaura.misc.WorldData;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
@ -22,9 +23,9 @@ import org.apache.commons.lang3.mutable.MutableInt;
|
||||||
import org.apache.commons.lang3.mutable.MutableObject;
|
import org.apache.commons.lang3.mutable.MutableObject;
|
||||||
import org.lwjgl.util.vector.Vector3f;
|
import org.lwjgl.util.vector.Vector3f;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class InternalHooks implements NaturesAuraAPI.IInternalHooks {
|
public class InternalHooks implements NaturesAuraAPI.IInternalHooks {
|
||||||
@Override
|
@Override
|
||||||
|
@ -107,25 +108,24 @@ public class InternalHooks implements NaturesAuraAPI.IInternalHooks {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Tuple<BlockPos, Integer>> getActiveEffectPowders(World world, AxisAlignedBB area, ResourceLocation name) {
|
public List<Tuple<Vec3d, Integer>> getActiveEffectPowders(World world, AxisAlignedBB area, ResourceLocation name) {
|
||||||
world.profiler.func_194340_a(() -> NaturesAura.MOD_ID + ":getActiveEffectPowders");
|
world.profiler.func_194340_a(() -> NaturesAura.MOD_ID + ":getActiveEffectPowders");
|
||||||
List<EntityEffectInhibitor> inhibitors = world.getEntitiesWithinAABB(
|
List<Tuple<Vec3d, Integer>> found = new ArrayList<>();
|
||||||
EntityEffectInhibitor.class, area,
|
for (Tuple<Vec3d, Integer> powder : ((WorldData) IWorldData.getWorldData(world)).effectPowders.get(name))
|
||||||
entity -> name.equals(entity.getInhibitedEffect()));
|
if (area.contains(powder.getFirst()))
|
||||||
List<Tuple<BlockPos, Integer>> tuples = inhibitors.stream()
|
found.add(powder);
|
||||||
.map(entity -> new Tuple<>(entity.getPosition(), entity.getAmount()))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
world.profiler.endSection();
|
world.profiler.endSection();
|
||||||
return tuples;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEffectPowderActive(World world, BlockPos pos, ResourceLocation name) {
|
public boolean isEffectPowderActive(World world, BlockPos pos, ResourceLocation name) {
|
||||||
world.profiler.func_194340_a(() -> NaturesAura.MOD_ID + ":isEffectPowderActive");
|
world.profiler.func_194340_a(() -> NaturesAura.MOD_ID + ":isEffectPowderActive");
|
||||||
List<Tuple<BlockPos, Integer>> powders = this.getActiveEffectPowders(world, new AxisAlignedBB(pos).grow(64), name);
|
Vec3d posVec = new Vec3d(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5);
|
||||||
for (Tuple<BlockPos, Integer> powder : powders) {
|
List<Tuple<Vec3d, Integer>> powders = this.getActiveEffectPowders(world, new AxisAlignedBB(pos).grow(64), name);
|
||||||
AxisAlignedBB bounds = new AxisAlignedBB(powder.getFirst()).grow(powder.getSecond());
|
for (Tuple<Vec3d, Integer> powder : powders) {
|
||||||
if (bounds.contains(new Vec3d(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5))) {
|
AxisAlignedBB bounds = Helper.aabb(powder.getFirst()).grow(powder.getSecond());
|
||||||
|
if (bounds.contains(posVec)) {
|
||||||
world.profiler.endSection();
|
world.profiler.endSection();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.Tuple;
|
import net.minecraft.util.Tuple;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.DimensionType;
|
import net.minecraft.world.DimensionType;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraftforge.common.capabilities.Capability;
|
import net.minecraftforge.common.capabilities.Capability;
|
||||||
|
@ -295,7 +296,7 @@ public final class NaturesAuraAPI {
|
||||||
* @param name The registry name of the powder
|
* @param name The registry name of the powder
|
||||||
* @return A list of powders' positions and ranges
|
* @return A list of powders' positions and ranges
|
||||||
*/
|
*/
|
||||||
List<Tuple<BlockPos, Integer>> getActiveEffectPowders(World world, AxisAlignedBB area, ResourceLocation name);
|
List<Tuple<Vec3d, Integer>> getActiveEffectPowders(World world, AxisAlignedBB area, ResourceLocation name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if there is an effect powder entity active anywhere
|
* Returns true if there is an effect powder entity active anywhere
|
||||||
|
|
|
@ -8,6 +8,7 @@ import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.Tuple;
|
import net.minecraft.util.Tuple;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -51,7 +52,7 @@ public class StubHooks implements NaturesAuraAPI.IInternalHooks {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Tuple<BlockPos, Integer>> getActiveEffectPowders(World world, AxisAlignedBB area, ResourceLocation name) {
|
public List<Tuple<Vec3d, Integer>> getActiveEffectPowders(World world, AxisAlignedBB area, ResourceLocation name) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ import net.minecraft.util.WeightedRandom;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.chunk.Chunk;
|
import net.minecraft.world.chunk.Chunk;
|
||||||
import net.minecraftforge.oredict.OreDictionary;
|
import net.minecraftforge.oredict.OreDictionary;
|
||||||
|
@ -78,19 +79,20 @@ public class OreSpawnEffect implements IDrainSpotEffect {
|
||||||
}
|
}
|
||||||
int totalWeight = WeightedRandom.getTotalWeight(ores);
|
int totalWeight = WeightedRandom.getTotalWeight(ores);
|
||||||
|
|
||||||
List<Tuple<BlockPos, Integer>> powders = NaturesAuraAPI.instance().getActiveEffectPowders(world,
|
List<Tuple<Vec3d, Integer>> powders = NaturesAuraAPI.instance().getActiveEffectPowders(world,
|
||||||
new AxisAlignedBB(pos).grow(this.dist), NAME);
|
new AxisAlignedBB(pos).grow(this.dist), NAME);
|
||||||
if (powders.isEmpty())
|
if (powders.isEmpty())
|
||||||
return;
|
return;
|
||||||
for (int i = 0; i < this.amount; i++) {
|
for (int i = 0; i < this.amount; i++) {
|
||||||
Tuple<BlockPos, Integer> powder = powders.get(i % powders.size());
|
Tuple<Vec3d, Integer> powder = powders.get(i % powders.size());
|
||||||
BlockPos powderPos = powder.getFirst();
|
Vec3d powderPos = powder.getFirst();
|
||||||
int range = powder.getSecond();
|
int range = powder.getSecond();
|
||||||
int x = MathHelper.floor(powderPos.getX() + world.rand.nextGaussian() * range);
|
int x = MathHelper.floor(powderPos.x + world.rand.nextGaussian() * range);
|
||||||
int y = MathHelper.floor(powderPos.getY() + world.rand.nextGaussian() * range);
|
int y = MathHelper.floor(powderPos.y + world.rand.nextGaussian() * range);
|
||||||
int z = MathHelper.floor(powderPos.getZ() + world.rand.nextGaussian() * range);
|
int z = MathHelper.floor(powderPos.z + world.rand.nextGaussian() * range);
|
||||||
BlockPos orePos = new BlockPos(x, y, z);
|
BlockPos orePos = new BlockPos(x, y, z);
|
||||||
if (orePos.distanceSq(powderPos) <= range * range && orePos.distanceSq(pos) <= this.dist * this.dist && world.isBlockLoaded(orePos)) {
|
if (orePos.distanceSq(powderPos.x, powderPos.y, powderPos.z) <= range * range
|
||||||
|
&& orePos.distanceSq(pos) <= this.dist * this.dist && world.isBlockLoaded(orePos)) {
|
||||||
IBlockState state = world.getBlockState(orePos);
|
IBlockState state = world.getBlockState(orePos);
|
||||||
Block block = state.getBlock();
|
Block block = state.getBlock();
|
||||||
if (block != requiredBlock)
|
if (block != requiredBlock)
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
package de.ellpeck.naturesaura.entities;
|
package de.ellpeck.naturesaura.entities;
|
||||||
|
|
||||||
|
import com.google.common.collect.ListMultimap;
|
||||||
|
import de.ellpeck.naturesaura.Helper;
|
||||||
import de.ellpeck.naturesaura.NaturesAura;
|
import de.ellpeck.naturesaura.NaturesAura;
|
||||||
|
import de.ellpeck.naturesaura.api.misc.IWorldData;
|
||||||
import de.ellpeck.naturesaura.api.render.IVisualizable;
|
import de.ellpeck.naturesaura.api.render.IVisualizable;
|
||||||
import de.ellpeck.naturesaura.items.ItemEffectPowder;
|
import de.ellpeck.naturesaura.items.ItemEffectPowder;
|
||||||
import de.ellpeck.naturesaura.items.ModItems;
|
import de.ellpeck.naturesaura.items.ModItems;
|
||||||
|
import de.ellpeck.naturesaura.misc.WorldData;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
|
@ -13,12 +17,16 @@ import net.minecraft.network.datasync.EntityDataManager;
|
||||||
import net.minecraft.util.DamageSource;
|
import net.minecraft.util.DamageSource;
|
||||||
import net.minecraft.util.EntityDamageSource;
|
import net.minecraft.util.EntityDamageSource;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.util.Tuple;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class EntityEffectInhibitor extends Entity implements IVisualizable {
|
public class EntityEffectInhibitor extends Entity implements IVisualizable {
|
||||||
|
|
||||||
private static final DataParameter<String> INHIBITED_EFFECT = EntityDataManager.createKey(EntityEffectInhibitor.class, DataSerializers.STRING);
|
private static final DataParameter<String> INHIBITED_EFFECT = EntityDataManager.createKey(EntityEffectInhibitor.class, DataSerializers.STRING);
|
||||||
|
@ -29,6 +37,52 @@ public class EntityEffectInhibitor extends Entity implements IVisualizable {
|
||||||
super(worldIn);
|
super(worldIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAddedToWorld() {
|
||||||
|
super.onAddedToWorld();
|
||||||
|
this.addToPowderList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRemovedFromWorld() {
|
||||||
|
this.removeFromPowderList();
|
||||||
|
super.onRemovedFromWorld();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPosition(double x, double y, double z) {
|
||||||
|
boolean should = x != this.posX || y != this.posY || z != this.posZ;
|
||||||
|
if (should)
|
||||||
|
this.removeFromPowderList();
|
||||||
|
super.setPosition(x, y, z);
|
||||||
|
if (should)
|
||||||
|
this.addToPowderList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addToPowderList() {
|
||||||
|
if (!this.isAddedToWorld())
|
||||||
|
return;
|
||||||
|
List<Tuple<Vec3d, Integer>> powders = this.getPowderList();
|
||||||
|
powders.add(new Tuple<>(this.getPositionVector(), this.getAmount()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeFromPowderList() {
|
||||||
|
if (!this.isAddedToWorld())
|
||||||
|
return;
|
||||||
|
List<Tuple<Vec3d, Integer>> powders = this.getPowderList();
|
||||||
|
Vec3d pos = this.getPositionVector();
|
||||||
|
for (int i = 0; i < powders.size(); i++)
|
||||||
|
if (pos.equals(powders.get(i).getFirst())) {
|
||||||
|
powders.remove(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Tuple<Vec3d, Integer>> getPowderList() {
|
||||||
|
ListMultimap<ResourceLocation, Tuple<Vec3d, Integer>> powders = ((WorldData) IWorldData.getWorldData(this.world)).effectPowders;
|
||||||
|
return powders.get(this.getInhibitedEffect());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void entityInit() {
|
protected void entityInit() {
|
||||||
this.setSize(0.25F, 0.25F);
|
this.setSize(0.25F, 0.25F);
|
||||||
|
@ -83,7 +137,9 @@ public class EntityEffectInhibitor extends Entity implements IVisualizable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInhibitedEffect(ResourceLocation effect) {
|
public void setInhibitedEffect(ResourceLocation effect) {
|
||||||
|
this.removeFromPowderList();
|
||||||
this.dataManager.set(INHIBITED_EFFECT, effect.toString());
|
this.dataManager.set(INHIBITED_EFFECT, effect.toString());
|
||||||
|
this.addToPowderList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResourceLocation getInhibitedEffect() {
|
public ResourceLocation getInhibitedEffect() {
|
||||||
|
@ -99,7 +155,9 @@ public class EntityEffectInhibitor extends Entity implements IVisualizable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAmount(int amount) {
|
public void setAmount(int amount) {
|
||||||
|
this.removeFromPowderList();
|
||||||
this.dataManager.set(AMOUNT, amount);
|
this.dataManager.set(AMOUNT, amount);
|
||||||
|
this.addToPowderList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getAmount() {
|
public int getAmount() {
|
||||||
|
@ -109,9 +167,7 @@ public class EntityEffectInhibitor extends Entity implements IVisualizable {
|
||||||
@Override
|
@Override
|
||||||
@SideOnly(Side.CLIENT)
|
@SideOnly(Side.CLIENT)
|
||||||
public AxisAlignedBB getVisualizationBounds(World world, BlockPos pos) {
|
public AxisAlignedBB getVisualizationBounds(World world, BlockPos pos) {
|
||||||
return new AxisAlignedBB(
|
return Helper.aabb(this.getPositionVector()).grow(this.getAmount());
|
||||||
this.posX, this.posY, this.posZ,
|
|
||||||
this.posX, this.posY, this.posZ).grow(this.getAmount());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -34,8 +34,7 @@ public class CommonEvents {
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void onWorldCapsAttach(AttachCapabilitiesEvent<World> event) {
|
public void onWorldCapsAttach(AttachCapabilitiesEvent<World> event) {
|
||||||
World world = event.getObject();
|
event.addCapability(new ResourceLocation(NaturesAura.MOD_ID, "data"), new WorldData());
|
||||||
event.addCapability(new ResourceLocation(NaturesAura.MOD_ID, "data"), new WorldData(world));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package de.ellpeck.naturesaura.misc;
|
package de.ellpeck.naturesaura.misc;
|
||||||
|
|
||||||
|
import com.google.common.collect.ArrayListMultimap;
|
||||||
|
import com.google.common.collect.ListMultimap;
|
||||||
import de.ellpeck.naturesaura.Helper;
|
import de.ellpeck.naturesaura.Helper;
|
||||||
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
|
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
|
||||||
import de.ellpeck.naturesaura.api.misc.IWorldData;
|
import de.ellpeck.naturesaura.api.misc.IWorldData;
|
||||||
|
@ -10,7 +12,9 @@ import net.minecraft.nbt.NBTBase;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.nbt.NBTTagList;
|
import net.minecraft.nbt.NBTTagList;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.util.Tuple;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraftforge.common.capabilities.Capability;
|
import net.minecraftforge.common.capabilities.Capability;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
@ -19,12 +23,8 @@ import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class WorldData implements IWorldData {
|
public class WorldData implements IWorldData {
|
||||||
private final World world;
|
|
||||||
private final Map<String, ItemStackHandlerNA> enderStorages = new HashMap<>();
|
private final Map<String, ItemStackHandlerNA> enderStorages = new HashMap<>();
|
||||||
|
public final ListMultimap<ResourceLocation, Tuple<Vec3d, Integer>> effectPowders = ArrayListMultimap.create();
|
||||||
public WorldData(World world) {
|
|
||||||
this.world = world;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasCapability(@Nonnull Capability<?> capability, @Nullable EnumFacing facing) {
|
public boolean hasCapability(@Nonnull Capability<?> capability, @Nullable EnumFacing facing) {
|
||||||
|
|
Loading…
Reference in a new issue