Made the creative portable grid work in block form, fix extraction of portable grid energy
This commit is contained in:
@@ -33,7 +33,7 @@ public class StorageCacheItemPortable implements IStorageCache<ItemStack> {
|
|||||||
portableGrid.getStorage().getStacks().forEach(list::add);
|
portableGrid.getStorage().getStacks().forEach(list::add);
|
||||||
}
|
}
|
||||||
|
|
||||||
portableGrid.getWatchers().forEach(this::sendTo);
|
portableGrid.getWatchers().forEach(this::sendUpdateTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -67,7 +67,7 @@ public class StorageCacheItemPortable implements IStorageCache<ItemStack> {
|
|||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendTo(EntityPlayer player) {
|
public void sendUpdateTo(EntityPlayer player) {
|
||||||
RS.INSTANCE.network.sendTo(new MessageGridItemUpdate(buf -> {
|
RS.INSTANCE.network.sendTo(new MessageGridItemUpdate(buf -> {
|
||||||
buf.writeInt(list.getStacks().size());
|
buf.writeInt(list.getStacks().size());
|
||||||
|
|
||||||
|
@@ -4,6 +4,8 @@ import com.raoulvdberge.refinedstorage.RS;
|
|||||||
import com.raoulvdberge.refinedstorage.RSGui;
|
import com.raoulvdberge.refinedstorage.RSGui;
|
||||||
import com.raoulvdberge.refinedstorage.item.ItemBlockPortableGrid;
|
import com.raoulvdberge.refinedstorage.item.ItemBlockPortableGrid;
|
||||||
import com.raoulvdberge.refinedstorage.tile.grid.portable.TilePortableGrid;
|
import com.raoulvdberge.refinedstorage.tile.grid.portable.TilePortableGrid;
|
||||||
|
import net.minecraft.block.properties.PropertyEnum;
|
||||||
|
import net.minecraft.block.state.BlockStateContainer;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
@@ -21,6 +23,8 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class BlockPortableGrid extends BlockBase {
|
public class BlockPortableGrid extends BlockBase {
|
||||||
|
public static final PropertyEnum TYPE = PropertyEnum.create("type", PortableGridType.class);
|
||||||
|
|
||||||
public BlockPortableGrid() {
|
public BlockPortableGrid() {
|
||||||
super("portable_grid");
|
super("portable_grid");
|
||||||
}
|
}
|
||||||
@@ -76,6 +80,23 @@ public class BlockPortableGrid extends BlockBase {
|
|||||||
return drops;
|
return drops;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected BlockStateContainer createBlockState() {
|
||||||
|
return createBlockStateBuilder()
|
||||||
|
.add(TYPE)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBlockState getStateFromMeta(int meta) {
|
||||||
|
return getDefaultState().withProperty(TYPE, meta == 0 ? PortableGridType.NORMAL : PortableGridType.CREATIVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMetaFromState(IBlockState state) {
|
||||||
|
return state.getValue(TYPE) == PortableGridType.NORMAL ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, EnumFacing side, float hitX, float hitY, float hitZ) {
|
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, EnumFacing side, float hitX, float hitY, float hitZ) {
|
||||||
if (!world.isRemote) {
|
if (!world.isRemote) {
|
||||||
|
@@ -0,0 +1,30 @@
|
|||||||
|
package com.raoulvdberge.refinedstorage.block;
|
||||||
|
|
||||||
|
import net.minecraft.util.IStringSerializable;
|
||||||
|
|
||||||
|
public enum PortableGridType implements IStringSerializable {
|
||||||
|
NORMAL(0, "normal"),
|
||||||
|
CREATIVE(1, "creative");
|
||||||
|
|
||||||
|
private int id;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
PortableGridType(int id, String name) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
@@ -1,11 +1,10 @@
|
|||||||
package com.raoulvdberge.refinedstorage.integration.forgeenergy;
|
package com.raoulvdberge.refinedstorage.integration.forgeenergy;
|
||||||
|
|
||||||
import com.raoulvdberge.refinedstorage.RS;
|
|
||||||
import net.minecraftforge.energy.EnergyStorage;
|
import net.minecraftforge.energy.EnergyStorage;
|
||||||
|
|
||||||
public class ControllerEnergyForge extends EnergyStorage {
|
public class EnergyForge extends EnergyStorage {
|
||||||
public ControllerEnergyForge() {
|
public EnergyForge(int capacity) {
|
||||||
super(RS.INSTANCE.config.controllerCapacity, Integer.MAX_VALUE, 0);
|
super(capacity, capacity, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int extractEnergyInternal(int maxExtract) {
|
public int extractEnergyInternal(int maxExtract) {
|
@@ -4,10 +4,10 @@ import net.darkhax.tesla.api.ITeslaConsumer;
|
|||||||
import net.darkhax.tesla.api.ITeslaHolder;
|
import net.darkhax.tesla.api.ITeslaHolder;
|
||||||
import net.minecraftforge.energy.IEnergyStorage;
|
import net.minecraftforge.energy.IEnergyStorage;
|
||||||
|
|
||||||
public class ControllerEnergyTesla implements ITeslaHolder, ITeslaConsumer {
|
public class EnergyTesla implements ITeslaHolder, ITeslaConsumer {
|
||||||
private IEnergyStorage energy;
|
private IEnergyStorage energy;
|
||||||
|
|
||||||
public ControllerEnergyTesla(IEnergyStorage energy) {
|
public EnergyTesla(IEnergyStorage energy) {
|
||||||
this.energy = energy;
|
this.energy = energy;
|
||||||
}
|
}
|
||||||
|
|
@@ -246,6 +246,7 @@ public class ProxyClient extends ProxyCommon {
|
|||||||
});
|
});
|
||||||
|
|
||||||
ModelLoader.setCustomStateMapper(RSBlocks.CONTROLLER, new StateMap.Builder().ignore(BlockController.TYPE).build());
|
ModelLoader.setCustomStateMapper(RSBlocks.CONTROLLER, new StateMap.Builder().ignore(BlockController.TYPE).build());
|
||||||
|
ModelLoader.setCustomStateMapper(RSBlocks.PORTABLE_GRID, new StateMap.Builder().ignore(BlockPortableGrid.TYPE).build());
|
||||||
|
|
||||||
ModelLoader.setCustomMeshDefinition(Item.getItemFromBlock(RSBlocks.CONTROLLER), stack -> {
|
ModelLoader.setCustomMeshDefinition(Item.getItemFromBlock(RSBlocks.CONTROLLER), stack -> {
|
||||||
int energy = stack.getItemDamage() == ControllerType.CREATIVE.getId() ? 7 : TileController.getEnergyScaled(ItemBlockController.getEnergyStored(stack), ItemBlockController.getEnergyCapacity(stack), 7);
|
int energy = stack.getItemDamage() == ControllerType.CREATIVE.getId() ? 7 : TileController.getEnergyScaled(ItemBlockController.getEnergyStored(stack), ItemBlockController.getEnergyCapacity(stack), 7);
|
||||||
|
@@ -36,8 +36,8 @@ import com.raoulvdberge.refinedstorage.block.GridType;
|
|||||||
import com.raoulvdberge.refinedstorage.container.ContainerCraftingMonitor;
|
import com.raoulvdberge.refinedstorage.container.ContainerCraftingMonitor;
|
||||||
import com.raoulvdberge.refinedstorage.container.ContainerGrid;
|
import com.raoulvdberge.refinedstorage.container.ContainerGrid;
|
||||||
import com.raoulvdberge.refinedstorage.container.ContainerReaderWriter;
|
import com.raoulvdberge.refinedstorage.container.ContainerReaderWriter;
|
||||||
import com.raoulvdberge.refinedstorage.integration.forgeenergy.ControllerEnergyForge;
|
import com.raoulvdberge.refinedstorage.integration.forgeenergy.EnergyForge;
|
||||||
import com.raoulvdberge.refinedstorage.integration.tesla.ControllerEnergyTesla;
|
import com.raoulvdberge.refinedstorage.integration.tesla.EnergyTesla;
|
||||||
import com.raoulvdberge.refinedstorage.integration.tesla.IntegrationTesla;
|
import com.raoulvdberge.refinedstorage.integration.tesla.IntegrationTesla;
|
||||||
import com.raoulvdberge.refinedstorage.network.*;
|
import com.raoulvdberge.refinedstorage.network.*;
|
||||||
import com.raoulvdberge.refinedstorage.proxy.CapabilityNetworkNodeProxy;
|
import com.raoulvdberge.refinedstorage.proxy.CapabilityNetworkNodeProxy;
|
||||||
@@ -159,8 +159,8 @@ public class TileController extends TileBase implements ITickable, INetworkMaste
|
|||||||
|
|
||||||
private Map<String, IReaderWriterChannel> readerWriterChannels = new HashMap<>();
|
private Map<String, IReaderWriterChannel> readerWriterChannels = new HashMap<>();
|
||||||
|
|
||||||
private ControllerEnergyForge energy = new ControllerEnergyForge();
|
private EnergyForge energy = new EnergyForge(RS.INSTANCE.config.controllerCapacity);
|
||||||
private ControllerEnergyTesla energyTesla;
|
private EnergyTesla energyTesla;
|
||||||
|
|
||||||
private int lastEnergyDisplay;
|
private int lastEnergyDisplay;
|
||||||
|
|
||||||
@@ -180,11 +180,11 @@ public class TileController extends TileBase implements ITickable, INetworkMaste
|
|||||||
dataManager.addParameter(NODES);
|
dataManager.addParameter(NODES);
|
||||||
|
|
||||||
if (IntegrationTesla.isLoaded()) {
|
if (IntegrationTesla.isLoaded()) {
|
||||||
this.energyTesla = new ControllerEnergyTesla(energy);
|
this.energyTesla = new EnergyTesla(energy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ControllerEnergyForge getEnergy() {
|
public EnergyForge getEnergy() {
|
||||||
return energy;
|
return energy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -108,11 +108,6 @@ public class PortableGrid implements IGrid, IPortableGrid {
|
|||||||
this.player = player;
|
this.player = player;
|
||||||
this.stack = stack;
|
this.stack = stack;
|
||||||
|
|
||||||
// Only extract when we can
|
|
||||||
if (isActive()) {
|
|
||||||
drainEnergy(RS.INSTANCE.config.portableGridOpenUsage);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.sortingType = ItemWirelessGrid.getSortingType(stack);
|
this.sortingType = ItemWirelessGrid.getSortingType(stack);
|
||||||
this.sortingDirection = ItemWirelessGrid.getSortingDirection(stack);
|
this.sortingDirection = ItemWirelessGrid.getSortingDirection(stack);
|
||||||
this.searchBoxMode = ItemWirelessGrid.getSearchBoxMode(stack);
|
this.searchBoxMode = ItemWirelessGrid.getSearchBoxMode(stack);
|
||||||
@@ -128,6 +123,8 @@ public class PortableGrid implements IGrid, IPortableGrid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
RSUtils.readItems(disk, 4, stack.getTagCompound());
|
RSUtils.readItems(disk, 4, stack.getTagCompound());
|
||||||
|
|
||||||
|
drainEnergy(RS.INSTANCE.config.portableGridOpenUsage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemStack getStack() {
|
public ItemStack getStack() {
|
||||||
|
@@ -11,11 +11,15 @@ import com.raoulvdberge.refinedstorage.apiimpl.network.node.NetworkNodeGrid;
|
|||||||
import com.raoulvdberge.refinedstorage.apiimpl.network.node.diskdrive.NetworkNodeDiskDrive;
|
import com.raoulvdberge.refinedstorage.apiimpl.network.node.diskdrive.NetworkNodeDiskDrive;
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.storage.StorageCacheItemPortable;
|
import com.raoulvdberge.refinedstorage.apiimpl.storage.StorageCacheItemPortable;
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.storage.StorageDiskItemPortable;
|
import com.raoulvdberge.refinedstorage.apiimpl.storage.StorageDiskItemPortable;
|
||||||
|
import com.raoulvdberge.refinedstorage.block.BlockPortableGrid;
|
||||||
import com.raoulvdberge.refinedstorage.block.GridType;
|
import com.raoulvdberge.refinedstorage.block.GridType;
|
||||||
|
import com.raoulvdberge.refinedstorage.block.PortableGridType;
|
||||||
import com.raoulvdberge.refinedstorage.gui.grid.GuiGrid;
|
import com.raoulvdberge.refinedstorage.gui.grid.GuiGrid;
|
||||||
|
import com.raoulvdberge.refinedstorage.integration.forgeenergy.EnergyForge;
|
||||||
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerBase;
|
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerBase;
|
||||||
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerFilter;
|
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerFilter;
|
||||||
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerListenerTile;
|
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerListenerTile;
|
||||||
|
import com.raoulvdberge.refinedstorage.item.ItemBlockPortableGrid;
|
||||||
import com.raoulvdberge.refinedstorage.item.ItemWirelessGrid;
|
import com.raoulvdberge.refinedstorage.item.ItemWirelessGrid;
|
||||||
import com.raoulvdberge.refinedstorage.item.filter.Filter;
|
import com.raoulvdberge.refinedstorage.item.filter.Filter;
|
||||||
import com.raoulvdberge.refinedstorage.item.filter.FilterTab;
|
import com.raoulvdberge.refinedstorage.item.filter.FilterTab;
|
||||||
@@ -34,7 +38,6 @@ import net.minecraft.network.datasync.DataSerializers;
|
|||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraftforge.common.capabilities.Capability;
|
import net.minecraftforge.common.capabilities.Capability;
|
||||||
import net.minecraftforge.energy.CapabilityEnergy;
|
import net.minecraftforge.energy.CapabilityEnergy;
|
||||||
import net.minecraftforge.energy.EnergyStorage;
|
|
||||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
|
|
||||||
@@ -53,8 +56,7 @@ public class TilePortableGrid extends TileBase implements IGrid, IPortableGrid {
|
|||||||
|
|
||||||
private static final String NBT_ENERGY = "Energy";
|
private static final String NBT_ENERGY = "Energy";
|
||||||
|
|
||||||
// @todo: make non-extractable
|
private EnergyForge energyStorage = new EnergyForge(3200);
|
||||||
private EnergyStorage energyStorage = new EnergyStorage(3200);
|
|
||||||
|
|
||||||
private int sortingType;
|
private int sortingType;
|
||||||
private int sortingDirection;
|
private int sortingDirection;
|
||||||
@@ -62,6 +64,8 @@ public class TilePortableGrid extends TileBase implements IGrid, IPortableGrid {
|
|||||||
private int tabSelected;
|
private int tabSelected;
|
||||||
private int size;
|
private int size;
|
||||||
|
|
||||||
|
private PortableGridType type;
|
||||||
|
|
||||||
private List<Filter> filters = new ArrayList<>();
|
private List<Filter> filters = new ArrayList<>();
|
||||||
private List<FilterTab> tabs = new ArrayList<>();
|
private List<FilterTab> tabs = new ArrayList<>();
|
||||||
private ItemHandlerFilter filter = new ItemHandlerFilter(filters, tabs, new ItemHandlerListenerTile(this));
|
private ItemHandlerFilter filter = new ItemHandlerFilter(filters, tabs, new ItemHandlerListenerTile(this));
|
||||||
@@ -105,6 +109,14 @@ public class TilePortableGrid extends TileBase implements IGrid, IPortableGrid {
|
|||||||
dataManager.addWatchedParameter(ENERGY_STORED);
|
dataManager.addWatchedParameter(ENERGY_STORED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PortableGridType getPortableType() {
|
||||||
|
if (type == null && getWorld().getBlockState(pos).getBlock() == RSBlocks.PORTABLE_GRID) {
|
||||||
|
this.type = (PortableGridType) getWorld().getBlockState(pos).getValue(BlockPortableGrid.TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return type == null ? PortableGridType.NORMAL : type;
|
||||||
|
}
|
||||||
|
|
||||||
public void onPassItemContext(ItemStack stack) {
|
public void onPassItemContext(ItemStack stack) {
|
||||||
this.sortingType = ItemWirelessGrid.getSortingType(stack);
|
this.sortingType = ItemWirelessGrid.getSortingType(stack);
|
||||||
this.sortingDirection = ItemWirelessGrid.getSortingDirection(stack);
|
this.sortingDirection = ItemWirelessGrid.getSortingDirection(stack);
|
||||||
@@ -112,7 +124,7 @@ public class TilePortableGrid extends TileBase implements IGrid, IPortableGrid {
|
|||||||
this.tabSelected = ItemWirelessGrid.getTabSelected(stack);
|
this.tabSelected = ItemWirelessGrid.getTabSelected(stack);
|
||||||
this.size = ItemWirelessGrid.getSize(stack);
|
this.size = ItemWirelessGrid.getSize(stack);
|
||||||
|
|
||||||
energyStorage.receiveEnergy(stack.getCapability(CapabilityEnergy.ENERGY, null).getEnergyStored(), false);
|
this.energyStorage.setEnergyStored(stack.getCapability(CapabilityEnergy.ENERGY, null).getEnergyStored());
|
||||||
|
|
||||||
for (int i = 0; i < 4; ++i) {
|
for (int i = 0; i < 4; ++i) {
|
||||||
RSUtils.readItems(filter, i, stack.getTagCompound());
|
RSUtils.readItems(filter, i, stack.getTagCompound());
|
||||||
@@ -128,7 +140,7 @@ public class TilePortableGrid extends TileBase implements IGrid, IPortableGrid {
|
|||||||
storage.writeToNBT();
|
storage.writeToNBT();
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemStack stack = new ItemStack(RSBlocks.PORTABLE_GRID);
|
ItemStack stack = new ItemStack(RSBlocks.PORTABLE_GRID, 1, getPortableType() == PortableGridType.NORMAL ? ItemBlockPortableGrid.TYPE_NORMAL : ItemBlockPortableGrid.TYPE_CREATIVE);
|
||||||
|
|
||||||
stack.setTagCompound(new NBTTagCompound());
|
stack.setTagCompound(new NBTTagCompound());
|
||||||
|
|
||||||
@@ -328,10 +340,9 @@ public class TilePortableGrid extends TileBase implements IGrid, IPortableGrid {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isActive() {
|
public boolean isActive() {
|
||||||
int stored = !world.isRemote ? energyStorage.getEnergyStored() : ENERGY_STORED.getValue();
|
int stored = !getWorld().isRemote ? energyStorage.getEnergyStored() : ENERGY_STORED.getValue();
|
||||||
|
|
||||||
// @todo: handle creative
|
if (getPortableType() != PortableGridType.CREATIVE && RS.INSTANCE.config.portableGridUsesEnergy && stored <= RS.INSTANCE.config.portableGridOpenUsage) {
|
||||||
if (RS.INSTANCE.config.portableGridUsesEnergy && stored <= RS.INSTANCE.config.portableGridOpenUsage) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,9 +366,8 @@ public class TilePortableGrid extends TileBase implements IGrid, IPortableGrid {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drainEnergy(int energy) {
|
public void drainEnergy(int energy) {
|
||||||
// @todo: handle creative
|
if (RS.INSTANCE.config.portableGridUsesEnergy && getPortableType() != PortableGridType.CREATIVE) {
|
||||||
if (RS.INSTANCE.config.portableGridUsesEnergy) {
|
energyStorage.extractEnergyInternal(energy);
|
||||||
energyStorage.extractEnergy(energy, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,12 +418,12 @@ public class TilePortableGrid extends TileBase implements IGrid, IPortableGrid {
|
|||||||
tabSelected = tag.getInteger(NetworkNodeGrid.NBT_TAB_SELECTED);
|
tabSelected = tag.getInteger(NetworkNodeGrid.NBT_TAB_SELECTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tag.hasKey(NBT_ENERGY)) {
|
|
||||||
energyStorage.receiveEnergy(tag.getInteger(NBT_ENERGY), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
RSUtils.readItems(disk, 0, tag);
|
RSUtils.readItems(disk, 0, tag);
|
||||||
RSUtils.readItems(filter, 1, tag);
|
RSUtils.readItems(filter, 1, tag);
|
||||||
|
|
||||||
|
if (tag.hasKey(NBT_ENERGY)) {
|
||||||
|
energyStorage.setEnergyStored(tag.getInteger(NBT_ENERGY));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -432,6 +442,8 @@ public class TilePortableGrid extends TileBase implements IGrid, IPortableGrid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onOpened(EntityPlayer player) {
|
public void onOpened(EntityPlayer player) {
|
||||||
cache.sendTo(player);
|
cache.sendUpdateTo(player);
|
||||||
|
|
||||||
|
drainEnergy(RS.INSTANCE.config.portableGridOpenUsage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user