Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6425ef6ecd | |||
| 7ebb2a0fbb | |||
| 20a1fec6fb | |||
| 0fffc829ab | |||
| 88635d9a8d | |||
| 0fd0ed1b1c | |||
| 87f884228e | |||
| 3495d3dfd4 | |||
| 0acb03b83d | |||
| 9adb0359dd | |||
| ac259dce6a | |||
| 7a6d49412e | |||
| 10f47a560a | |||
| a8f0bbe06b | |||
| dd3cdfcec5 | |||
| 503f14f0a6 | |||
| 30af345ceb | |||
| e8af0f228b | |||
| 0291ceff30 |
+1
-1
@@ -18,7 +18,7 @@ aebuild=7
|
||||
includeMCVersionJar = false
|
||||
|
||||
# The name of your jar when you produce builds, not including any versioning info
|
||||
modArchivesBaseName = appliedenergistics2
|
||||
modArchivesBaseName = ae2-uel
|
||||
|
||||
# Will update your build.gradle automatically whenever an update is available
|
||||
autoUpdateBuildScript = false
|
||||
|
||||
@@ -81,7 +81,11 @@ public enum Settings
|
||||
|
||||
PLACE_BLOCK( EnumSet.of( YesNo.YES, YesNo.NO ) ),
|
||||
|
||||
SCHEDULING_MODE( EnumSet.allOf( SchedulingMode.class ) );
|
||||
SCHEDULING_MODE( EnumSet.allOf( SchedulingMode.class ) ),
|
||||
|
||||
STICKY_MODE( EnumSet.of( YesNo.YES, YesNo.NO ) ),
|
||||
|
||||
;
|
||||
|
||||
private final EnumSet<? extends Enum<?>> values;
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ public enum Upgrades {
|
||||
REDSTONE(0),
|
||||
CRAFTING(0),
|
||||
MAGNET(0),
|
||||
STICKY(0),
|
||||
|
||||
/**
|
||||
* Diamond Tier Upgrades.
|
||||
|
||||
@@ -100,6 +100,8 @@ public interface IMaterials {
|
||||
|
||||
IItemDefinition cardCrafting();
|
||||
|
||||
IItemDefinition cardSticky();
|
||||
|
||||
IItemDefinition enderDust();
|
||||
|
||||
IItemDefinition flour();
|
||||
|
||||
@@ -89,4 +89,12 @@ public interface IMEInventoryHandler<T extends IAEStack<T>> extends IMEInventory
|
||||
* @return true, if this inventory is valid for this pass.
|
||||
*/
|
||||
boolean validForPass( int i );
|
||||
|
||||
/**
|
||||
* Gets whether an inventory is "Sticky" i.e. only it and other sticky storages that have partitions with certain
|
||||
* items are allowed to be put into sticky storages.
|
||||
*/
|
||||
default boolean isSticky() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,8 +29,10 @@ import appeng.block.AEBaseTileBlock;
|
||||
import appeng.client.UnlistedProperty;
|
||||
import appeng.client.render.cablebus.CableBusBakedModel;
|
||||
import appeng.client.render.cablebus.CableBusRenderState;
|
||||
import appeng.client.render.cablebus.FacadeRenderState;
|
||||
import appeng.core.AppEng;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.PacketCableBusLandingParticle;
|
||||
import appeng.core.sync.packets.PacketClick;
|
||||
import appeng.helpers.AEGlassMaterial;
|
||||
import appeng.integration.abstraction.IAEFacade;
|
||||
@@ -70,10 +72,12 @@ import net.minecraft.util.math.RayTraceResult.Type;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldServer;
|
||||
import net.minecraftforge.common.property.ExtendedBlockState;
|
||||
import net.minecraftforge.common.property.IExtendedBlockState;
|
||||
import net.minecraftforge.common.property.IUnlistedProperty;
|
||||
import net.minecraftforge.fml.client.registry.ClientRegistry;
|
||||
import net.minecraftforge.fml.common.network.NetworkRegistry;
|
||||
import net.minecraftforge.fml.common.registry.GameRegistry;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
@@ -298,6 +302,90 @@ public class BlockCableBus extends AEBaseTileBlock implements IAEFacade {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addRunningEffects(IBlockState state, World world, BlockPos pos, Entity entity) {
|
||||
if (world.isRemote) {
|
||||
addRunningParticle(world, pos, entity);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
private void addRunningParticle(World world, BlockPos pos, Entity entity) {
|
||||
final ICableBusContainer cb = this.cb(world, pos);
|
||||
final IBakedModel model = Minecraft.getMinecraft().getBlockRendererDispatcher().getModelForState(this.getDefaultState());
|
||||
|
||||
if (!(model instanceof CableBusBakedModel cableBusModel)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final CableBusRenderState renderState = cb.getRenderState();
|
||||
final TextureAtlasSprite texture = getSpriteForParticle(renderState, cableBusModel);
|
||||
if (texture != null) {
|
||||
final double d0 = entity.posX + (world.rand.nextFloat() - 0.5f) * entity.width;
|
||||
final double d1 = entity.getEntityBoundingBox().minY + 0.1f;
|
||||
final double d2 = entity.posZ + (world.rand.nextFloat() - 0.5f) * entity.width;
|
||||
|
||||
final ParticleDigging particle = new DestroyFX(world, d0, d1, d2, -entity.motionX * 4.0f, 1.5f, -entity.motionZ * 4.0f, this.getDefaultState()).setBlockPos(pos);
|
||||
particle.setParticleTexture(texture);
|
||||
Minecraft.getMinecraft().effectRenderer.addEffect(particle);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addLandingEffects(IBlockState state, WorldServer world, BlockPos pos, IBlockState iblockstate, EntityLivingBase entity, int numberOfParticles) {
|
||||
// for reasons only notch can explain, this method is only called on the server, so we have to sync
|
||||
// a packet to all tracking players for landing particle effects
|
||||
if (!world.isRemote) {
|
||||
final PacketCableBusLandingParticle packet = new PacketCableBusLandingParticle(pos, entity, numberOfParticles);
|
||||
final NetworkRegistry.TargetPoint point = new NetworkRegistry.TargetPoint(world.provider.getDimension(), pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, 32);
|
||||
NetworkHandler.instance().sendToAllTracking(packet, point);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void addLandingParticle(BlockPos pos, double entityX, double entityY, double entityZ, int numberOfParticles) {
|
||||
final World world = Minecraft.getMinecraft().world;
|
||||
final ICableBusContainer cb = this.cb(world, pos);
|
||||
final IBakedModel model = Minecraft.getMinecraft().getBlockRendererDispatcher().getModelForState(this.getDefaultState());
|
||||
|
||||
if (!(model instanceof CableBusBakedModel cableBusModel)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final TextureAtlasSprite texture = getSpriteForParticle(cb.getRenderState(), cableBusModel);
|
||||
if (texture != null) {
|
||||
final Vec3d startVec = new Vec3d(entityX, entityY, entityZ);
|
||||
final Vec3d endVec = startVec.add(0.0f, -4.0f, 0.0f);
|
||||
RayTraceResult result = world.rayTraceBlocks(startVec, endVec, true, false, true);
|
||||
final double speed = 0.15f;
|
||||
|
||||
if (result != null && result.typeOfHit == Type.BLOCK && numberOfParticles != 0) {
|
||||
for (int i = 0; i < numberOfParticles; i++) {
|
||||
final double d0 = world.rand.nextGaussian() * speed;
|
||||
final double d1 = world.rand.nextGaussian() * speed;
|
||||
final double d2 = world.rand.nextGaussian() * speed;
|
||||
|
||||
final ParticleDigging particle = new DestroyFX(world, entityX, entityY, entityZ, d0, d1, d2, this.getDefaultState()).setBlockPos(pos);
|
||||
particle.setParticleTexture(texture);
|
||||
Minecraft.getMinecraft().effectRenderer.addEffect(particle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
private TextureAtlasSprite getSpriteForParticle(CableBusRenderState renderState, CableBusBakedModel cableBusModel) {
|
||||
final FacadeRenderState frs = renderState.getFacades().get(EnumFacing.UP);
|
||||
if (frs != null) {
|
||||
final IBlockState state = frs.getSourceBlock();
|
||||
final IBakedModel model = Minecraft.getMinecraft().getBlockRendererDispatcher().getModelForState(state);
|
||||
return model.getParticleTexture();
|
||||
}
|
||||
return Platform.pickRandom(cableBusModel.getParticleTextures(renderState));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void neighborChanged(IBlockState state, World world, BlockPos pos, Block blockIn, BlockPos fromPos) {
|
||||
if (Platform.isServer()) {
|
||||
|
||||
@@ -54,6 +54,7 @@ import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.settings.KeyBinding;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.EnumHand;
|
||||
@@ -82,6 +83,7 @@ import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
|
||||
import static appeng.client.KeyBindings.WCT;
|
||||
import static appeng.client.KeyBindings.WFT;
|
||||
@@ -372,4 +374,16 @@ public class ClientHelper extends ServerHelper {
|
||||
public boolean isActionKey(ActionKey key, int pressedKeyCode) {
|
||||
return this.bindings.get(key).isActiveAndMatches(pressedKeyCode);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityPlayer getPlayerByUUID(UUID uuid) {
|
||||
if (Platform.isClient()) {
|
||||
if (Minecraft.getMinecraft().player.getUniqueID().equals(uuid)) {
|
||||
return Minecraft.getMinecraft().player;
|
||||
}
|
||||
return null;
|
||||
} else {
|
||||
return super.getPlayerByUUID(uuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
package appeng.client.gui;
|
||||
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.client.gui.implementations.*;
|
||||
import appeng.client.gui.implementations.GuiCraftAmount;
|
||||
import appeng.client.gui.implementations.GuiCraftConfirm;
|
||||
import appeng.client.gui.implementations.GuiCraftingCPU;
|
||||
import appeng.client.gui.implementations.GuiExpandedProcessingPatternTerm;
|
||||
import appeng.client.gui.implementations.GuiPatternTerm;
|
||||
import appeng.client.gui.implementations.GuiUpgradeable;
|
||||
import appeng.container.interfaces.IJEIGhostIngredients;
|
||||
import appeng.container.slot.SlotFake;
|
||||
import appeng.fluids.client.gui.widgets.GuiFluidSlot;
|
||||
import appeng.container.slot.IJEITargetSlot;
|
||||
import mezz.jei.api.gui.IAdvancedGuiHandler;
|
||||
import mezz.jei.api.gui.IGhostIngredientHandler;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
@@ -78,12 +82,12 @@ public class AEGuiHandler implements IAdvancedGuiHandler<AEBaseGui>, IGhostIngre
|
||||
return (guiSloty * 3) + guiSlotx + (currentScroll * 3);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
@Nonnull
|
||||
public <I> List<Target<I>> getTargets(@Nonnull AEBaseGui gui, @Nonnull I ingredient, boolean doStart) {
|
||||
ArrayList<Target<I>> targets = new ArrayList<>();
|
||||
if (gui instanceof IJEIGhostIngredients) {
|
||||
IJEIGhostIngredients g = (IJEIGhostIngredients) gui;
|
||||
if (gui instanceof IJEIGhostIngredients g) {
|
||||
List<Target<?>> phantomTargets = g.getPhantomTargets(ingredient);
|
||||
targets.addAll((List<Target<I>>) (Object) phantomTargets);
|
||||
}
|
||||
@@ -91,13 +95,8 @@ public class AEGuiHandler implements IAdvancedGuiHandler<AEBaseGui>, IGhostIngre
|
||||
if (gui instanceof GuiUpgradeable || gui instanceof GuiPatternTerm || gui instanceof GuiExpandedProcessingPatternTerm) {
|
||||
IJEIGhostIngredients ghostGui = ((IJEIGhostIngredients) gui);
|
||||
for (Target<I> target : targets) {
|
||||
if (ghostGui.getFakeSlotTargetMap().get(target) instanceof SlotFake) {
|
||||
if (((SlotFake) ghostGui.getFakeSlotTargetMap().get(target)).getStack().isEmpty()) {
|
||||
target.accept(ingredient);
|
||||
break;
|
||||
}
|
||||
} else if (ghostGui.getFakeSlotTargetMap().get(target) instanceof GuiFluidSlot) {
|
||||
if (((GuiFluidSlot) ghostGui.getFakeSlotTargetMap().get(target)).getFluidStack() == null) {
|
||||
if (ghostGui.getFakeSlotTargetMap().get(target) instanceof IJEITargetSlot jeiSlot) {
|
||||
if (jeiSlot.needAccept()) {
|
||||
target.accept(ingredient);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.FluidUtil;
|
||||
import org.lwjgl.input.Mouse;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.awt.*;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
@@ -54,7 +55,7 @@ import java.util.*;
|
||||
|
||||
|
||||
public class GuiUpgradeable extends AEBaseGui implements IJEIGhostIngredients {
|
||||
private final Map<Target<?>, Object> mapTargetSlot = new HashMap<>();
|
||||
protected final Map<Target<?>, Object> mapTargetSlot = new HashMap<>();
|
||||
protected final ContainerUpgradeable cvb;
|
||||
protected final IUpgradeableHost bc;
|
||||
|
||||
@@ -218,24 +219,25 @@ public class GuiUpgradeable extends AEBaseGui implements IJEIGhostIngredients {
|
||||
List<Target<?>> targets = new ArrayList<>();
|
||||
|
||||
List<IJEITargetSlot> slots = new ArrayList<>();
|
||||
if (this.inventorySlots.inventorySlots.size() > 0) {
|
||||
if (!this.inventorySlots.inventorySlots.isEmpty()) {
|
||||
for (Slot slot : this.inventorySlots.inventorySlots) {
|
||||
if (slot instanceof SlotFake && (!itemStack.isEmpty() || this instanceof GuiCellWorkbench && fluidStack != null)) {
|
||||
slots.add((IJEITargetSlot) slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.getGuiSlots().size() > 0) {
|
||||
if (!this.getGuiSlots().isEmpty()) {
|
||||
for (GuiCustomSlot slot : this.getGuiSlots()) {
|
||||
if (slot instanceof GuiFluidSlot && fluidStack != null) {
|
||||
slots.add((IJEITargetSlot) slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Object slot : slots) {
|
||||
for (IJEITargetSlot slot : slots) {
|
||||
ItemStack finalItemStack = itemStack;
|
||||
FluidStack finalFluidStack = fluidStack;
|
||||
Target<Object> targetItem = new Target<Object>() {
|
||||
Target<Object> targetItem = new Target<>() {
|
||||
@Nonnull
|
||||
@Override
|
||||
public Rectangle getArea() {
|
||||
if (slot instanceof SlotFake && ((SlotFake) slot).isSlotEnabled()) {
|
||||
@@ -247,20 +249,20 @@ public class GuiUpgradeable extends AEBaseGui implements IJEIGhostIngredients {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(Object ingredient) {
|
||||
public void accept(@Nonnull Object ingredient) {
|
||||
PacketInventoryAction p = null;
|
||||
try {
|
||||
if (slot instanceof SlotFake && ((SlotFake) slot).isSlotEnabled()) {
|
||||
if (finalItemStack.isEmpty() && finalFluidStack != null) {
|
||||
p = new PacketInventoryAction(InventoryAction.PLACE_JEI_GHOST_ITEM, (IJEITargetSlot) slot, AEItemStack.fromItemStack(FluidUtil.getFilledBucket(finalFluidStack)));
|
||||
p = new PacketInventoryAction(InventoryAction.PLACE_JEI_GHOST_ITEM, slot, AEItemStack.fromItemStack(FluidUtil.getFilledBucket(finalFluidStack)));
|
||||
} else if (!finalItemStack.isEmpty()) {
|
||||
p = new PacketInventoryAction(InventoryAction.PLACE_JEI_GHOST_ITEM, (IJEITargetSlot) slot, AEItemStack.fromItemStack(finalItemStack));
|
||||
p = new PacketInventoryAction(InventoryAction.PLACE_JEI_GHOST_ITEM, slot, AEItemStack.fromItemStack(finalItemStack));
|
||||
}
|
||||
} else {
|
||||
if (finalFluidStack == null) {
|
||||
return;
|
||||
}
|
||||
p = new PacketInventoryAction(InventoryAction.PLACE_JEI_GHOST_ITEM, (IJEITargetSlot) slot, AEItemStack.fromItemStack(AEFluidStack.fromFluidStack(finalFluidStack).asItemStackRepresentation()));
|
||||
p = new PacketInventoryAction(InventoryAction.PLACE_JEI_GHOST_ITEM, slot, AEItemStack.fromItemStack(AEFluidStack.fromFluidStack(finalFluidStack).asItemStackRepresentation()));
|
||||
}
|
||||
NetworkHandler.instance().sendToServer(p);
|
||||
|
||||
|
||||
@@ -24,6 +24,10 @@ import appeng.api.parts.IPartModel;
|
||||
import appeng.api.util.AECableType;
|
||||
import appeng.api.util.AEColor;
|
||||
import appeng.block.networking.BlockCableBus;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.cache.Weigher;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||
@@ -38,6 +42,7 @@ import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.client.MinecraftForgeClient;
|
||||
import net.minecraftforge.common.property.IExtendedBlockState;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
@@ -45,8 +50,6 @@ import java.util.Map.Entry;
|
||||
|
||||
public class CableBusBakedModel implements IBakedModel {
|
||||
|
||||
static final Map<CableBusRenderState, List<BakedQuad>> CABLE_MODEL_CACHE = new HashMap<>();
|
||||
|
||||
private final CableBuilder cableBuilder;
|
||||
|
||||
private final FacadeBuilder facadeBuilder;
|
||||
@@ -57,11 +60,24 @@ public class CableBusBakedModel implements IBakedModel {
|
||||
|
||||
private final TextureMap textureMap = Minecraft.getMinecraft().getTextureMapBlocks();
|
||||
|
||||
private final LoadingCache<CableBusRenderState, List<BakedQuad>> cableModelCache;
|
||||
|
||||
CableBusBakedModel(CableBuilder cableBuilder, FacadeBuilder facadeBuilder, Map<ResourceLocation, IBakedModel> partModels, TextureAtlasSprite particleTexture) {
|
||||
this.cableBuilder = cableBuilder;
|
||||
this.facadeBuilder = facadeBuilder;
|
||||
this.partModels = partModels;
|
||||
this.particleTexture = particleTexture;
|
||||
this.cableModelCache = CacheBuilder.newBuilder()
|
||||
.maximumWeight(5000)
|
||||
.weigher((Weigher<CableBusRenderState, List<BakedQuad>>) (k, v) -> v.size())
|
||||
.build(new CacheLoader<>() {
|
||||
@Override
|
||||
public List<BakedQuad> load(@Nonnull CableBusRenderState rs) {
|
||||
final List<BakedQuad> model = new ArrayList<>();
|
||||
addCableQuads(rs, model);
|
||||
return model;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -82,12 +98,7 @@ public class CableBusBakedModel implements IBakedModel {
|
||||
if (layer == BlockRenderLayer.CUTOUT) {
|
||||
|
||||
// First, handle the cable at the center of the cable bus
|
||||
final List<BakedQuad> cableModel = CABLE_MODEL_CACHE.computeIfAbsent(renderState, k ->
|
||||
{
|
||||
final List<BakedQuad> model = new ArrayList<>();
|
||||
this.addCableQuads(renderState, model);
|
||||
return model;
|
||||
});
|
||||
final List<BakedQuad> cableModel = cableModelCache.getUnchecked(renderState);
|
||||
quads.addAll(cableModel);
|
||||
|
||||
// Then handle attachments
|
||||
|
||||
@@ -27,26 +27,21 @@ import com.google.common.collect.ImmutableMap;
|
||||
import net.minecraft.client.renderer.block.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.renderer.vertex.VertexFormat;
|
||||
import net.minecraft.client.resources.IResourceManager;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.client.model.IModel;
|
||||
import net.minecraftforge.client.model.ModelLoaderRegistry;
|
||||
import net.minecraftforge.client.resource.IResourceType;
|
||||
import net.minecraftforge.client.resource.ISelectiveResourceReloadListener;
|
||||
import net.minecraftforge.client.resource.VanillaResourceType;
|
||||
import net.minecraftforge.common.model.IModelState;
|
||||
import net.minecraftforge.common.model.TRSRTransformation;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
|
||||
/**
|
||||
* The built-in model for the cable bus block.
|
||||
*/
|
||||
public class CableBusModel implements IModel, ISelectiveResourceReloadListener {
|
||||
public class CableBusModel implements IModel {
|
||||
|
||||
private final PartModels partModels;
|
||||
|
||||
@@ -106,12 +101,4 @@ public class CableBusModel implements IModel, ISelectiveResourceReloadListener {
|
||||
public IModelState getDefaultState() {
|
||||
return TRSRTransformation.identity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResourceManagerReload(IResourceManager resourceManager, Predicate<IResourceType> resourcePredicate) {
|
||||
if (resourcePredicate.test(VanillaResourceType.MODELS)) {
|
||||
CableBusBakedModel.CABLE_MODEL_CACHE.clear();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -399,7 +399,7 @@ public abstract class AEBaseContainer extends Container {
|
||||
return ItemStack.EMPTY; // don't insert duplicate encoded patterns to interfaces
|
||||
}
|
||||
|
||||
int maxSize = Math.max(tis.getMaxStackSize(), d.getSlotStackLimit());
|
||||
int maxSize = Math.min(tis.getMaxStackSize(), d.getSlotStackLimit());
|
||||
|
||||
int placeAble = maxSize - t.getCount();
|
||||
|
||||
@@ -435,7 +435,7 @@ public abstract class AEBaseContainer extends Container {
|
||||
|
||||
if (d.isItemValid(tis)) {
|
||||
if (!d.getHasStack()) {
|
||||
int maxSize = Math.max(tis.getMaxStackSize(), d.getSlotStackLimit());
|
||||
int maxSize = Math.min(tis.getMaxStackSize(), d.getSlotStackLimit());
|
||||
|
||||
final ItemStack tmp = tis.copy();
|
||||
if (tmp.getCount() > maxSize) {
|
||||
@@ -964,26 +964,34 @@ public abstract class AEBaseContainer extends Container {
|
||||
if (!draggedStack.isEmpty()) {
|
||||
if (appEngSlot.isItemValid(draggedStack)) {
|
||||
if (slotStack.getItem() == draggedStack.getItem() && slotStack.getMetadata() == draggedStack.getMetadata() && ItemStack.areItemStackTagsEqual(slotStack, draggedStack)) {
|
||||
var maxSize = Math.max(appEngSlot.getSlotStackLimit(), draggedStack.getMaxStackSize());
|
||||
var maxInsertable = Math.min(draggedStack.getCount(), maxSize - appEngSlot.getStack().getCount());
|
||||
var toInsert = Math.min(maxInsertable, dragType == 0 ? maxInsertable : 1);
|
||||
// Slot size or stack size, whichever is smaller.
|
||||
var maxSize = Math.min(appEngSlot.getSlotStackLimit(), draggedStack.getMaxStackSize());
|
||||
|
||||
draggedStack.shrink(toInsert);
|
||||
slotStack.grow(toInsert);
|
||||
// The maximum number of items that can be inserted into the slot, non-negative.
|
||||
var maxInsertable = Math.min(draggedStack.getCount(),
|
||||
Math.max(0, maxSize - appEngSlot.getStack().getCount()));
|
||||
|
||||
slot.onSlotChanged();
|
||||
return ItemStack.EMPTY;
|
||||
if (maxInsertable != 0) {
|
||||
var toInsert = Math.min(maxInsertable, dragType == 0 ? maxInsertable : 1);
|
||||
|
||||
draggedStack.shrink(toInsert);
|
||||
slotStack.grow(toInsert);
|
||||
|
||||
slot.putStack(slot.getStack());
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Fixes taking and halving issues from oversized slots.
|
||||
else if (dragType == 0 || dragType == 1) {
|
||||
if (slot.canTakeStack(player) && !slotStack.isEmpty()) {
|
||||
var result = slotStack.copy();
|
||||
var toTake = Math.min(slotStack.getCount(), slotStack.getMaxStackSize());
|
||||
this.invPlayer.setItemStack(slot.decrStackSize(dragType == 0 ? toTake : (toTake + 1) / 2));
|
||||
|
||||
slot.onTake(player, invPlayer.getItemStack());
|
||||
return ItemStack.EMPTY;
|
||||
slot.putStack(slot.getStack());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,6 +50,9 @@ public class ContainerStorageBus extends ContainerUpgradeable {
|
||||
@GuiSync(4)
|
||||
public StorageFilter storageFilter = StorageFilter.EXTRACTABLE_ONLY;
|
||||
|
||||
@GuiSync(7)
|
||||
public YesNo stickyMode = YesNo.NO;
|
||||
|
||||
public ContainerStorageBus(final InventoryPlayer ip, final PartStorageBus te) {
|
||||
super(ip, te);
|
||||
this.storageBus = te;
|
||||
@@ -111,6 +114,7 @@ public class ContainerStorageBus extends ContainerUpgradeable {
|
||||
this.setFuzzyMode((FuzzyMode) this.getUpgradeable().getConfigManager().getSetting(Settings.FUZZY_MODE));
|
||||
this.setReadWriteMode((AccessRestriction) this.getUpgradeable().getConfigManager().getSetting(Settings.ACCESS));
|
||||
this.setStorageFilter((StorageFilter) this.getUpgradeable().getConfigManager().getSetting(Settings.STORAGE_FILTER));
|
||||
this.setStickyMode((YesNo) this.getUpgradeable().getConfigManager().getSetting(Settings.STICKY_MODE));
|
||||
}
|
||||
|
||||
this.standardDetectAndSendChanges();
|
||||
@@ -168,4 +172,12 @@ public class ContainerStorageBus extends ContainerUpgradeable {
|
||||
private void setStorageFilter(final StorageFilter storageFilter) {
|
||||
this.storageFilter = storageFilter;
|
||||
}
|
||||
|
||||
public YesNo getStickyMode() {
|
||||
return this.stickyMode;
|
||||
}
|
||||
|
||||
private void setStickyMode(final YesNo stickyMode) {
|
||||
this.stickyMode = stickyMode;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
package appeng.container.slot;
|
||||
|
||||
public interface IJEITargetSlot {
|
||||
|
||||
default boolean needAccept() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -50,7 +50,6 @@ public class SlotFake extends AppEngSlot implements IJEITargetSlot {
|
||||
if (!is.isEmpty()) {
|
||||
is = is.copy();
|
||||
}
|
||||
|
||||
super.putStack(is);
|
||||
}
|
||||
|
||||
@@ -58,4 +57,10 @@ public class SlotFake extends AppEngSlot implements IJEITargetSlot {
|
||||
public boolean canTakeStack(final EntityPlayer par1EntityPlayer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needAccept() {
|
||||
return this.getStack().isEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import appeng.client.ActionKey;
|
||||
import appeng.client.EffectType;
|
||||
import appeng.core.sync.AppEngPacket;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.world.World;
|
||||
@@ -32,6 +33,7 @@ import net.minecraft.world.World;
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
|
||||
|
||||
public abstract class CommonHelper {
|
||||
@@ -66,4 +68,5 @@ public abstract class CommonHelper {
|
||||
|
||||
public abstract boolean isActionKey(@Nonnull final ActionKey key, int pressedKeyCode);
|
||||
|
||||
public abstract EntityPlayer getPlayerByUUID(UUID uuid);
|
||||
}
|
||||
|
||||
@@ -364,15 +364,19 @@ final class Registration {
|
||||
// Storage Cells
|
||||
Upgrades.FUZZY.registerItem(items.cell1k(), 1);
|
||||
Upgrades.INVERTER.registerItem(items.cell1k(), 1);
|
||||
Upgrades.STICKY.registerItem(items.cell1k(), 1);
|
||||
|
||||
Upgrades.FUZZY.registerItem(items.cell4k(), 1);
|
||||
Upgrades.INVERTER.registerItem(items.cell4k(), 1);
|
||||
Upgrades.STICKY.registerItem(items.cell4k(), 1);
|
||||
|
||||
Upgrades.FUZZY.registerItem(items.cell16k(), 1);
|
||||
Upgrades.INVERTER.registerItem(items.cell16k(), 1);
|
||||
Upgrades.STICKY.registerItem(items.cell16k(), 1);
|
||||
|
||||
Upgrades.FUZZY.registerItem(items.cell64k(), 1);
|
||||
Upgrades.INVERTER.registerItem(items.cell64k(), 1);
|
||||
Upgrades.STICKY.registerItem(items.cell64k(), 1);
|
||||
|
||||
Upgrades.FUZZY.registerItem(items.portableCell(), 1);
|
||||
Upgrades.INVERTER.registerItem(items.portableCell(), 1);
|
||||
@@ -383,14 +387,29 @@ final class Registration {
|
||||
Upgrades.FUZZY.registerItem(AEApi.instance().definitions().materials().cardMagnet(), 1);
|
||||
Upgrades.INVERTER.registerItem(AEApi.instance().definitions().materials().cardMagnet(), 1);
|
||||
|
||||
// Fluid Cells
|
||||
Upgrades.INVERTER.registerItem(items.fluidCell1k(), 1);
|
||||
Upgrades.STICKY.registerItem(items.fluidCell1k(), 1);
|
||||
|
||||
Upgrades.INVERTER.registerItem(items.fluidCell4k(), 1);
|
||||
Upgrades.STICKY.registerItem(items.fluidCell4k(), 1);
|
||||
|
||||
Upgrades.INVERTER.registerItem(items.fluidCell16k(), 1);
|
||||
Upgrades.STICKY.registerItem(items.fluidCell16k(), 1);
|
||||
|
||||
Upgrades.INVERTER.registerItem(items.fluidCell64k(), 1);
|
||||
Upgrades.STICKY.registerItem(items.fluidCell64k(), 1);
|
||||
|
||||
// Storage Bus
|
||||
Upgrades.FUZZY.registerItem(parts.storageBus(), 1);
|
||||
Upgrades.INVERTER.registerItem(parts.storageBus(), 1);
|
||||
Upgrades.CAPACITY.registerItem(parts.storageBus(), 5);
|
||||
Upgrades.STICKY.registerItem(parts.storageBus(), 1);
|
||||
|
||||
// Storage Bus Fluids
|
||||
Upgrades.INVERTER.registerItem(parts.fluidStorageBus(), 1);
|
||||
Upgrades.CAPACITY.registerItem(parts.fluidStorageBus(), 5);
|
||||
Upgrades.STICKY.registerItem(parts.fluidStorageBus(), 1);
|
||||
|
||||
// Formation Plane
|
||||
Upgrades.FUZZY.registerItem(parts.formationPlane(), 1);
|
||||
|
||||
@@ -60,6 +60,10 @@ public class ApiClientHelper implements IClientHelper {
|
||||
lines.add("[" + GuiText.Partitioned.getLocal() + "]" + " - " + list + ' ' + GuiText.Precise.getLocal());
|
||||
}
|
||||
|
||||
if (handler.isSticky()) {
|
||||
lines.add(GuiText.Sticky.getLocal());
|
||||
}
|
||||
|
||||
if (Minecraft.getMinecraft().gameSettings.advancedItemTooltips || Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT)) {
|
||||
IItemHandler inv = cellInventory.getConfigInventory();
|
||||
cellInventory.getAvailableItems((IItemList) itemList);
|
||||
|
||||
@@ -90,6 +90,7 @@ public final class ApiMaterials implements IMaterials {
|
||||
private final IItemDefinition cardFuzzy;
|
||||
private final IItemDefinition cardInverter;
|
||||
private final IItemDefinition cardCrafting;
|
||||
private final IItemDefinition cardSticky;
|
||||
|
||||
private final IItemDefinition enderDust;
|
||||
private final IItemDefinition flour;
|
||||
@@ -208,6 +209,7 @@ public final class ApiMaterials implements IMaterials {
|
||||
this.cardFuzzy = new DamagedItemDefinition("material.card.fuzzy", materials.createMaterial(MaterialType.CARD_FUZZY));
|
||||
this.cardInverter = new DamagedItemDefinition("material.card.inverter", materials.createMaterial(MaterialType.CARD_INVERTER));
|
||||
this.cardCrafting = new DamagedItemDefinition("material.card.crafting", materials.createMaterial(MaterialType.CARD_CRAFTING));
|
||||
this.cardSticky = new DamagedItemDefinition("material.card.sticky", materials.createMaterial(MaterialType.CARD_STICKY));
|
||||
|
||||
this.enderDust = new DamagedItemDefinition("material.dust.ender", materials.createMaterial(MaterialType.ENDER_DUST));
|
||||
this.flour = new DamagedItemDefinition("material.flour", materials.createMaterial(MaterialType.FLOUR));
|
||||
@@ -425,6 +427,11 @@ public final class ApiMaterials implements IMaterials {
|
||||
return this.cardCrafting;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemDefinition cardSticky() {
|
||||
return this.cardSticky;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemDefinition enderDust() {
|
||||
return this.enderDust;
|
||||
|
||||
@@ -195,6 +195,7 @@ public enum GuiText {
|
||||
Partitioned,
|
||||
Precise,
|
||||
Fuzzy,
|
||||
Sticky,
|
||||
|
||||
// Used in a terminal to indicate that an item is craftable
|
||||
SmallFontCraft,
|
||||
|
||||
@@ -88,7 +88,11 @@ public class AppEngPacketHandlerBase {
|
||||
|
||||
PACKET_CRAFTING_TOAST(PacketCraftingToast.class),
|
||||
|
||||
PACKET_COLOR_APPLICATOR_SELECT_COLOR(PacketColorApplicatorSelectColor.class);
|
||||
PACKET_COLOR_APPLICATOR_SELECT_COLOR(PacketColorApplicatorSelectColor.class),
|
||||
|
||||
PACKET_CABLE_BUS_LANDING_PARTICLE(PacketCableBusLandingParticle.class),
|
||||
|
||||
;
|
||||
|
||||
|
||||
private final Class<? extends AppEngPacket> packetClass;
|
||||
|
||||
@@ -112,6 +112,10 @@ public class NetworkHandler {
|
||||
this.ec.sendToAllAround(message.getProxy(), point);
|
||||
}
|
||||
|
||||
public void sendToAllTracking(final AppEngPacket message, final NetworkRegistry.TargetPoint point) {
|
||||
this.ec.sendToAllTracking(message.getProxy(), point);
|
||||
}
|
||||
|
||||
public void sendToDimension(final AppEngPacket message, final int dimensionId) {
|
||||
this.ec.sendToDimension(message.getProxy(), dimensionId);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package appeng.core.sync.packets;
|
||||
|
||||
import appeng.block.networking.BlockCableBus;
|
||||
import appeng.core.sync.AppEngPacket;
|
||||
import appeng.core.sync.network.INetworkInfo;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
||||
public class PacketCableBusLandingParticle extends AppEngPacket {
|
||||
|
||||
private BlockPos pos;
|
||||
private double entityX;
|
||||
private double entityY;
|
||||
private double entityZ;
|
||||
private int numberOfParticles;
|
||||
|
||||
public PacketCableBusLandingParticle(final ByteBuf stream) {
|
||||
this.pos = BlockPos.fromLong(stream.readLong());
|
||||
this.entityX = stream.readDouble();
|
||||
this.entityY = stream.readDouble();
|
||||
this.entityZ = stream.readDouble();
|
||||
this.numberOfParticles = stream.readInt();
|
||||
}
|
||||
|
||||
public PacketCableBusLandingParticle(final BlockPos pos, final Entity entity, final int numberOfParticles) {
|
||||
final ByteBuf data = Unpooled.buffer();
|
||||
|
||||
data.writeInt(this.getPacketID());
|
||||
data.writeLong(pos.toLong());
|
||||
data.writeDouble(entity.posX);
|
||||
data.writeDouble(entity.posY);
|
||||
data.writeDouble(entity.posZ);
|
||||
data.writeInt(numberOfParticles);
|
||||
|
||||
this.configureWrite(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void clientPacketData(INetworkInfo network, AppEngPacket packet, EntityPlayer player) {
|
||||
final World world = Minecraft.getMinecraft().world;
|
||||
final IBlockState state = world.getBlockState(pos);
|
||||
if (state.getBlock() instanceof BlockCableBus cb) {
|
||||
cb.addLandingParticle(pos, entityX, entityY, entityZ, numberOfParticles);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,10 +22,12 @@ package appeng.core.sync.packets;
|
||||
import appeng.block.networking.BlockCableBus;
|
||||
import appeng.core.sync.AppEngPacket;
|
||||
import appeng.core.sync.network.INetworkInfo;
|
||||
import appeng.items.tools.ToolNetworkTool;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
@@ -97,6 +99,11 @@ public class PacketClick extends AppEngPacket {
|
||||
if (block instanceof BlockCableBus) {
|
||||
((BlockCableBus) block).onBlockClickPacket(player.world, pos, player, this.hand, new Vec3d(this.hitX, this.hitY, this.hitZ));
|
||||
}
|
||||
} else {
|
||||
final ItemStack is = player.inventory.getCurrentItem();
|
||||
if (!is.isEmpty() && is.getItem() instanceof ToolNetworkTool tnt) {
|
||||
tnt.serverSideToolLogic(is, player, hand, player.world, pos, side, hitX, hitY, hitZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@ import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -39,11 +41,15 @@ public class PacketCraftingToast extends AppEngPacket {
|
||||
@Override
|
||||
public void clientPacketData(INetworkInfo network, AppEngPacket packet, EntityPlayer player) {
|
||||
if (AEConfig.instance().isFeatureEnabled(AEFeature.CRAFTING_TOASTS)) {
|
||||
Minecraft.getMinecraft()
|
||||
.getToastGui().add(new CraftingStatusToast(stack.asItemStackRepresentation(), cancelled));
|
||||
doCraftingToast();
|
||||
}
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
private void doCraftingToast() {
|
||||
Minecraft.getMinecraft().getToastGui().add(new CraftingStatusToast(stack.asItemStackRepresentation(), cancelled));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serverPacketData(INetworkInfo manager, AppEngPacket packet, EntityPlayer player) {}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import net.minecraft.launchwrapper.IClassTransformer;
|
||||
import net.minecraft.launchwrapper.Launch;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
@@ -31,7 +32,11 @@ import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.commons.ClassRemapper;
|
||||
import org.objectweb.asm.commons.Remapper;
|
||||
import org.objectweb.asm.tree.*;
|
||||
import org.objectweb.asm.tree.AbstractInsnNode;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.FieldNode;
|
||||
import org.objectweb.asm.tree.MethodInsnNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -48,7 +53,7 @@ public class AE2ELTransformer implements IClassTransformer {
|
||||
|
||||
if ("net.minecraftforge.common.ForgeHooks".equals(transformedName)) {
|
||||
ClassReader cr = new ClassReader(basicClass);
|
||||
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
|
||||
ClassWriter cw = new SafeClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
|
||||
ClassVisitor cv = new PickBlockPatch(cw);
|
||||
cr.accept(cv, ClassReader.EXPAND_FRAMES);
|
||||
return cw.toByteArray();
|
||||
@@ -188,4 +193,39 @@ public class AE2ELTransformer implements IClassTransformer {
|
||||
|
||||
}
|
||||
|
||||
private static class SafeClassWriter extends ClassWriter {
|
||||
|
||||
public SafeClassWriter(int flags) {
|
||||
super(flags);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getCommonSuperClass(final String type1, final String type2) {
|
||||
Class<?> c, d;
|
||||
// clueless
|
||||
ClassLoader classLoader = Launch.classLoader;
|
||||
try {
|
||||
c = Class.forName(type1.replace('/', '.'), false, classLoader);
|
||||
d = Class.forName(type2.replace('/', '.'), false, classLoader);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e.toString());
|
||||
}
|
||||
if (c.isAssignableFrom(d)) {
|
||||
return type1;
|
||||
}
|
||||
if (d.isAssignableFrom(c)) {
|
||||
return type2;
|
||||
}
|
||||
if (c.isInterface() || d.isInterface()) {
|
||||
return "java/lang/Object";
|
||||
} else {
|
||||
do {
|
||||
c = c.getSuperclass();
|
||||
} while (!c.isAssignableFrom(d));
|
||||
return c.getName().replace('.', '/');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -93,4 +93,10 @@ public class GuiFluidSlot extends GuiCustomSlot implements IJEITargetSlot {
|
||||
this.fluids.setFluidInSlot(this.slot, stack);
|
||||
NetworkHandler.instance().sendToServer(new PacketFluidSlot(Collections.singletonMap(this.getId(), this.getFluidStack())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needAccept() {
|
||||
return this.getFluidStack() == null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ package appeng.fluids.items;
|
||||
import appeng.bootstrap.IItemRendering;
|
||||
import appeng.bootstrap.ItemRenderingCustomizer;
|
||||
import appeng.client.render.DummyFluidItemModel;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
|
||||
|
||||
/**
|
||||
@@ -33,5 +34,9 @@ public class FluidDummyItemRendering extends ItemRenderingCustomizer {
|
||||
@Override
|
||||
public void customize(IItemRendering rendering) {
|
||||
rendering.builtInModel("models/item/dummy_fluid_item", new DummyFluidItemModel());
|
||||
rendering.color(((s, i) -> {
|
||||
FluidStack fluid = ((FluidDummyItem) s.getItem()).getFluidStack(s);
|
||||
return fluid != null ? fluid.getFluid().getColor() : 0xFFFFFFFF;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,6 +80,7 @@ import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
@@ -220,11 +221,13 @@ public class PartFluidStorageBus extends PartUpgradeable implements IGridTickabl
|
||||
@Override
|
||||
public void postChange(final IBaseMonitor<IAEFluidStack> monitor, final Iterable<IAEFluidStack> change, final IActionSource source) {
|
||||
if (this.getProxy().isActive()) {
|
||||
var filteredChanges = this.filterChanges(change);
|
||||
|
||||
AccessRestriction currentAccess = (AccessRestriction) ((ConfigManager) this.getConfigManager()).getSetting(Settings.ACCESS);
|
||||
if (readOncePass) {
|
||||
readOncePass = false;
|
||||
try {
|
||||
this.getProxy().getStorage().postAlterationOfStoredItems(AEApi.instance().storage().getStorageChannel(IFluidStorageChannel.class), change, this.source);
|
||||
this.getProxy().getStorage().postAlterationOfStoredItems(AEApi.instance().storage().getStorageChannel(IFluidStorageChannel.class), filteredChanges, this.source);
|
||||
} catch (final GridAccessException e) {
|
||||
// :(
|
||||
}
|
||||
@@ -234,7 +237,7 @@ public class PartFluidStorageBus extends PartUpgradeable implements IGridTickabl
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this.getProxy().getStorage().postAlterationOfStoredItems(AEApi.instance().storage().getStorageChannel(IFluidStorageChannel.class), change, source);
|
||||
this.getProxy().getStorage().postAlterationOfStoredItems(AEApi.instance().storage().getStorageChannel(IFluidStorageChannel.class), filteredChanges, source);
|
||||
} catch (final GridAccessException e) {
|
||||
// :(
|
||||
}
|
||||
@@ -426,6 +429,7 @@ public class PartFluidStorageBus extends PartUpgradeable implements IGridTickabl
|
||||
this.handler.setBaseAccess((AccessRestriction) this.getConfigManager().getSetting(Settings.ACCESS));
|
||||
this.handler.setWhitelist(this.getInstalledUpgrades(Upgrades.INVERTER) > 0 ? IncludeExclude.BLACKLIST : IncludeExclude.WHITELIST);
|
||||
this.handler.setPriority(this.getPriority());
|
||||
this.handler.setStorageFilter((StorageFilter) this.getConfigManager().getSetting(Settings.STORAGE_FILTER));
|
||||
|
||||
final IItemList<IAEFluidStack> priorityList = AEApi.instance().storage().getStorageChannel(IFluidStorageChannel.class).createList();
|
||||
|
||||
@@ -437,6 +441,10 @@ public class PartFluidStorageBus extends PartUpgradeable implements IGridTickabl
|
||||
}
|
||||
}
|
||||
|
||||
if (this.getInstalledUpgrades(Upgrades.STICKY) > 0) {
|
||||
this.handler.setSticky(true);
|
||||
}
|
||||
|
||||
if (this.getInstalledUpgrades(Upgrades.FUZZY) > 0) {
|
||||
this.handler.setPartitionList(new FuzzyPriorityList<IAEFluidStack>(priorityList, (FuzzyMode) this.getConfigManager().getSetting(Settings.FUZZY_MODE)));
|
||||
} else {
|
||||
@@ -533,4 +541,26 @@ public class PartFluidStorageBus extends PartUpgradeable implements IGridTickabl
|
||||
public GuiBridge getGuiBridge() {
|
||||
return GuiBridge.GUI_STORAGEBUS_FLUID;
|
||||
}
|
||||
|
||||
// TODO: 1/28/2024 Unify both methods.
|
||||
/**
|
||||
* Filters the changes to only include items that pass the storage filter.
|
||||
* Optimally, this should be handled by the underlying monitor.
|
||||
*
|
||||
* @see appeng.parts.misc.PartStorageBus#filterChanges
|
||||
*/
|
||||
protected Iterable<IAEFluidStack> filterChanges(Iterable<IAEFluidStack> change) {
|
||||
var storageFilter = this.getConfigManager().getSetting(Settings.STORAGE_FILTER);
|
||||
if (storageFilter == StorageFilter.EXTRACTABLE_ONLY && handler != null) {
|
||||
var filteredList = new ArrayList<IAEFluidStack>();
|
||||
for (final IAEFluidStack stack : change) {
|
||||
if (this.handler.passesBlackOrWhitelist(stack)) {
|
||||
filteredList.add(stack);
|
||||
}
|
||||
}
|
||||
|
||||
return filteredList;
|
||||
}
|
||||
return change;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
package appeng.helpers;
|
||||
|
||||
import appeng.util.Platform;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraftforge.fml.server.FMLServerHandler;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class PlayerHelper {
|
||||
@Nullable
|
||||
public static EntityPlayerMP getPlayerByUUID(UUID uuid) {
|
||||
final MinecraftServer server;
|
||||
if (Platform.isClientInstall()) {
|
||||
server = Minecraft.getMinecraft().getIntegratedServer();
|
||||
} else {
|
||||
server = FMLServerHandler.instance().getServer();
|
||||
}
|
||||
|
||||
if (server == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return server.getPlayerList().getPlayerByUUID(uuid);
|
||||
}
|
||||
}
|
||||
@@ -166,6 +166,8 @@ public final class ItemMaterial extends AEBaseItem implements IStorageComponent,
|
||||
return Upgrades.MAGNET;
|
||||
case CARD_QUANTUM_LINK:
|
||||
return Upgrades.QUANTUM_LINK;
|
||||
case CARD_STICKY:
|
||||
return Upgrades.STICKY;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -120,7 +120,9 @@ public enum MaterialType {
|
||||
|
||||
CARD_PATTERN_EXPANSION(58, "material_card_pattern_expansion", EnumSet.of(AEFeature.ADVANCED_CARDS)),
|
||||
CARD_QUANTUM_LINK(59, "material_card_quantum_link", EnumSet.of(AEFeature.ADVANCED_CARDS, AEFeature.QUANTUM_LINKING_CARD)),
|
||||
CARD_MAGNET(60, "material_card_magnet", EnumSet.of(AEFeature.BASIC_CARDS));
|
||||
CARD_MAGNET(60, "material_card_magnet", EnumSet.of(AEFeature.BASIC_CARDS)),
|
||||
CARD_STICKY(61, "material_card_sticky", EnumSet.of(AEFeature.BASIC_CARDS)),
|
||||
;
|
||||
|
||||
|
||||
private final Set<AEFeature> features;
|
||||
|
||||
@@ -221,6 +221,9 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
||||
// new craftables!
|
||||
for (final ICraftingPatternDetails details : this.craftingMethods.keySet()) {
|
||||
for (IAEItemStack out : details.getOutputs()) {
|
||||
if (out == null) {
|
||||
continue;
|
||||
}
|
||||
out = out.copy();
|
||||
out.reset();
|
||||
out.setCraftable(true);
|
||||
|
||||
@@ -41,12 +41,12 @@ import appeng.api.util.WorldCoord;
|
||||
import appeng.container.ContainerNull;
|
||||
import appeng.core.AEConfig;
|
||||
import appeng.core.AELog;
|
||||
import appeng.core.AppEng;
|
||||
import appeng.core.features.AEFeature;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.PacketCraftingToast;
|
||||
import appeng.crafting.*;
|
||||
import appeng.helpers.PatternHelper;
|
||||
import appeng.helpers.PlayerHelper;
|
||||
import appeng.me.cache.CraftingGridCache;
|
||||
import appeng.me.cluster.IAECluster;
|
||||
import appeng.me.helpers.MachineSource;
|
||||
@@ -57,6 +57,7 @@ import appeng.util.Platform;
|
||||
import appeng.util.item.AEItemStack;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.inventory.InventoryCrafting;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
@@ -395,10 +396,10 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU {
|
||||
if (this.finalOutput == null) return;
|
||||
if (!AEConfig.instance().isFeatureEnabled(AEFeature.CRAFTING_TOASTS)) return;
|
||||
|
||||
var player = PlayerHelper.getPlayerByUUID(this.requestingPlayerUUID);
|
||||
if (player != null) {
|
||||
var player = AppEng.proxy.getPlayerByUUID(this.requestingPlayerUUID);
|
||||
if (player instanceof EntityPlayerMP playerMP) {
|
||||
try {
|
||||
NetworkHandler.instance().sendTo(new PacketCraftingToast(this.finalOutput, cancelled), player);
|
||||
NetworkHandler.instance().sendTo(new PacketCraftingToast(this.finalOutput, cancelled), playerMP);
|
||||
} catch (IOException ignored) {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,4 +160,8 @@ public class MEMonitorHandler<T extends IAEStack<T>> implements IMEMonitor<T> {
|
||||
return this.getHandler().validForPass(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSticky() {
|
||||
return this.internalHandler.isSticky();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ public class BasicCellInventoryHandler<T extends IAEStack<T>> extends MEInventor
|
||||
|
||||
boolean hasInverter = false;
|
||||
boolean hasFuzzy = false;
|
||||
boolean hasSticky = false;
|
||||
|
||||
for (int x = 0; x < upgrades.getSlots(); x++) {
|
||||
final ItemStack is = upgrades.getStackInSlot(x);
|
||||
@@ -69,6 +70,9 @@ public class BasicCellInventoryHandler<T extends IAEStack<T>> extends MEInventor
|
||||
case INVERTER:
|
||||
hasInverter = true;
|
||||
break;
|
||||
case STICKY:
|
||||
hasSticky = true;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
@@ -87,6 +91,10 @@ public class BasicCellInventoryHandler<T extends IAEStack<T>> extends MEInventor
|
||||
|
||||
this.setWhitelist(hasInverter ? IncludeExclude.BLACKLIST : IncludeExclude.WHITELIST);
|
||||
|
||||
if (hasSticky) {
|
||||
setSticky(true);
|
||||
}
|
||||
|
||||
if (!priorityList.isEmpty()) {
|
||||
if (hasFuzzy) {
|
||||
this.setPartitionList(new FuzzyPriorityList<>(priorityList, fzMode));
|
||||
|
||||
@@ -40,7 +40,6 @@ public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T> {
|
||||
private final ICellHandler handler;
|
||||
private final TileDrive drive;
|
||||
private final IActionSource source;
|
||||
|
||||
public DriveWatcher(final ICellInventoryHandler<T> i, final ItemStack is, final ICellHandler han, final TileDrive drive) {
|
||||
super(i, i.getChannel());
|
||||
this.is = is;
|
||||
@@ -100,4 +99,13 @@ public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T> {
|
||||
|
||||
return extractable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSticky() {
|
||||
if (this.getInternal() instanceof ICellInventoryHandler<?> cellInventoryHandler) {
|
||||
return cellInventoryHandler.isSticky();
|
||||
}
|
||||
|
||||
return super.isSticky();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ package appeng.me.storage;
|
||||
import appeng.api.config.AccessRestriction;
|
||||
import appeng.api.config.Actionable;
|
||||
import appeng.api.config.IncludeExclude;
|
||||
import appeng.api.config.StorageFilter;
|
||||
import appeng.api.networking.security.IActionSource;
|
||||
import appeng.api.storage.IMEInventory;
|
||||
import appeng.api.storage.IMEInventoryHandler;
|
||||
@@ -38,11 +39,14 @@ public class MEInventoryHandler<T extends IAEStack<T>> implements IMEInventoryHa
|
||||
private int myPriority;
|
||||
private IncludeExclude myWhitelist;
|
||||
private AccessRestriction myAccess;
|
||||
private StorageFilter storageFilter;
|
||||
private IPartitionList<T> myPartitionList;
|
||||
|
||||
private AccessRestriction cachedAccessRestriction;
|
||||
private boolean hasReadAccess;
|
||||
private boolean hasWriteAccess;
|
||||
private boolean isSticky;
|
||||
private boolean gettingAvailableContent;
|
||||
|
||||
public MEInventoryHandler(final IMEInventory<T> i, final IStorageChannel<T> channel) {
|
||||
if (i instanceof IMEInventoryHandler) {
|
||||
@@ -76,7 +80,7 @@ public class MEInventoryHandler<T extends IAEStack<T>> implements IMEInventoryHa
|
||||
this.hasWriteAccess = this.cachedAccessRestriction.hasPermission(AccessRestriction.WRITE);
|
||||
}
|
||||
|
||||
IPartitionList<T> getPartitionList() {
|
||||
public IPartitionList<T> getPartitionList() {
|
||||
return this.myPartitionList;
|
||||
}
|
||||
|
||||
@@ -95,7 +99,7 @@ public class MEInventoryHandler<T extends IAEStack<T>> implements IMEInventoryHa
|
||||
|
||||
@Override
|
||||
public T extractItems(final T request, final Actionable type, final IActionSource src) {
|
||||
if (!this.hasReadAccess) {
|
||||
if (!this.canExtract(request)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -104,11 +108,27 @@ public class MEInventoryHandler<T extends IAEStack<T>> implements IMEInventoryHa
|
||||
|
||||
@Override
|
||||
public IItemList<T> getAvailableItems(final IItemList<T> out) {
|
||||
if (!this.hasReadAccess) {
|
||||
if (this.gettingAvailableContent || !this.hasReadAccess) {
|
||||
return out;
|
||||
}
|
||||
|
||||
return this.internal.getAvailableItems(out);
|
||||
this.gettingAvailableContent = true;
|
||||
try {
|
||||
if (this.storageFilter == StorageFilter.EXTRACTABLE_ONLY) {
|
||||
var stackList = this.internal.getAvailableItems(this.getChannel().createList());
|
||||
for (final T t : stackList) {
|
||||
if (this.shouldItemBeAvailable(t)) {
|
||||
out.add(t);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return this.internal.getAvailableItems(out);
|
||||
}
|
||||
} finally {
|
||||
this.gettingAvailableContent = false;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -135,13 +155,11 @@ public class MEInventoryHandler<T extends IAEStack<T>> implements IMEInventoryHa
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.myWhitelist == IncludeExclude.BLACKLIST && this.myPartitionList.isListed(input)) {
|
||||
if (!this.passesBlackOrWhitelist(input)) {
|
||||
return false;
|
||||
}
|
||||
if (this.myPartitionList.isEmpty() || this.myWhitelist == IncludeExclude.BLACKLIST) {
|
||||
return this.internal.canAccept(input);
|
||||
}
|
||||
return this.myPartitionList.isListed(input) && this.internal.canAccept(input);
|
||||
|
||||
return this.internal.canAccept(input);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -166,4 +184,40 @@ public class MEInventoryHandler<T extends IAEStack<T>> implements IMEInventoryHa
|
||||
public IMEInventory<T> getInternal() {
|
||||
return this.internal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSticky() {
|
||||
return isSticky;
|
||||
}
|
||||
|
||||
public void setSticky(boolean isSticky) {
|
||||
this.isSticky = isSticky;
|
||||
}
|
||||
|
||||
protected boolean canExtract(T request) {
|
||||
return this.hasReadAccess;
|
||||
}
|
||||
|
||||
private boolean shouldItemBeAvailable(T t) {
|
||||
return this.hasReadAccess && this.passesBlackOrWhitelist(t);
|
||||
}
|
||||
|
||||
public boolean passesBlackOrWhitelist(T input) {
|
||||
if (this.myPartitionList.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return switch (this.myWhitelist) {
|
||||
case WHITELIST -> this.myPartitionList.isListed(input);
|
||||
case BLACKLIST -> !this.myPartitionList.isListed(input);
|
||||
};
|
||||
}
|
||||
|
||||
public StorageFilter getStorageFilter() {
|
||||
return storageFilter;
|
||||
}
|
||||
|
||||
public void setStorageFilter(StorageFilter storageFilter) {
|
||||
this.storageFilter = storageFilter;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import appeng.api.storage.IStorageChannel;
|
||||
import appeng.api.storage.data.IAEStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.me.cache.SecurityCache;
|
||||
import net.minecraft.network.Packet;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -45,19 +46,24 @@ public class NetworkInventoryHandler<T extends IAEStack<T>> implements IMEInvent
|
||||
private final IStorageChannel<T> myChannel;
|
||||
private final SecurityCache security;
|
||||
private final NavigableMap<Integer, List<IMEInventoryHandler<T>>> priorityInventory;
|
||||
private final NavigableMap<Integer, List<IMEInventoryHandler<T>>> stickyPriorityInventory;
|
||||
private int myPass = 0;
|
||||
|
||||
public NetworkInventoryHandler(final IStorageChannel<T> chan, final SecurityCache security) {
|
||||
this.myChannel = chan;
|
||||
this.security = security;
|
||||
this.priorityInventory = new TreeMap<>(PRIORITY_SORTER);
|
||||
this.stickyPriorityInventory = new TreeMap<>(PRIORITY_SORTER);
|
||||
}
|
||||
|
||||
public void addNewStorage(final IMEInventoryHandler<T> h) {
|
||||
final int priority = h.getPriority();
|
||||
List<IMEInventoryHandler<T>> list = this.priorityInventory.get(priority);
|
||||
if (list == null) {
|
||||
this.priorityInventory.put(priority, list = new ArrayList<>());
|
||||
|
||||
final List<IMEInventoryHandler<T>> list;
|
||||
if (h.isSticky()) {
|
||||
list = this.stickyPriorityInventory.computeIfAbsent(priority, $ -> new ArrayList<>());
|
||||
} else {
|
||||
list = this.priorityInventory.computeIfAbsent(priority, $ -> new ArrayList<>());
|
||||
}
|
||||
|
||||
list.add(h);
|
||||
@@ -74,6 +80,25 @@ public class NetworkInventoryHandler<T extends IAEStack<T>> implements IMEInvent
|
||||
return input;
|
||||
}
|
||||
|
||||
boolean stickyInventoryFound = false;
|
||||
// For this pass we do return input if the item is able to go into a sticky inventory. We NEVER want to try and
|
||||
// insert the item into a non-sticky inventory if it could already go into a sticky inventory.
|
||||
for (final List<IMEInventoryHandler<T>> stickyInvList : this.stickyPriorityInventory.values()) {
|
||||
Iterator<IMEInventoryHandler<T>> ii = stickyInvList.iterator();
|
||||
while (ii.hasNext() && input != null) {
|
||||
final IMEInventoryHandler<T> inv = ii.next();
|
||||
if (inv.validForPass(1) && inv.canAccept(input) && (inv.isPrioritized(input) || inv.extractItems(input, Actionable.SIMULATE, src) != null)) {
|
||||
input = inv.injectItems(input, type, src);
|
||||
stickyInventoryFound = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (stickyInventoryFound) {
|
||||
this.surface(this, type);
|
||||
return input;
|
||||
}
|
||||
|
||||
for (final List<IMEInventoryHandler<T>> invList : this.priorityInventory.values()) {
|
||||
Iterator<IMEInventoryHandler<T>> ii = invList.iterator();
|
||||
while (ii.hasNext() && input != null) {
|
||||
@@ -186,6 +211,16 @@ public class NetworkInventoryHandler<T extends IAEStack<T>> implements IMEInvent
|
||||
}
|
||||
}
|
||||
|
||||
for (List<IMEInventoryHandler<T>> invList : this.stickyPriorityInventory.descendingMap().values()) {
|
||||
final Iterator<IMEInventoryHandler<T>> jj = invList.iterator();
|
||||
while (jj.hasNext() && output.getStackSize() < req) {
|
||||
final IMEInventoryHandler<T> inv = jj.next();
|
||||
|
||||
request.setStackSize(req - output.getStackSize());
|
||||
output.add(inv.extractItems(request, mode, src));
|
||||
}
|
||||
}
|
||||
|
||||
this.surface(this, mode);
|
||||
|
||||
if (output.getStackSize() <= 0) {
|
||||
@@ -201,15 +236,21 @@ public class NetworkInventoryHandler<T extends IAEStack<T>> implements IMEInvent
|
||||
return out;
|
||||
}
|
||||
|
||||
// for (Entry<Integer, IMEInventoryHandler<T>> h : priorityInventory.entries())
|
||||
for (final List<IMEInventoryHandler<T>> i : this.priorityInventory.values()) {
|
||||
out = iterateInventories(out, priorityInventory);
|
||||
out = iterateInventories(out, stickyPriorityInventory);
|
||||
|
||||
this.surface(this, Actionable.SIMULATE);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
private IItemList<T> iterateInventories(IItemList<T> out, final NavigableMap<Integer, List<IMEInventoryHandler<T>>> map) {
|
||||
for (final List<IMEInventoryHandler<T>> i : map.values()) {
|
||||
for (final IMEInventoryHandler<T> j : i) {
|
||||
out = j.getAvailableItems(out);
|
||||
}
|
||||
}
|
||||
|
||||
this.surface(this, Actionable.SIMULATE);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ public abstract class UpgradeInventory extends AppEngInternalInventory implement
|
||||
private int patternExpansionUpgrades = 0;
|
||||
private int magnetUpgrades = 0;
|
||||
private int quantumUpgrades = 0;
|
||||
private int stickyUpgrades = 0;
|
||||
|
||||
public UpgradeInventory(final IAEAppEngInventory parent, final int s) {
|
||||
super(null, s, 1);
|
||||
@@ -85,6 +86,8 @@ public abstract class UpgradeInventory extends AppEngInternalInventory implement
|
||||
return this.magnetUpgrades;
|
||||
case QUANTUM_LINK:
|
||||
return this.quantumUpgrades;
|
||||
case STICKY:
|
||||
return this.stickyUpgrades;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -94,7 +97,7 @@ public abstract class UpgradeInventory extends AppEngInternalInventory implement
|
||||
|
||||
private void updateUpgradeInfo() {
|
||||
this.cached = true;
|
||||
this.patternExpansionUpgrades = this.inverterUpgrades = this.capacityUpgrades = this.redstoneUpgrades = this.speedUpgrades = this.fuzzyUpgrades = this.craftingUpgrades = magnetUpgrades = quantumUpgrades = 0;
|
||||
this.patternExpansionUpgrades = this.inverterUpgrades = this.capacityUpgrades = this.redstoneUpgrades = this.speedUpgrades = this.fuzzyUpgrades = this.craftingUpgrades = magnetUpgrades = quantumUpgrades = stickyUpgrades = 0;
|
||||
|
||||
for (final ItemStack is : this) {
|
||||
if (is == null || is.getItem() == Items.AIR || !(is.getItem() instanceof IUpgradeModule)) {
|
||||
@@ -129,6 +132,10 @@ public abstract class UpgradeInventory extends AppEngInternalInventory implement
|
||||
break;
|
||||
case QUANTUM_LINK:
|
||||
this.quantumUpgrades++;
|
||||
break;
|
||||
case STICKY:
|
||||
this.stickyUpgrades++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -143,6 +150,7 @@ public abstract class UpgradeInventory extends AppEngInternalInventory implement
|
||||
this.patternExpansionUpgrades = Math.min(this.patternExpansionUpgrades, this.getMaxInstalled(Upgrades.PATTERN_EXPANSION));
|
||||
this.magnetUpgrades = Math.min(this.magnetUpgrades, this.getMaxInstalled(Upgrades.MAGNET));
|
||||
this.quantumUpgrades = Math.min(this.quantumUpgrades, this.getMaxInstalled(Upgrades.QUANTUM_LINK));
|
||||
this.stickyUpgrades = Math.min(this.stickyUpgrades, this.getMaxInstalled(Upgrades.STICKY));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -111,8 +111,8 @@ public class PartOreDicStorageBus extends PartStorageBus {
|
||||
this.handler.setBaseAccess((AccessRestriction) this.getConfigManager().getSetting(Settings.ACCESS));
|
||||
this.handler.setWhitelist(this.getInstalledUpgrades(Upgrades.INVERTER) > 0 ? IncludeExclude.BLACKLIST : IncludeExclude.WHITELIST);
|
||||
this.handler.setPriority(this.priority);
|
||||
|
||||
this.handler.setPartitionList(this.getPriorityList());
|
||||
this.handler.setStorageFilter((StorageFilter) this.getConfigManager().getSetting(Settings.STORAGE_FILTER));
|
||||
|
||||
if (inv instanceof IBaseMonitor) {
|
||||
if (((AccessRestriction) ((ConfigManager) this.getConfigManager()).getSetting(Settings.ACCESS)).hasPermission(AccessRestriction.READ)) {
|
||||
@@ -165,9 +165,7 @@ public class PartOreDicStorageBus extends PartStorageBus {
|
||||
this.oreExp = oreMatch;
|
||||
|
||||
this.priorityList = new OreDictPriorityList<>(OreHelper.INSTANCE.getMatchingOre(oreExp), oreExp);
|
||||
if (this.handler != null) {
|
||||
handler.setPartitionList(this.priorityList);
|
||||
}
|
||||
this.resetCache(true);
|
||||
this.getHost().markForSave();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,6 +80,7 @@ import net.minecraftforge.common.capabilities.CapabilityInject;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
@@ -113,6 +114,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
|
||||
this.getConfigManager().registerSetting(Settings.ACCESS, AccessRestriction.READ_WRITE);
|
||||
this.getConfigManager().registerSetting(Settings.FUZZY_MODE, FuzzyMode.IGNORE_ALL);
|
||||
this.getConfigManager().registerSetting(Settings.STORAGE_FILTER, StorageFilter.EXTRACTABLE_ONLY);
|
||||
this.getConfigManager().registerSetting(Settings.STICKY_MODE, YesNo.NO);
|
||||
this.mySrc = new MachineSource(this);
|
||||
}
|
||||
|
||||
@@ -194,7 +196,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
|
||||
return super.getInventoryByName(name);
|
||||
}
|
||||
|
||||
private void resetCache(final boolean fullReset) {
|
||||
protected void resetCache(final boolean fullReset) {
|
||||
if (this.getHost() == null || this.getHost().getTile() == null || this.getHost().getTile().getWorld() == null || this.getHost().getTile().getWorld().isRemote) {
|
||||
return;
|
||||
}
|
||||
@@ -220,11 +222,13 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
|
||||
@Override
|
||||
public void postChange(final IBaseMonitor<IAEItemStack> monitor, final Iterable<IAEItemStack> change, final IActionSource source) {
|
||||
if (this.getProxy().isActive()) {
|
||||
var filteredChanges = this.filterChanges(change);
|
||||
|
||||
AccessRestriction currentAccess = (AccessRestriction) ((ConfigManager) this.getConfigManager()).getSetting(Settings.ACCESS);
|
||||
if (readOncePass) {
|
||||
readOncePass = false;
|
||||
try {
|
||||
this.getProxy().getStorage().postAlterationOfStoredItems(AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class), change, mySrc);
|
||||
this.getProxy().getStorage().postAlterationOfStoredItems(AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class), filteredChanges, mySrc);
|
||||
} catch (final GridAccessException e) {
|
||||
// :(
|
||||
}
|
||||
@@ -234,7 +238,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this.getProxy().getStorage().postAlterationOfStoredItems(AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class), change, source);
|
||||
this.getProxy().getStorage().postAlterationOfStoredItems(AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class), filteredChanges, source);
|
||||
} catch (final GridAccessException e) {
|
||||
// :(
|
||||
}
|
||||
@@ -315,7 +319,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
|
||||
return TickRateModulation.SLEEP;
|
||||
}
|
||||
|
||||
private void resetCache() {
|
||||
protected void resetCache() {
|
||||
final boolean fullReset = this.resetCacheLogic == 2;
|
||||
this.resetCacheLogic = 0;
|
||||
|
||||
@@ -456,6 +460,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
|
||||
this.handler.setBaseAccess((AccessRestriction) this.getConfigManager().getSetting(Settings.ACCESS));
|
||||
this.handler.setWhitelist(this.getInstalledUpgrades(Upgrades.INVERTER) > 0 ? IncludeExclude.BLACKLIST : IncludeExclude.WHITELIST);
|
||||
this.handler.setPriority(this.priority);
|
||||
this.handler.setStorageFilter((StorageFilter) this.getConfigManager().getSetting(Settings.STORAGE_FILTER));
|
||||
|
||||
final IItemList<IAEItemStack> priorityList = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class).createList();
|
||||
|
||||
@@ -467,6 +472,10 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
|
||||
}
|
||||
}
|
||||
|
||||
if (this.getInstalledUpgrades(Upgrades.STICKY) > 0) {
|
||||
this.handler.setSticky(true);
|
||||
}
|
||||
|
||||
if (this.getInstalledUpgrades(Upgrades.FUZZY) > 0) {
|
||||
this.handler.setPartitionList(new FuzzyPriorityList<>(priorityList, (FuzzyMode) this.getConfigManager().getSetting(Settings.FUZZY_MODE)));
|
||||
} else {
|
||||
@@ -566,4 +575,26 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
|
||||
public GuiBridge getGuiBridge() {
|
||||
return GuiBridge.GUI_STORAGEBUS;
|
||||
}
|
||||
|
||||
// TODO: 1/28/2024 Unify both methods.
|
||||
/**
|
||||
* Filters the changes to only include items that pass the storage filter.
|
||||
* Optimally, this should be handled by the underlying monitor.
|
||||
*
|
||||
* @see appeng.fluids.parts.PartFluidStorageBus#filterChanges
|
||||
*/
|
||||
protected Iterable<IAEItemStack> filterChanges(Iterable<IAEItemStack> change) {
|
||||
var storageFilter = this.getConfigManager().getSetting(Settings.STORAGE_FILTER);
|
||||
if (storageFilter == StorageFilter.EXTRACTABLE_ONLY && handler != null) {
|
||||
var filteredList = new ArrayList<IAEItemStack>();
|
||||
for (final IAEItemStack stack : change) {
|
||||
if (this.handler.passesBlackOrWhitelist(stack)) {
|
||||
filteredList.add(stack);
|
||||
}
|
||||
}
|
||||
|
||||
return filteredList;
|
||||
}
|
||||
return change;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
|
||||
|
||||
public class ServerHelper extends CommonHelper {
|
||||
@@ -167,4 +168,17 @@ public class ServerHelper extends CommonHelper {
|
||||
public boolean isActionKey(ActionKey key, int pressedKeyCode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityPlayer getPlayerByUUID(UUID uuid) {
|
||||
if (!Platform.isClient()) {
|
||||
final MinecraftServer server = FMLCommonHandler.instance().getMinecraftServerInstance();
|
||||
|
||||
if (server != null) {
|
||||
return server.getPlayerList().getPlayerByUUID(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,6 +178,12 @@ public class TileIOPort extends AENetworkInvTile implements IUpgradeableHost, IC
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void gridChanged() {
|
||||
super.gridChanged();
|
||||
updateTask();
|
||||
}
|
||||
|
||||
public void updateRedstoneState() {
|
||||
final YesNo currentState = this.world.getRedstonePowerFromNeighbors(this.pos) != 0 ? YesNo.YES : YesNo.NO;
|
||||
if (this.lastRedstoneState != currentState) {
|
||||
|
||||
@@ -253,6 +253,7 @@ gui.appliedenergistics2.Renamer=Custom Name: (Enter to set)
|
||||
gui.appliedenergistics2.Nothing=Nothing
|
||||
gui.appliedenergistics2.CraftingToastDone=Crafting Done!
|
||||
gui.appliedenergistics2.CraftingToastCancelled=Crafting Cancelled!
|
||||
gui.appliedenergistics2.Sticky=Sticky
|
||||
|
||||
// GUI Tooltips
|
||||
gui.tooltips.appliedenergistics2.Stash=Store Items
|
||||
@@ -524,6 +525,7 @@ item.appliedenergistics2.material.silicon_print.name=Printed Silicon
|
||||
item.appliedenergistics2.material.name_press.name=Inscriber Name Press
|
||||
item.appliedenergistics2.material.sky_dust.name=Sky Stone Dust
|
||||
item.appliedenergistics2.material.card_crafting.name=Crafting Card
|
||||
item.appliedenergistics2.material.card_sticky.name=Sticky Card
|
||||
|
||||
item.appliedenergistics2.multi_part.annihilation_plane.name=ME Annihilation Plane
|
||||
item.appliedenergistics2.multi_part.fluid_annihilation_plane.name=ME Fluid Annihilation Plane
|
||||
|
||||
@@ -253,6 +253,7 @@ gui.appliedenergistics2.Renamer=自定义名称(按下Enter以设定)
|
||||
gui.appliedenergistics2.Nothing=无
|
||||
gui.appliedenergistics2.CraftingToastDone=合成已完成!
|
||||
gui.appliedenergistics2.CraftingToastCancelled=合成已取消!
|
||||
gui.appliedenergistics2.Sticky=粘滞
|
||||
|
||||
// GUI Tooltips
|
||||
gui.tooltips.appliedenergistics2.Stash=存储物品
|
||||
@@ -524,6 +525,7 @@ item.appliedenergistics2.material.silicon_print.name=硅板
|
||||
item.appliedenergistics2.material.name_press.name=名称压印模板
|
||||
item.appliedenergistics2.material.sky_dust.name=陨石粉
|
||||
item.appliedenergistics2.material.card_crafting.name=合成卡
|
||||
item.appliedenergistics2.material.card_sticky.name=粘滞卡
|
||||
|
||||
item.appliedenergistics2.multi_part.annihilation_plane.name=ME破坏面板
|
||||
item.appliedenergistics2.multi_part.fluid_annihilation_plane.name=ME流体破坏面板
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "item/generated",
|
||||
"textures": {
|
||||
"layer0": "appliedenergistics2:items/material_card_sticky"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"conditions": [
|
||||
{
|
||||
"type": "forge:and",
|
||||
"values": [
|
||||
{
|
||||
"type": "appliedenergistics2:material_exists",
|
||||
"material": "material.card_sticky"
|
||||
},
|
||||
{
|
||||
"type": "appliedenergistics2:material_exists",
|
||||
"material": "material.basic_card"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"type": "appliedenergistics2:part",
|
||||
"part": "material.card_sticky"
|
||||
},
|
||||
"type": "appliedenergistics2:part_shapeless",
|
||||
"ingredients": [
|
||||
{
|
||||
"item": "minecraft:slime_ball"
|
||||
},
|
||||
{
|
||||
"type": "appliedenergistics2:part",
|
||||
"part": "material.basic_card"
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 448 B |
Reference in New Issue
Block a user