use of mekanism.common.tile.base.TileEntityMekanism in project Mekanism by mekanism.
the class RecipeUpgradeData method getSupportedTypes.
@Nonnull
static Set<RecipeUpgradeType> getSupportedTypes(ItemStack stack) {
// TODO: Add more types of data that can be transferred such as side configs, auto sort, bucket mode, dumping mode
if (stack.isEmpty()) {
return Collections.emptySet();
}
Set<RecipeUpgradeType> supportedTypes = EnumSet.noneOf(RecipeUpgradeType.class);
Item item = stack.getItem();
TileEntityMekanism tile = null;
if (item instanceof BlockItem) {
Block block = ((BlockItem) item).getBlock();
if (block instanceof IHasTileEntity) {
TileEntity tileEntity = ((IHasTileEntity<?>) block).getTileType().create();
if (tileEntity instanceof TileEntityMekanism) {
tile = (TileEntityMekanism) tileEntity;
}
}
if (Attribute.has(block, AttributeUpgradeSupport.class)) {
supportedTypes.add(RecipeUpgradeType.UPGRADE);
}
}
if (stack.getCapability(Capabilities.STRICT_ENERGY_CAPABILITY).isPresent() || tile != null && tile.handles(SubstanceType.ENERGY)) {
// If we are for a block that handles energy, or we have an energy handler capability
supportedTypes.add(RecipeUpgradeType.ENERGY);
}
if (FluidUtil.getFluidHandler(stack).isPresent() || tile != null && tile.handles(SubstanceType.FLUID)) {
// If we are for a block that handles fluid, or we have a fluid handler capability
supportedTypes.add(RecipeUpgradeType.FLUID);
}
if (stack.getCapability(Capabilities.GAS_HANDLER_CAPABILITY).isPresent() || tile != null && tile.handles(SubstanceType.GAS)) {
// If we are for a block that handles gas, or we have a gas handler capability
supportedTypes.add(RecipeUpgradeType.GAS);
}
if (stack.getCapability(Capabilities.INFUSION_HANDLER_CAPABILITY).isPresent() || tile != null && tile.handles(SubstanceType.INFUSION)) {
// If we are for a block that handles infusion, or we have an infusion handler capability
supportedTypes.add(RecipeUpgradeType.INFUSION);
}
if (stack.getCapability(Capabilities.PIGMENT_HANDLER_CAPABILITY).isPresent() || tile != null && tile.handles(SubstanceType.PIGMENT)) {
// If we are for a block that handles pigment, or we have a pigment handler capability
supportedTypes.add(RecipeUpgradeType.PIGMENT);
}
if (stack.getCapability(Capabilities.SLURRY_HANDLER_CAPABILITY).isPresent() || tile != null && tile.handles(SubstanceType.SLURRY)) {
// If we are for a block that handles slurry, or we have a slurry handler capability
supportedTypes.add(RecipeUpgradeType.SLURRY);
}
if (item instanceof ISustainedInventory || tile != null && tile.persistInventory()) {
supportedTypes.add(RecipeUpgradeType.ITEM);
}
if (item instanceof ISecurityItem) {
supportedTypes.add(RecipeUpgradeType.SECURITY);
}
if (item instanceof IQIODriveItem) {
supportedTypes.add(RecipeUpgradeType.QIO_DRIVE);
}
return supportedTypes;
}
use of mekanism.common.tile.base.TileEntityMekanism in project Mekanism by mekanism.
the class BaseBlockLootTables method dropSelfWithContents.
protected void dropSelfWithContents(List<IBlockProvider> blockProviders) {
// For example, when writing this we added dump mode for chemical tanks to getting transferred to the item
for (IBlockProvider blockProvider : blockProviders) {
Block block = blockProvider.getBlock();
if (skipBlock(block)) {
continue;
}
CopyNbt.Builder nbtBuilder = CopyNbt.copyData(Source.BLOCK_ENTITY);
boolean hasData = false;
boolean hasContents = false;
@Nullable TileEntity tile = null;
if (block instanceof IHasTileEntity) {
tile = ((IHasTileEntity<?>) block).getTileType().create();
}
if (tile instanceof IFrequencyHandler && ((IFrequencyHandler) tile).getFrequencyComponent().hasCustomFrequencies()) {
nbtBuilder.copy(NBTConstants.COMPONENT_FREQUENCY, NBTConstants.MEK_DATA + "." + NBTConstants.COMPONENT_FREQUENCY);
hasData = true;
}
if (Attribute.has(block, AttributeSecurity.class)) {
// TODO: Should we just save the entire security component?
nbtBuilder.copy(NBTConstants.COMPONENT_SECURITY + "." + NBTConstants.OWNER_UUID, NBTConstants.MEK_DATA + "." + NBTConstants.OWNER_UUID);
nbtBuilder.copy(NBTConstants.COMPONENT_SECURITY + "." + NBTConstants.SECURITY_MODE, NBTConstants.MEK_DATA + "." + NBTConstants.SECURITY_MODE);
hasData = true;
}
if (Attribute.has(block, AttributeUpgradeSupport.class)) {
nbtBuilder.copy(NBTConstants.COMPONENT_UPGRADE, NBTConstants.MEK_DATA + "." + NBTConstants.COMPONENT_UPGRADE);
hasData = true;
}
if (tile instanceof ISideConfiguration) {
nbtBuilder.copy(NBTConstants.COMPONENT_CONFIG, NBTConstants.MEK_DATA + "." + NBTConstants.COMPONENT_CONFIG);
nbtBuilder.copy(NBTConstants.COMPONENT_EJECTOR, NBTConstants.MEK_DATA + "." + NBTConstants.COMPONENT_EJECTOR);
hasData = true;
}
if (tile instanceof ISustainedData) {
Set<Entry<String, String>> remapEntries = ((ISustainedData) tile).getTileDataRemap().entrySet();
for (Entry<String, String> remapEntry : remapEntries) {
nbtBuilder.copy(remapEntry.getKey(), NBTConstants.MEK_DATA + "." + remapEntry.getValue());
}
if (!remapEntries.isEmpty()) {
hasData = true;
}
}
if (Attribute.has(block, AttributeRedstone.class)) {
nbtBuilder.copy(NBTConstants.CONTROL_TYPE, NBTConstants.MEK_DATA + "." + NBTConstants.CONTROL_TYPE);
hasData = true;
}
if (tile instanceof TileEntityMekanism) {
TileEntityMekanism tileEntity = (TileEntityMekanism) tile;
for (SubstanceType type : EnumUtils.SUBSTANCES) {
if (tileEntity.handles(type) && !type.getContainers(tileEntity).isEmpty()) {
nbtBuilder.copy(type.getContainerTag(), NBTConstants.MEK_DATA + "." + type.getContainerTag());
hasData = true;
if (type != SubstanceType.ENERGY && type != SubstanceType.HEAT) {
hasContents = true;
}
}
}
}
if (Attribute.has(block, AttributeInventory.class)) {
// then only copy the slots if we actually have any slots because otherwise maybe something just went wrong
if (!(tile instanceof IItemHandler) || ((IItemHandler) tile).getSlots() > 0) {
// If we don't actually handle saving an inventory (such as the quantum entangloporter, don't actually add it as something to copy)
if (!(tile instanceof TileEntityMekanism) || ((TileEntityMekanism) tile).persistInventory()) {
nbtBuilder.copy(NBTConstants.ITEMS, NBTConstants.MEK_DATA + "." + NBTConstants.ITEMS);
hasData = true;
hasContents = true;
}
}
}
if (block instanceof BlockCardboardBox) {
// TODO: Do this better so that it doesn't have to be as hard coded to being a cardboard box
nbtBuilder.copy(NBTConstants.DATA, NBTConstants.MEK_DATA + "." + NBTConstants.DATA);
hasData = true;
}
if (!hasData) {
// To keep the json as clean as possible don't bother even registering a blank accept function if we have no
// persistent data that we want to copy. Also log a warning so that we don't have to attempt to check against
// that block
dropSelf(block);
} else {
add(block, LootTable.lootTable().withPool(applyExplosionCondition(hasContents, LootPool.lootPool().name("main").setRolls(ConstantRange.exactly(1)).add(ItemLootEntry.lootTableItem(block).apply(nbtBuilder)))));
}
}
}
use of mekanism.common.tile.base.TileEntityMekanism in project Mekanism by mekanism.
the class BlockMekanism method setPlacedBy.
@Override
public void setPlacedBy(@Nonnull World world, @Nonnull BlockPos pos, @Nonnull BlockState state, @Nullable LivingEntity placer, @Nonnull ItemStack stack) {
super.setPlacedBy(world, pos, state, placer, stack);
TileEntityMekanism tile = WorldUtils.getTileEntity(TileEntityMekanism.class, world, pos);
if (tile == null) {
return;
}
if (tile.supportsRedstone()) {
tile.redstone = world.hasNeighborSignal(pos);
}
tile.onPlace();
// Handle item
Item item = stack.getItem();
setTileData(world, pos, state, placer, stack, tile);
// but there is a good chance a lot of this stuff has no real reason to need to be set on the client side at all
if (!world.isClientSide && tile.getFrequencyComponent().hasCustomFrequencies()) {
tile.getFrequencyComponent().read(ItemDataUtils.getDataMap(stack));
}
if (tile instanceof TileEntitySecurityDesk && placer != null) {
tile.getSecurity().setOwnerUUID(placer.getUUID());
}
if (item instanceof ISecurityItem && tile.hasSecurity()) {
ISecurityItem securityItem = (ISecurityItem) item;
tile.setSecurityMode(securityItem.getSecurity(stack));
UUID ownerUUID = securityItem.getOwnerUUID(stack);
if (ownerUUID != null) {
tile.getSecurity().setOwnerUUID(ownerUUID);
} else if (placer != null) {
tile.getSecurity().setOwnerUUID(placer.getUUID());
if (!world.isClientSide) {
// If the machine doesn't already have an owner, make sure we portray this
Mekanism.packetHandler.sendToAll(new PacketSecurityUpdate(placer.getUUID(), null));
}
}
}
if (tile.supportsUpgrades()) {
// The read method validates that data is stored
tile.getComponent().read(ItemDataUtils.getDataMap(stack));
}
if (tile instanceof ISideConfiguration) {
ISideConfiguration config = (ISideConfiguration) tile;
// The read methods validate that data is stored
config.getConfig().read(ItemDataUtils.getDataMap(stack));
config.getEjector().read(ItemDataUtils.getDataMap(stack));
}
for (SubstanceType type : EnumUtils.SUBSTANCES) {
if (type.canHandle(tile)) {
DataHandlerUtils.readContainers(type.getContainers(tile), ItemDataUtils.getList(stack, type.getContainerTag()));
}
}
if (tile instanceof ISustainedData && stack.hasTag()) {
((ISustainedData) tile).readSustainedData(stack);
}
if (tile.supportsRedstone() && ItemDataUtils.hasData(stack, NBTConstants.CONTROL_TYPE, NBT.TAG_INT)) {
tile.setControlType(RedstoneControl.byIndexStatic(ItemDataUtils.getInt(stack, NBTConstants.CONTROL_TYPE)));
}
if (item instanceof ISustainedInventory && tile.persistInventory()) {
tile.setInventory(((ISustainedInventory) item).getInventory(stack));
}
}
use of mekanism.common.tile.base.TileEntityMekanism in project Mekanism by mekanism.
the class PacketGeneratorsGuiButtonPress method handle.
@Override
public void handle(NetworkEvent.Context context) {
ServerPlayerEntity player = context.getSender();
if (player != null) {
// If we are on the server (the only time we should be receiving this packet), let forge handle switching the Gui
TileEntityMekanism tile = WorldUtils.getTileEntity(TileEntityMekanism.class, player.level, tilePosition);
if (tile != null) {
INamedContainerProvider provider = tileButton.getProvider(tile, extra);
if (provider != null) {
// Ensure valid data
NetworkHooks.openGui(player, provider, buf -> {
buf.writeBlockPos(tilePosition);
buf.writeVarInt(extra);
});
}
}
}
}
use of mekanism.common.tile.base.TileEntityMekanism in project Mekanism by mekanism.
the class FluidRecipeData method applyToStack.
@Override
public boolean applyToStack(ItemStack stack) {
if (fluidTanks.isEmpty()) {
return true;
}
Item item = stack.getItem();
Optional<IFluidHandlerItem> capability = FluidUtil.getFluidHandler(stack).resolve();
List<IExtendedFluidTank> fluidTanks = new ArrayList<>();
if (capability.isPresent()) {
IFluidHandlerItem fluidHandler = capability.get();
for (int i = 0; i < fluidHandler.getTanks(); i++) {
int tank = i;
fluidTanks.add(BasicFluidTank.create(fluidHandler.getTankCapacity(tank), fluid -> fluidHandler.isFluidValid(tank, fluid), null));
}
} else if (item instanceof BlockItem) {
TileEntityMekanism tile = getTileFromBlock(((BlockItem) item).getBlock());
if (tile == null || !tile.handles(SubstanceType.FLUID)) {
// Something went wrong
return false;
}
for (int i = 0; i < tile.getTanks(); i++) {
int tank = i;
fluidTanks.add(BasicFluidTank.create(tile.getTankCapacity(tank), fluid -> tile.isFluidValid(tank, fluid), null));
}
} else {
return false;
}
if (fluidTanks.isEmpty()) {
// We don't actually have any tanks in the output
return true;
}
// TODO: Improve the logic used so that it tries to batch similar types of fluids together first
// and maybe make it try multiple slot combinations
IMekanismFluidHandler outputHandler = new IMekanismFluidHandler() {
@Nonnull
@Override
public List<IExtendedFluidTank> getFluidTanks(@Nullable Direction side) {
return fluidTanks;
}
@Override
public void onContentsChanged() {
}
};
boolean hasData = false;
for (IExtendedFluidTank fluidTank : this.fluidTanks) {
if (!fluidTank.isEmpty()) {
if (!outputHandler.insertFluid(fluidTank.getFluid(), Action.EXECUTE).isEmpty()) {
// If we have a remainder something failed so bail
return false;
}
hasData = true;
}
}
if (hasData) {
// We managed to transfer it all into valid slots, so save it to the stack
ItemDataUtils.setList(stack, NBTConstants.FLUID_TANKS, DataHandlerUtils.writeContainers(fluidTanks));
}
return true;
}
Aggregations