Craft only feature
This commit is contained in:
@@ -111,6 +111,11 @@ public interface ICraftingTask {
|
|||||||
*/
|
*/
|
||||||
boolean isValid();
|
boolean isValid();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return whether the task is finished
|
||||||
|
*/
|
||||||
|
boolean isFinished();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the missing items
|
* @return the missing items
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -166,8 +166,10 @@ public interface INetworkMaster {
|
|||||||
* @param stack the stack
|
* @param stack the stack
|
||||||
* @param toSchedule the amount of tasks to schedule
|
* @param toSchedule the amount of tasks to schedule
|
||||||
* @param compare the compare value to find patterns
|
* @param compare the compare value to find patterns
|
||||||
|
* @return the crafting task created, or null if no task is created
|
||||||
*/
|
*/
|
||||||
void scheduleCraftingTask(ItemStack stack, int toSchedule, int compare);
|
@Nullable
|
||||||
|
ICraftingTask scheduleCraftingTask(ItemStack stack, int toSchedule, int compare);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a grid update packet with all the items to all clients that are watching a grid connected to this network.
|
* Sends a grid update packet with all the items to all clients that are watching a grid connected to this network.
|
||||||
|
|||||||
@@ -300,13 +300,13 @@ public class CraftingTask implements ICraftingTask {
|
|||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "\nCraftingTask{quantity=" + quantity +
|
return "\nCraftingTask{quantity=" + quantity +
|
||||||
"\n, toTake=" + toTake +
|
"\n, toTake=" + toTake +
|
||||||
"\n, toTakeFluids=" + toTakeFluids +
|
"\n, toTakeFluids=" + toTakeFluids +
|
||||||
"\n, toCraft=" + toCraft +
|
"\n, toCraft=" + toCraft +
|
||||||
"\n, toInsertItems=" + toInsertItems +
|
"\n, toInsertItems=" + toInsertItems +
|
||||||
"\n, toInsertFluids=" + toInsertFluids +
|
"\n, toInsertFluids=" + toInsertFluids +
|
||||||
"\n, mainSteps=" + mainSteps +
|
"\n, mainSteps=" + mainSteps +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -456,23 +456,23 @@ public class CraftingTask implements ICraftingTask {
|
|||||||
ICraftingMonitorElementList elements = API.instance().createCraftingMonitorElementList();
|
ICraftingMonitorElementList elements = API.instance().createCraftingMonitorElementList();
|
||||||
|
|
||||||
elements.directAdd(new CraftingMonitorElementItemRender(
|
elements.directAdd(new CraftingMonitorElementItemRender(
|
||||||
network.getCraftingTasks().indexOf(this),
|
network.getCraftingTasks().indexOf(this),
|
||||||
requested != null ? requested : pattern.getOutputs().get(0),
|
requested != null ? requested : pattern.getOutputs().get(0),
|
||||||
quantity,
|
quantity,
|
||||||
0
|
0
|
||||||
));
|
));
|
||||||
|
|
||||||
if (!missing.isEmpty()) {
|
if (!missing.isEmpty()) {
|
||||||
elements.directAdd(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.items_missing", 16));
|
elements.directAdd(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.items_missing", 16));
|
||||||
|
|
||||||
missing.getStacks().stream()
|
missing.getStacks().stream()
|
||||||
.map(stack -> new CraftingMonitorElementError(new CraftingMonitorElementItemRender(
|
.map(stack -> new CraftingMonitorElementError(new CraftingMonitorElementItemRender(
|
||||||
-1,
|
-1,
|
||||||
stack,
|
stack,
|
||||||
stack.getCount(),
|
stack.getCount(),
|
||||||
32
|
32
|
||||||
), ""))
|
), ""))
|
||||||
.forEach(elements::add);
|
.forEach(elements::add);
|
||||||
|
|
||||||
elements.commit();
|
elements.commit();
|
||||||
}
|
}
|
||||||
@@ -481,13 +481,13 @@ public class CraftingTask implements ICraftingTask {
|
|||||||
elements.directAdd(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.items_inserting", 16));
|
elements.directAdd(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.items_inserting", 16));
|
||||||
|
|
||||||
toInsertItems.stream()
|
toInsertItems.stream()
|
||||||
.map(stack -> new CraftingMonitorElementItemRender(
|
.map(stack -> new CraftingMonitorElementItemRender(
|
||||||
-1,
|
-1,
|
||||||
stack,
|
stack,
|
||||||
stack.getCount(),
|
stack.getCount(),
|
||||||
32
|
32
|
||||||
))
|
))
|
||||||
.forEach(elements::add);
|
.forEach(elements::add);
|
||||||
|
|
||||||
elements.commit();
|
elements.commit();
|
||||||
}
|
}
|
||||||
@@ -502,10 +502,10 @@ public class CraftingTask implements ICraftingTask {
|
|||||||
for (ICraftingStep step : getSteps().stream().filter(s -> !s.getPattern().isProcessing()).collect(Collectors.toList())) {
|
for (ICraftingStep step : getSteps().stream().filter(s -> !s.getPattern().isProcessing()).collect(Collectors.toList())) {
|
||||||
for (int i = 0; i < step.getPattern().getOutputs().size(); ++i) {
|
for (int i = 0; i < step.getPattern().getOutputs().size(); ++i) {
|
||||||
ICraftingMonitorElement element = new CraftingMonitorElementItemRender(
|
ICraftingMonitorElement element = new CraftingMonitorElementItemRender(
|
||||||
-1,
|
-1,
|
||||||
step.getPattern().getOutputs().get(i),
|
step.getPattern().getOutputs().get(i),
|
||||||
step.getPattern().getOutputs().get(i).getCount(),
|
step.getPattern().getOutputs().get(i).getCount(),
|
||||||
32
|
32
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!step.hasStartedProcessing() && !step.canStartProcessing(oreDictPrepped, networkFluids)) {
|
if (!step.hasStartedProcessing() && !step.canStartProcessing(oreDictPrepped, networkFluids)) {
|
||||||
@@ -525,10 +525,10 @@ public class CraftingTask implements ICraftingTask {
|
|||||||
for (ICraftingStep step : getSteps().stream().filter(s -> s.getPattern().isProcessing()).collect(Collectors.toList())) {
|
for (ICraftingStep step : getSteps().stream().filter(s -> s.getPattern().isProcessing()).collect(Collectors.toList())) {
|
||||||
for (int i = 0; i < step.getPattern().getOutputs().size(); ++i) {
|
for (int i = 0; i < step.getPattern().getOutputs().size(); ++i) {
|
||||||
ICraftingMonitorElement element = new CraftingMonitorElementItemRender(
|
ICraftingMonitorElement element = new CraftingMonitorElementItemRender(
|
||||||
-1,
|
-1,
|
||||||
step.getPattern().getOutputs().get(i),
|
step.getPattern().getOutputs().get(i),
|
||||||
step.getPattern().getOutputs().get(i).getCount(),
|
step.getPattern().getOutputs().get(i).getCount(),
|
||||||
32
|
32
|
||||||
);
|
);
|
||||||
|
|
||||||
if (step.getPattern().getContainer().getFacingTile() == null) {
|
if (step.getPattern().getContainer().getFacingTile() == null) {
|
||||||
@@ -621,7 +621,8 @@ public class CraftingTask implements ICraftingTask {
|
|||||||
return elements;
|
return elements;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isFinished() {
|
@Override
|
||||||
|
public boolean isFinished() {
|
||||||
return mainSteps.stream().allMatch(ICraftingStep::hasReceivedOutputs);
|
return mainSteps.stream().allMatch(ICraftingStep::hasReceivedOutputs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.raoulvdberge.refinedstorage.apiimpl.network.node;
|
|||||||
|
|
||||||
import com.raoulvdberge.refinedstorage.RS;
|
import com.raoulvdberge.refinedstorage.RS;
|
||||||
import com.raoulvdberge.refinedstorage.RSUtils;
|
import com.raoulvdberge.refinedstorage.RSUtils;
|
||||||
|
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask;
|
||||||
import com.raoulvdberge.refinedstorage.api.network.INetworkNodeHolder;
|
import com.raoulvdberge.refinedstorage.api.network.INetworkNodeHolder;
|
||||||
import com.raoulvdberge.refinedstorage.api.util.IComparer;
|
import com.raoulvdberge.refinedstorage.api.util.IComparer;
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||||
@@ -28,6 +29,7 @@ public class NetworkNodeExporter extends NetworkNode implements IComparable, ITy
|
|||||||
private static final String NBT_COMPARE = "Compare";
|
private static final String NBT_COMPARE = "Compare";
|
||||||
private static final String NBT_TYPE = "Type";
|
private static final String NBT_TYPE = "Type";
|
||||||
private static final String NBT_REGULATOR = "Regulator";
|
private static final String NBT_REGULATOR = "Regulator";
|
||||||
|
private static final String NBT_CRAFT_ONLY = "CraftOnly";
|
||||||
|
|
||||||
private ItemHandlerBasic itemFilters = new ItemHandlerBasic(9, new ItemHandlerListenerNetworkNode(this));
|
private ItemHandlerBasic itemFilters = new ItemHandlerBasic(9, new ItemHandlerListenerNetworkNode(this));
|
||||||
private ItemHandlerFluid fluidFilters = new ItemHandlerFluid(9, new ItemHandlerListenerNetworkNode(this));
|
private ItemHandlerFluid fluidFilters = new ItemHandlerFluid(9, new ItemHandlerListenerNetworkNode(this));
|
||||||
@@ -37,6 +39,9 @@ public class NetworkNodeExporter extends NetworkNode implements IComparable, ITy
|
|||||||
private int compare = IComparer.COMPARE_NBT | IComparer.COMPARE_DAMAGE;
|
private int compare = IComparer.COMPARE_NBT | IComparer.COMPARE_DAMAGE;
|
||||||
private int type = IType.ITEMS;
|
private int type = IType.ITEMS;
|
||||||
private boolean regulator = false;
|
private boolean regulator = false;
|
||||||
|
private boolean craftOnly = false;
|
||||||
|
private ICraftingTask[] craftOnlyTask = new ICraftingTask[9];
|
||||||
|
private Integer[] craftOnlyToExtract = new Integer[9];
|
||||||
|
|
||||||
public NetworkNodeExporter(INetworkNodeHolder holder) {
|
public NetworkNodeExporter(INetworkNodeHolder holder) {
|
||||||
super(holder);
|
super(holder);
|
||||||
@@ -57,7 +62,38 @@ public class NetworkNodeExporter extends NetworkNode implements IComparable, ITy
|
|||||||
for (int i = 0; i < itemFilters.getSlots(); ++i) {
|
for (int i = 0; i < itemFilters.getSlots(); ++i) {
|
||||||
ItemStack slot = itemFilters.getStackInSlot(i);
|
ItemStack slot = itemFilters.getStackInSlot(i);
|
||||||
|
|
||||||
if (!slot.isEmpty()) {
|
if (slot.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (craftOnly) {
|
||||||
|
if (craftOnlyTask[i] == null) {
|
||||||
|
craftOnlyTask[i] = network.scheduleCraftingTask(slot, upgrades.getItemInteractCount(), compare);
|
||||||
|
|
||||||
|
if (craftOnlyTask[i] != null) {
|
||||||
|
craftOnlyToExtract[i] = craftOnlyTask[i].getPattern().getQuantityPerRequest(slot, compare);
|
||||||
|
}
|
||||||
|
} else if (craftOnlyTask[i].isFinished() && craftOnlyTask[i].getMissing().isEmpty()) {
|
||||||
|
int toExtract = Math.min(upgrades.getItemInteractCount(), craftOnlyToExtract[i]);
|
||||||
|
|
||||||
|
ItemStack took = network.extractItem(slot, toExtract, compare, true);
|
||||||
|
|
||||||
|
if (took != null && ItemHandlerHelper.insertItem(handler, took, true).isEmpty()) {
|
||||||
|
took = network.extractItem(slot, toExtract, compare, false);
|
||||||
|
|
||||||
|
ItemHandlerHelper.insertItem(handler, took, false);
|
||||||
|
|
||||||
|
craftOnlyToExtract[i] -= toExtract;
|
||||||
|
|
||||||
|
if (craftOnlyToExtract[i] <= 0) {
|
||||||
|
craftOnlyToExtract[i] = null;
|
||||||
|
craftOnlyTask[i] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (!network.getCraftingTasks().contains(craftOnlyTask[i])) {
|
||||||
|
craftOnlyTask[i] = null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
int stackSize = upgrades.getItemInteractCount();
|
int stackSize = upgrades.getItemInteractCount();
|
||||||
|
|
||||||
boolean skipSlot = false;
|
boolean skipSlot = false;
|
||||||
@@ -189,6 +225,7 @@ public class NetworkNodeExporter extends NetworkNode implements IComparable, ITy
|
|||||||
tag.setInteger(NBT_COMPARE, compare);
|
tag.setInteger(NBT_COMPARE, compare);
|
||||||
tag.setInteger(NBT_TYPE, type);
|
tag.setInteger(NBT_TYPE, type);
|
||||||
tag.setBoolean(NBT_REGULATOR, regulator);
|
tag.setBoolean(NBT_REGULATOR, regulator);
|
||||||
|
tag.setBoolean(NBT_CRAFT_ONLY, craftOnly);
|
||||||
|
|
||||||
RSUtils.writeItems(itemFilters, 0, tag);
|
RSUtils.writeItems(itemFilters, 0, tag);
|
||||||
RSUtils.writeItems(fluidFilters, 2, tag);
|
RSUtils.writeItems(fluidFilters, 2, tag);
|
||||||
@@ -212,6 +249,10 @@ public class NetworkNodeExporter extends NetworkNode implements IComparable, ITy
|
|||||||
regulator = tag.getBoolean(NBT_REGULATOR);
|
regulator = tag.getBoolean(NBT_REGULATOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tag.hasKey(NBT_CRAFT_ONLY)) {
|
||||||
|
craftOnly = tag.getBoolean(NBT_CRAFT_ONLY);
|
||||||
|
}
|
||||||
|
|
||||||
RSUtils.readItems(itemFilters, 0, tag);
|
RSUtils.readItems(itemFilters, 0, tag);
|
||||||
RSUtils.readItems(fluidFilters, 2, tag);
|
RSUtils.readItems(fluidFilters, 2, tag);
|
||||||
}
|
}
|
||||||
@@ -257,4 +298,12 @@ public class NetworkNodeExporter extends NetworkNode implements IComparable, ITy
|
|||||||
public IItemHandler getFilterInventory() {
|
public IItemHandler getFilterInventory() {
|
||||||
return getType() == IType.ITEMS ? itemFilters : fluidFilters;
|
return getType() == IType.ITEMS ? itemFilters : fluidFilters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isCraftOnly() {
|
||||||
|
return craftOnly;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCraftOnly(boolean craftOnly) {
|
||||||
|
this.craftOnly = craftOnly;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,7 @@ package com.raoulvdberge.refinedstorage.gui;
|
|||||||
|
|
||||||
import com.raoulvdberge.refinedstorage.api.util.IComparer;
|
import com.raoulvdberge.refinedstorage.api.util.IComparer;
|
||||||
import com.raoulvdberge.refinedstorage.container.ContainerExporter;
|
import com.raoulvdberge.refinedstorage.container.ContainerExporter;
|
||||||
import com.raoulvdberge.refinedstorage.gui.sidebutton.SideButtonCompare;
|
import com.raoulvdberge.refinedstorage.gui.sidebutton.*;
|
||||||
import com.raoulvdberge.refinedstorage.gui.sidebutton.SideButtonRedstoneMode;
|
|
||||||
import com.raoulvdberge.refinedstorage.gui.sidebutton.SideButtonRegulator;
|
|
||||||
import com.raoulvdberge.refinedstorage.gui.sidebutton.SideButtonType;
|
|
||||||
import com.raoulvdberge.refinedstorage.tile.TileExporter;
|
import com.raoulvdberge.refinedstorage.tile.TileExporter;
|
||||||
|
|
||||||
public class GuiExporter extends GuiBase {
|
public class GuiExporter extends GuiBase {
|
||||||
@@ -23,7 +20,8 @@ public class GuiExporter extends GuiBase {
|
|||||||
addSideButton(new SideButtonCompare(this, TileExporter.COMPARE, IComparer.COMPARE_NBT));
|
addSideButton(new SideButtonCompare(this, TileExporter.COMPARE, IComparer.COMPARE_NBT));
|
||||||
addSideButton(new SideButtonCompare(this, TileExporter.COMPARE, IComparer.COMPARE_OREDICT));
|
addSideButton(new SideButtonCompare(this, TileExporter.COMPARE, IComparer.COMPARE_OREDICT));
|
||||||
|
|
||||||
addSideButton(new SideButtonRegulator(this));
|
addSideButton(new SideButtonExporterRegulator(this));
|
||||||
|
addSideButton(new SideButtonExporterCraftOnly(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package com.raoulvdberge.refinedstorage.gui.sidebutton;
|
||||||
|
|
||||||
|
import com.raoulvdberge.refinedstorage.gui.GuiBase;
|
||||||
|
import com.raoulvdberge.refinedstorage.tile.TileExporter;
|
||||||
|
import com.raoulvdberge.refinedstorage.tile.data.TileDataManager;
|
||||||
|
import net.minecraft.util.text.TextFormatting;
|
||||||
|
|
||||||
|
public class SideButtonExporterCraftOnly extends SideButton {
|
||||||
|
public SideButtonExporterCraftOnly(GuiBase gui) {
|
||||||
|
super(gui);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void drawButtonIcon(int x, int y) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTooltip() {
|
||||||
|
return TextFormatting.GREEN + GuiBase.t("sidebutton.refinedstorage:exporter.craft_only") + TextFormatting.RESET + "\n" + GuiBase.t(TileExporter.CRAFT_ONLY.getValue() ? "gui.yes" : "gui.no");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed() {
|
||||||
|
TileDataManager.setParameter(TileExporter.CRAFT_ONLY, !TileExporter.CRAFT_ONLY.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,8 +5,8 @@ import com.raoulvdberge.refinedstorage.tile.TileExporter;
|
|||||||
import com.raoulvdberge.refinedstorage.tile.data.TileDataManager;
|
import com.raoulvdberge.refinedstorage.tile.data.TileDataManager;
|
||||||
import net.minecraft.util.text.TextFormatting;
|
import net.minecraft.util.text.TextFormatting;
|
||||||
|
|
||||||
public class SideButtonRegulator extends SideButton {
|
public class SideButtonExporterRegulator extends SideButton {
|
||||||
public SideButtonRegulator(GuiBase gui) {
|
public SideButtonExporterRegulator(GuiBase gui) {
|
||||||
super(gui);
|
super(gui);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -438,7 +438,7 @@ public class TileController extends TileBase implements INetworkMaster, IRedston
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void scheduleCraftingTask(ItemStack stack, int toSchedule, int compare) {
|
public ICraftingTask scheduleCraftingTask(ItemStack stack, int toSchedule, int compare) {
|
||||||
for (ICraftingTask task : getCraftingTasks()) {
|
for (ICraftingTask task : getCraftingTasks()) {
|
||||||
for (ItemStack output : task.getPattern().getOutputs()) {
|
for (ItemStack output : task.getPattern().getOutputs()) {
|
||||||
if (API.instance().getComparer().isEqual(output, stack, compare)) {
|
if (API.instance().getComparer().isEqual(output, stack, compare)) {
|
||||||
@@ -459,8 +459,12 @@ public class TileController extends TileBase implements INetworkMaster, IRedston
|
|||||||
addCraftingTask(task);
|
addCraftingTask(task);
|
||||||
|
|
||||||
markCraftingMonitorForUpdate();
|
markCraftingMonitorForUpdate();
|
||||||
|
|
||||||
|
return task;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -55,10 +55,24 @@ public class TileExporter extends TileNode {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
public static final TileDataParameter<Boolean> CRAFT_ONLY = new TileDataParameter<Boolean>(DataSerializers.BOOLEAN, false, new ITileDataProducer<Boolean, TileExporter>() {
|
||||||
|
@Override
|
||||||
|
public Boolean getValue(TileExporter tile) {
|
||||||
|
return ((NetworkNodeExporter) tile.getNode()).isCraftOnly();
|
||||||
|
}
|
||||||
|
}, new ITileDataConsumer<Boolean, TileExporter>() {
|
||||||
|
@Override
|
||||||
|
public void setValue(TileExporter tile, Boolean value) {
|
||||||
|
((NetworkNodeExporter) tile.getNode()).setCraftOnly(value);
|
||||||
|
tile.getNode().markDirty();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
public TileExporter() {
|
public TileExporter() {
|
||||||
dataManager.addWatchedParameter(COMPARE);
|
dataManager.addWatchedParameter(COMPARE);
|
||||||
dataManager.addWatchedParameter(TYPE);
|
dataManager.addWatchedParameter(TYPE);
|
||||||
dataManager.addWatchedParameter(REGULATOR);
|
dataManager.addWatchedParameter(REGULATOR);
|
||||||
|
dataManager.addWatchedParameter(CRAFT_ONLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -161,6 +161,7 @@ sidebutton.refinedstorage:access_type.1=Insert only
|
|||||||
sidebutton.refinedstorage:access_type.2=Extract only
|
sidebutton.refinedstorage:access_type.2=Extract only
|
||||||
|
|
||||||
sidebutton.refinedstorage:exporter.regulator=Regulator Mode
|
sidebutton.refinedstorage:exporter.regulator=Regulator Mode
|
||||||
|
sidebutton.refinedstorage:exporter.craft_only=Craft-only Mode
|
||||||
|
|
||||||
block.refinedstorage:controller.0.name=Controller
|
block.refinedstorage:controller.0.name=Controller
|
||||||
block.refinedstorage:controller.1.name=Creative Controller
|
block.refinedstorage:controller.1.name=Creative Controller
|
||||||
|
|||||||
Reference in New Issue
Block a user