mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2024-12-14 12:10:30 +00:00
Merge pull request #1485 from cc-tweaked/feature/turtle-upgrade-ui
Allow changing turtle upgrades from the GUI
This commit is contained in:
commit
36b9f4ec55
@ -26,9 +26,11 @@ public class TurtleScreen extends AbstractComputerScreen<TurtleMenu> {
|
||||
private static final ResourceLocation BACKGROUND_NORMAL = new ResourceLocation(ComputerCraftAPI.MOD_ID, "textures/gui/turtle_normal.png");
|
||||
private static final ResourceLocation BACKGROUND_ADVANCED = new ResourceLocation(ComputerCraftAPI.MOD_ID, "textures/gui/turtle_advanced.png");
|
||||
|
||||
private static final int TEX_WIDTH = 254;
|
||||
private static final int TEX_WIDTH = 278;
|
||||
private static final int TEX_HEIGHT = 217;
|
||||
|
||||
private static final int FULL_TEX_SIZE = 512;
|
||||
|
||||
public TurtleScreen(TurtleMenu container, Inventory player, Component title) {
|
||||
super(container, player, title, BORDER);
|
||||
|
||||
@ -45,16 +47,16 @@ public class TurtleScreen extends AbstractComputerScreen<TurtleMenu> {
|
||||
protected void renderBg(PoseStack transform, float partialTicks, int mouseX, int mouseY) {
|
||||
var advanced = family == ComputerFamily.ADVANCED;
|
||||
RenderSystem.setShaderTexture(0, advanced ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL);
|
||||
blit(transform, leftPos + AbstractComputerMenu.SIDEBAR_WIDTH, topPos, 0, 0, TEX_WIDTH, TEX_HEIGHT);
|
||||
blit(transform, leftPos + AbstractComputerMenu.SIDEBAR_WIDTH, topPos, 0, 0, 0, TEX_WIDTH, TEX_HEIGHT, FULL_TEX_SIZE, FULL_TEX_SIZE);
|
||||
|
||||
// Render selected slot
|
||||
var slot = getMenu().getSelectedSlot();
|
||||
if (slot >= 0) {
|
||||
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
var slotX = slot % 4;
|
||||
var slotY = slot / 4;
|
||||
blit(transform,
|
||||
leftPos + TURTLE_START_X - 2 + slotX * 18, topPos + PLAYER_START_Y - 2 + slotY * 18,
|
||||
0, 217, 24, 24
|
||||
leftPos + TURTLE_START_X - 2 + slotX * 18, topPos + PLAYER_START_Y - 2 + slotY * 18, 0,
|
||||
0, 217, 24, 24, FULL_TEX_SIZE, FULL_TEX_SIZE
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,34 @@
|
||||
// SPDX-FileCopyrightText: 2023 The CC: Tweaked Developers
|
||||
//
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package dan200.computercraft.data.client;
|
||||
|
||||
import dan200.computercraft.data.DataProviders;
|
||||
import dan200.computercraft.shared.turtle.inventory.UpgradeSlot;
|
||||
import net.minecraft.client.renderer.texture.atlas.SpriteSources;
|
||||
import net.minecraft.client.renderer.texture.atlas.sources.SingleFile;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.PackType;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* A version of {@link DataProviders} which relies on client-side classes.
|
||||
* <p>
|
||||
* This is called from {@link DataProviders#add(DataProviders.GeneratorSink)}.
|
||||
*/
|
||||
public final class ClientDataProviders {
|
||||
private ClientDataProviders() {
|
||||
}
|
||||
|
||||
public static void add(DataProviders.GeneratorSink generator) {
|
||||
generator.addFromCodec("Block atlases", PackType.CLIENT_RESOURCES, "atlases", SpriteSources.FILE_CODEC, out -> {
|
||||
out.accept(new ResourceLocation("blocks"), List.of(
|
||||
new SingleFile(UpgradeSlot.LEFT_UPGRADE, Optional.empty()),
|
||||
new SingleFile(UpgradeSlot.RIGHT_UPGRADE, Optional.empty())
|
||||
));
|
||||
});
|
||||
}
|
||||
}
|
@ -4,16 +4,20 @@
|
||||
|
||||
package dan200.computercraft.data;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import net.minecraft.data.DataProvider;
|
||||
import net.minecraft.data.PackOutput;
|
||||
import net.minecraft.data.loot.LootTableProvider.SubProviderEntry;
|
||||
import net.minecraft.data.models.BlockModelGenerators;
|
||||
import net.minecraft.data.models.ItemModelGenerators;
|
||||
import net.minecraft.data.tags.TagsProvider;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.PackType;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
@ -37,11 +41,22 @@ public final class DataProviders {
|
||||
generator.models(BlockModelProvider::addBlockModels, ItemModelProvider::addItemModels);
|
||||
|
||||
generator.add(out -> new LanguageProvider(out, turtleUpgrades, pocketUpgrades));
|
||||
|
||||
// Unfortunately we rely on some client-side classes in this code. We just load in the client side data provider
|
||||
// and invoke that.
|
||||
try {
|
||||
Class.forName("dan200.computercraft.data.client.ClientDataProviders")
|
||||
.getMethod("add", GeneratorSink.class).invoke(null, generator);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
interface GeneratorSink {
|
||||
public interface GeneratorSink {
|
||||
<T extends DataProvider> T add(DataProvider.Factory<T> factory);
|
||||
|
||||
<T> void addFromCodec(String name, PackType type, String directory, Codec<T> codec, Consumer<BiConsumer<ResourceLocation, T>> output);
|
||||
|
||||
void lootTable(List<SubProviderEntry> tables);
|
||||
|
||||
TagsProvider<Block> blockTags(Consumer<TagProvider.TagConsumer<Block>> tags);
|
||||
|
@ -7,7 +7,6 @@ package dan200.computercraft.shared.container;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.ContainerHelper;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
/**
|
||||
@ -16,24 +15,6 @@ import net.minecraft.world.item.ItemStack;
|
||||
public interface BasicContainer extends Container {
|
||||
NonNullList<ItemStack> getContents();
|
||||
|
||||
@Override
|
||||
default int getMaxStackSize() {
|
||||
return 64;
|
||||
}
|
||||
|
||||
@Override
|
||||
default void startOpen(Player player) {
|
||||
}
|
||||
|
||||
@Override
|
||||
default void stopOpen(Player player) {
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean canPlaceItem(int slot, ItemStack stack) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
default int getContainerSize() {
|
||||
return getContents().size();
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
package dan200.computercraft.shared.turtle.inventory;
|
||||
|
||||
import dan200.computercraft.api.turtle.TurtleSide;
|
||||
import dan200.computercraft.shared.ModRegistry;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||
@ -29,12 +30,13 @@ public final class TurtleMenu extends AbstractComputerMenu {
|
||||
public static final int PLAYER_START_Y = 134;
|
||||
public static final int TURTLE_START_X = SIDEBAR_WIDTH + 175;
|
||||
public static final int PLAYER_START_X = SIDEBAR_WIDTH + BORDER;
|
||||
public static final int UPGRADE_START_X = SIDEBAR_WIDTH + 254;
|
||||
|
||||
private final ContainerData data;
|
||||
|
||||
private TurtleMenu(
|
||||
int id, Predicate<Player> canUse, ComputerFamily family, @Nullable ServerComputer computer, @Nullable ComputerContainerData menuData,
|
||||
Inventory playerInventory, Container inventory, ContainerData data
|
||||
Inventory playerInventory, Container inventory, Container turtleUpgrades, ContainerData data
|
||||
) {
|
||||
super(ModRegistry.Menus.TURTLE.get(), id, canUse, family, computer, menuData);
|
||||
this.data = data;
|
||||
@ -58,19 +60,24 @@ public final class TurtleMenu extends AbstractComputerMenu {
|
||||
for (var x = 0; x < 9; x++) {
|
||||
addSlot(new Slot(playerInventory, x, PLAYER_START_X + x * 18, PLAYER_START_Y + 3 * 18 + 5));
|
||||
}
|
||||
|
||||
// Turtle upgrades
|
||||
addSlot(new UpgradeSlot(turtleUpgrades, TurtleSide.LEFT, 0, UPGRADE_START_X, PLAYER_START_Y + 1));
|
||||
addSlot(new UpgradeSlot(turtleUpgrades, TurtleSide.RIGHT, 1, UPGRADE_START_X, PLAYER_START_Y + 1 + 18));
|
||||
}
|
||||
|
||||
public static TurtleMenu ofBrain(int id, Inventory player, TurtleBrain turtle) {
|
||||
return new TurtleMenu(
|
||||
// Laziness in turtle.getOwner() is important here!
|
||||
id, p -> turtle.getOwner().stillValid(p), turtle.getFamily(), turtle.getOwner().createServerComputer(), null,
|
||||
player, turtle.getInventory(), (SingleContainerData) turtle::getSelectedSlot
|
||||
player, turtle.getInventory(), new UpgradeContainer(turtle), (SingleContainerData) turtle::getSelectedSlot
|
||||
);
|
||||
}
|
||||
|
||||
public static TurtleMenu ofMenuData(int id, Inventory player, ComputerContainerData data) {
|
||||
return new TurtleMenu(
|
||||
id, x -> true, data.family(), null, data, player, new SimpleContainer(TurtleBlockEntity.INVENTORY_SIZE), new SimpleContainerData(1)
|
||||
id, x -> true, data.family(), null, data,
|
||||
player, new SimpleContainer(TurtleBlockEntity.INVENTORY_SIZE), new SimpleContainer(2), new SimpleContainerData(1)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,108 @@
|
||||
// SPDX-FileCopyrightText: 2023 The CC: Tweaked Developers
|
||||
//
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package dan200.computercraft.shared.turtle.inventory;
|
||||
|
||||
import dan200.computercraft.api.turtle.ITurtleAccess;
|
||||
import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
||||
import dan200.computercraft.api.turtle.TurtleSide;
|
||||
import dan200.computercraft.impl.TurtleUpgrades;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A fake {@link Container} which exposes the {@linkplain ITurtleAccess#getUpgrade(TurtleSide) upgrades} a turtle has.
|
||||
*
|
||||
* @see TurtleMenu
|
||||
* @see UpgradeSlot
|
||||
*/
|
||||
class UpgradeContainer implements Container {
|
||||
private static final int SIZE = 2;
|
||||
|
||||
private final ITurtleAccess turtle;
|
||||
|
||||
private final List<ITurtleUpgrade> lastUpgrade = Arrays.asList(null, null);
|
||||
private final NonNullList<ItemStack> lastStack = NonNullList.withSize(2, ItemStack.EMPTY);
|
||||
|
||||
UpgradeContainer(ITurtleAccess turtle) {
|
||||
this.turtle = turtle;
|
||||
}
|
||||
|
||||
private TurtleSide getSide(int slot) {
|
||||
return switch (slot) {
|
||||
case 0 -> TurtleSide.LEFT;
|
||||
case 1 -> TurtleSide.RIGHT;
|
||||
default -> throw new IllegalArgumentException("Invalid slot " + slot);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItem(int slot) {
|
||||
var upgrade = turtle.getUpgrade(getSide(slot));
|
||||
|
||||
// We don't want to return getCraftingItem directly here, as consumers may mutate the stack (they shouldn't!,
|
||||
// but if they do it's a pain to track down). To avoid recreating the stack each tick, we maintain a simple
|
||||
// cache.
|
||||
if (upgrade == lastUpgrade.get(slot)) return lastStack.get(slot);
|
||||
|
||||
var stack = upgrade == null ? ItemStack.EMPTY : upgrade.getCraftingItem().copy();
|
||||
lastUpgrade.set(slot, upgrade);
|
||||
lastStack.set(slot, stack);
|
||||
return stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItem(int slot, ItemStack itemStack) {
|
||||
turtle.setUpgrade(getSide(slot), TurtleUpgrades.instance().get(itemStack));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getContainerSize() {
|
||||
return SIZE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxStackSize() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
for (var i = 0; i < SIZE; i++) {
|
||||
if (!getItem(i).isEmpty()) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeItem(int slot, int count) {
|
||||
return count <= 0 ? ItemStack.EMPTY : removeItemNoUpdate(slot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeItemNoUpdate(int slot) {
|
||||
var current = getItem(slot);
|
||||
setItem(slot, ItemStack.EMPTY);
|
||||
return current;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChanged() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stillValid(Player player) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearContent() {
|
||||
for (var i = 0; i < SIZE; i++) setItem(i, ItemStack.EMPTY);
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
// SPDX-FileCopyrightText: 2023 The CC: Tweaked Developers
|
||||
//
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package dan200.computercraft.shared.turtle.inventory;
|
||||
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import dan200.computercraft.api.ComputerCraftAPI;
|
||||
import dan200.computercraft.api.turtle.TurtleSide;
|
||||
import dan200.computercraft.impl.TurtleUpgrades;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.inventory.InventoryMenu;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* A slot in the turtle UI which holds the turtle's current upgrade.
|
||||
*
|
||||
* @see TurtleMenu
|
||||
*/
|
||||
public class UpgradeSlot extends Slot {
|
||||
public static final ResourceLocation LEFT_UPGRADE = new ResourceLocation(ComputerCraftAPI.MOD_ID, "gui/turtle_upgrade_left");
|
||||
public static final ResourceLocation RIGHT_UPGRADE = new ResourceLocation(ComputerCraftAPI.MOD_ID, "gui/turtle_upgrade_right");
|
||||
|
||||
private final TurtleSide side;
|
||||
|
||||
public UpgradeSlot(Container container, TurtleSide side, int slot, int xPos, int yPos) {
|
||||
super(container, slot, xPos, yPos);
|
||||
this.side = side;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mayPlace(ItemStack stack) {
|
||||
return TurtleUpgrades.instance().get(stack) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxStackSize() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Pair<ResourceLocation, ResourceLocation> getNoItemIcon() {
|
||||
return Pair.of(InventoryMenu.BLOCK_ATLAS, side == TurtleSide.LEFT ? LEFT_UPGRADE : RIGHT_UPGRADE);
|
||||
}
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 1004 B After Width: | Height: | Size: 1.4 KiB |
Binary file not shown.
Before Width: | Height: | Size: 983 B After Width: | Height: | Size: 1.4 KiB |
Binary file not shown.
After Width: | Height: | Size: 129 B |
@ -0,0 +1,3 @@
|
||||
SPDX-FileCopyrightText: 2023 The CC: Tweaked Developers
|
||||
|
||||
SPDX-License-Identifier: MPL-2.0
|
Binary file not shown.
After Width: | Height: | Size: 129 B |
@ -0,0 +1,3 @@
|
||||
SPDX-FileCopyrightText: 2023 The CC: Tweaked Developers
|
||||
|
||||
SPDX-License-Identifier: MPL-2.0
|
@ -119,7 +119,7 @@ loom {
|
||||
|
||||
register("data") {
|
||||
configName = "Datagen"
|
||||
server()
|
||||
client()
|
||||
|
||||
runDir("run/dataGen")
|
||||
property("cct.pretty-json")
|
||||
|
6
projects/fabric/src/generated/resources/assets/minecraft/atlases/blocks.json
generated
Normal file
6
projects/fabric/src/generated/resources/assets/minecraft/atlases/blocks.json
generated
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"sources": [
|
||||
{"type": "minecraft:single", "resource": "computercraft:gui/turtle_upgrade_left"},
|
||||
{"type": "minecraft:single", "resource": "computercraft:gui/turtle_upgrade_right"}
|
||||
]
|
||||
}
|
@ -4,21 +4,25 @@
|
||||
|
||||
package dan200.computercraft.data;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import dan200.computercraft.shared.platform.RegistryWrappers;
|
||||
import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint;
|
||||
import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator;
|
||||
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
|
||||
import net.fabricmc.fabric.api.datagen.v1.provider.FabricCodecDataProvider;
|
||||
import net.fabricmc.fabric.api.datagen.v1.provider.FabricModelProvider;
|
||||
import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider;
|
||||
import net.fabricmc.fabric.api.datagen.v1.provider.SimpleFabricLootTableProvider;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.data.CachedOutput;
|
||||
import net.minecraft.data.DataProvider;
|
||||
import net.minecraft.data.PackOutput;
|
||||
import net.minecraft.data.loot.LootTableProvider;
|
||||
import net.minecraft.data.models.BlockModelGenerators;
|
||||
import net.minecraft.data.models.ItemModelGenerators;
|
||||
import net.minecraft.data.tags.TagsProvider;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.PackType;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
@ -43,6 +47,27 @@ public class FabricDataGenerators implements DataGeneratorEntrypoint {
|
||||
return generator.addProvider(factory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void addFromCodec(String name, PackType type, String directory, Codec<T> codec, Consumer<BiConsumer<ResourceLocation, T>> output) {
|
||||
generator.addProvider((FabricDataOutput out) -> {
|
||||
var ourType = switch (type) {
|
||||
case SERVER_DATA -> PackOutput.Target.DATA_PACK;
|
||||
case CLIENT_RESOURCES -> PackOutput.Target.RESOURCE_PACK;
|
||||
};
|
||||
return new FabricCodecDataProvider<T>(out, ourType, directory, codec) {
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(BiConsumer<ResourceLocation, T> provider) {
|
||||
output.accept(provider);
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lootTable(List<LootTableProvider.SubProviderEntry> tables) {
|
||||
for (var table : tables) {
|
||||
|
6
projects/forge/src/generated/resources/assets/minecraft/atlases/blocks.json
generated
Normal file
6
projects/forge/src/generated/resources/assets/minecraft/atlases/blocks.json
generated
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"sources": [
|
||||
{"type": "minecraft:single", "resource": "computercraft:gui/turtle_upgrade_left"},
|
||||
{"type": "minecraft:single", "resource": "computercraft:gui/turtle_upgrade_right"}
|
||||
]
|
||||
}
|
@ -4,6 +4,8 @@
|
||||
|
||||
package dan200.computercraft.data;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import dan200.computercraft.api.ComputerCraftAPI;
|
||||
import dan200.computercraft.shared.platform.RegistryWrappers;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
@ -14,18 +16,24 @@ import net.minecraft.data.models.BlockModelGenerators;
|
||||
import net.minecraft.data.models.ItemModelGenerators;
|
||||
import net.minecraft.data.tags.ItemTagsProvider;
|
||||
import net.minecraft.data.tags.TagsProvider;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.PackType;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraftforge.common.data.BlockTagsProvider;
|
||||
import net.minecraftforge.common.data.ExistingFileHelper;
|
||||
import net.minecraftforge.common.data.JsonCodecProvider;
|
||||
import net.minecraftforge.data.event.GatherDataEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)
|
||||
@ -46,6 +54,15 @@ public class Generators {
|
||||
return generator.addProvider(factory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void addFromCodec(String name, PackType type, String directory, Codec<T> codec, Consumer<BiConsumer<ResourceLocation, T>> output) {
|
||||
generator.addProvider(out -> {
|
||||
Map<ResourceLocation, T> map = new HashMap<>();
|
||||
output.accept(map::put);
|
||||
return new JsonCodecProvider<>(out, existingFiles, ComputerCraftAPI.MOD_ID, JsonOps.INSTANCE, type, directory, codec, map);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lootTable(List<LootTableProvider.SubProviderEntry> tables) {
|
||||
add(out -> new LootTableProvider(out, Set.of(), tables));
|
||||
|
Loading…
Reference in New Issue
Block a user