mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-27 07:27:15 +01:00
No anvil, no problem
- Clipboards can now be used to manually write to Display Boards and Nixie Tubes - Clipboards can now be used as Material Checklists in the Schematicannon - Added Clipboard recipe and clearing recipe
This commit is contained in:
parent
9dd5cde745
commit
ef07383a74
16 changed files with 320 additions and 50 deletions
|
@ -567,7 +567,7 @@ bf2b0310500213ff853c748c236eb5d01f61658e assets/create/blockstates/yellow_toolbo
|
|||
7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json
|
||||
b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json
|
||||
0f4e5a2fc58580df5b156fdac438ddeb6b57e386 assets/create/lang/en_ud.json
|
||||
85d790bedbdc65bb6e6377edcc63e7b00455e879 assets/create/lang/en_us.json
|
||||
2502e2934b3e39763f5619e1522b0b6f98bc26d7 assets/create/lang/en_us.json
|
||||
487a511a01b2a4531fb672f917922312db78f958 assets/create/models/block/acacia_window.json
|
||||
b48060cba1a382f373a05bf0039054053eccf076 assets/create/models/block/acacia_window_pane_noside.json
|
||||
3066db1bf03cffa1a9c7fbacf47ae586632f4eb3 assets/create/models/block/acacia_window_pane_noside_alt.json
|
||||
|
@ -2316,6 +2316,8 @@ ba80332510acab3f60f30d8b802ee2d450fd51b9 data/create/advancements/recipes/create
|
|||
1dea56b4759da676f0edf0878ec834a4129d110b data/create/advancements/recipes/create.base/copper_ladder_from_plates_copper_stonecutting.json
|
||||
3397bed32684183c2896348e3010f47137e3216d data/create/advancements/recipes/create.base/copycat_panel_from_zinc_ingot_stonecutting.json
|
||||
3c22b58635d4b1c1e4c4033e43b7b4a74b1af186 data/create/advancements/recipes/create.base/copycat_step_from_zinc_ingot_stonecutting.json
|
||||
3194b8da04cfb26f070b0a14f210f0117f252993 data/create/advancements/recipes/create.base/crafting/appliances/clipboard.json
|
||||
a1746099602e91fd23fba112016d41c71f9de62e data/create/advancements/recipes/create.base/crafting/appliances/clipboard_clear.json
|
||||
376bda381f3dedb52b03eb1504b103d8ddd1b672 data/create/advancements/recipes/create.base/crafting/appliances/copper_backtank.json
|
||||
9833d16405f8c51646590e98588fb410f96d9523 data/create/advancements/recipes/create.base/crafting/appliances/copper_diving_boots.json
|
||||
680c982dd1d3c45bed4d390fc0da5042750c157a data/create/advancements/recipes/create.base/crafting/appliances/copper_diving_helmet.json
|
||||
|
@ -4004,6 +4006,8 @@ bea832822e0e5f0048eb94649641ea541e11f943 data/create/recipes/copper_shingles_fro
|
|||
10fdc13f5b2b745e13e6e4e949a07ceaf4544a26 data/create/recipes/copper_tiles_from_plates_copper_stonecutting.json
|
||||
89aed29928cdfa7cdde43d4a51fc4387497ddde0 data/create/recipes/copycat_panel_from_zinc_ingot_stonecutting.json
|
||||
c06a4519139a33250c01297b532ba6ac7d76284c data/create/recipes/copycat_step_from_zinc_ingot_stonecutting.json
|
||||
005f8ad32598ea98314031e66b06e95e1f8ddd13 data/create/recipes/crafting/appliances/clipboard.json
|
||||
db648fd89bc2030f3e1e9baa0d2b5b69238dec4c data/create/recipes/crafting/appliances/clipboard_clear.json
|
||||
eb18d5972484418fa5a768633e68688ad20d2bd7 data/create/recipes/crafting/appliances/copper_backtank.json
|
||||
5771562086710eb5a3a05d464989d2f23d6c5e86 data/create/recipes/crafting/appliances/copper_diving_boots.json
|
||||
ec38ddb44e4bf8eaaba6f9d27e8469234fc98528 data/create/recipes/crafting/appliances/copper_diving_helmet.json
|
||||
|
|
|
@ -1212,7 +1212,7 @@
|
|||
"create.gui.schematicannon.option.skipMissing": "Skip missing Blocks",
|
||||
"create.gui.schematicannon.option.skipBlockEntities": "Protect Block Entities",
|
||||
"create.gui.schematicannon.slot.gunpowder": "Add gunpowder to fuel the cannon",
|
||||
"create.gui.schematicannon.slot.listPrinter": "Place books here to print a Checklist for your Schematic",
|
||||
"create.gui.schematicannon.slot.listPrinter": "Place a Clipboard or Book here to print a Checklist for your Schematic",
|
||||
"create.gui.schematicannon.slot.schematic": "Add your Schematic here. Make sure it is deployed at a specific location.",
|
||||
"create.gui.schematicannon.option.skipMissing.description": "If the cannon cannot find a required Block for placement, it will continue at the next Location.",
|
||||
"create.gui.schematicannon.option.skipBlockEntities.description": "The cannon will avoid replacing data holding blocks such as Chests.",
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"parent": "minecraft:recipes/root",
|
||||
"rewards": {
|
||||
"recipes": [
|
||||
"create:crafting/appliances/clipboard"
|
||||
]
|
||||
},
|
||||
"criteria": {
|
||||
"has_item": {
|
||||
"trigger": "minecraft:inventory_changed",
|
||||
"conditions": {
|
||||
"items": [
|
||||
{
|
||||
"items": [
|
||||
"create:andesite_alloy"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"has_the_recipe": {
|
||||
"trigger": "minecraft:recipe_unlocked",
|
||||
"conditions": {
|
||||
"recipe": "create:crafting/appliances/clipboard"
|
||||
}
|
||||
}
|
||||
},
|
||||
"requirements": [
|
||||
[
|
||||
"has_item",
|
||||
"has_the_recipe"
|
||||
]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"parent": "minecraft:recipes/root",
|
||||
"rewards": {
|
||||
"recipes": [
|
||||
"create:crafting/appliances/clipboard_clear"
|
||||
]
|
||||
},
|
||||
"criteria": {
|
||||
"has_item": {
|
||||
"trigger": "minecraft:inventory_changed",
|
||||
"conditions": {
|
||||
"items": [
|
||||
{
|
||||
"items": [
|
||||
"create:clipboard"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"has_the_recipe": {
|
||||
"trigger": "minecraft:recipe_unlocked",
|
||||
"conditions": {
|
||||
"recipe": "create:crafting/appliances/clipboard_clear"
|
||||
}
|
||||
}
|
||||
},
|
||||
"requirements": [
|
||||
[
|
||||
"has_item",
|
||||
"has_the_recipe"
|
||||
]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"pattern": [
|
||||
"A",
|
||||
"P",
|
||||
"G"
|
||||
],
|
||||
"key": {
|
||||
"G": {
|
||||
"tag": "minecraft:planks"
|
||||
},
|
||||
"P": {
|
||||
"item": "minecraft:paper"
|
||||
},
|
||||
"A": {
|
||||
"item": "create:andesite_alloy"
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"item": "create:clipboard"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"type": "minecraft:crafting_shapeless",
|
||||
"ingredients": [
|
||||
{
|
||||
"item": "create:clipboard"
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"item": "create:clipboard"
|
||||
}
|
||||
}
|
|
@ -13,12 +13,19 @@ import net.minecraft.world.item.ItemStack;
|
|||
|
||||
public class ClipboardEntry {
|
||||
|
||||
boolean checked;
|
||||
MutableComponent text;
|
||||
public boolean checked;
|
||||
public MutableComponent text;
|
||||
public ItemStack icon;
|
||||
|
||||
public ClipboardEntry(boolean checked, MutableComponent text) {
|
||||
this.checked = checked;
|
||||
this.text = text;
|
||||
this.icon = ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
public ClipboardEntry displayItem(ItemStack icon) {
|
||||
this.icon = icon;
|
||||
return this;
|
||||
}
|
||||
|
||||
public static List<List<ClipboardEntry>> readAll(ItemStack clipboardItem) {
|
||||
|
@ -29,6 +36,17 @@ public class ClipboardEntry {
|
|||
.readCompoundList(pageTag.getList("Entries", Tag.TAG_COMPOUND), ClipboardEntry::readNBT));
|
||||
}
|
||||
|
||||
public static List<ClipboardEntry> getLastViewedEntries(ItemStack heldItem) {
|
||||
List<List<ClipboardEntry>> pages = ClipboardEntry.readAll(heldItem);
|
||||
if (pages.isEmpty())
|
||||
return new ArrayList<>();
|
||||
int page = heldItem.getTag() == null ? 0
|
||||
: Math.min(heldItem.getTag()
|
||||
.getInt("PreviouslyOpenedPage"), pages.size() - 1);
|
||||
List<ClipboardEntry> entries = pages.get(page);
|
||||
return entries;
|
||||
}
|
||||
|
||||
public static void saveAll(List<List<ClipboardEntry>> entries, ItemStack clipboardItem) {
|
||||
CompoundTag tag = clipboardItem.getOrCreateTag();
|
||||
tag.put("Pages", NBTHelper.writeCompoundList(entries, list -> {
|
||||
|
@ -42,11 +60,18 @@ public class ClipboardEntry {
|
|||
CompoundTag nbt = new CompoundTag();
|
||||
nbt.putBoolean("Checked", checked);
|
||||
nbt.putString("Text", Component.Serializer.toJson(text));
|
||||
if (icon.isEmpty())
|
||||
return nbt;
|
||||
nbt.put("Icon", icon.serializeNBT());
|
||||
return nbt;
|
||||
}
|
||||
|
||||
public static ClipboardEntry readNBT(CompoundTag tag) {
|
||||
return new ClipboardEntry(tag.getBoolean("Checked"), Component.Serializer.fromJson(tag.getString("Text")));
|
||||
ClipboardEntry clipboardEntry =
|
||||
new ClipboardEntry(tag.getBoolean("Checked"), Component.Serializer.fromJson(tag.getString("Text")));
|
||||
if (tag.contains("Icon"))
|
||||
clipboardEntry.displayItem(ItemStack.of(tag.getCompound("Icon")));
|
||||
return clipboardEntry;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -64,6 +64,7 @@ public class ClipboardScreen extends AbstractSimiScreen {
|
|||
|
||||
int hoveredEntry;
|
||||
boolean hoveredCheck;
|
||||
boolean readonly;
|
||||
|
||||
DisplayCache displayCache = DisplayCache.EMPTY;
|
||||
TextFieldHelper editContext;
|
||||
|
@ -91,6 +92,10 @@ public class ClipboardScreen extends AbstractSimiScreen {
|
|||
editContext = new TextFieldHelper(this::getCurrentEntryText, this::setCurrentEntryText, this::getClipboard,
|
||||
this::setClipboard, this::validateTextForEntry);
|
||||
editingIndex = startEmpty ? 0 : -1;
|
||||
readonly = item.getTag() != null && item.getTag()
|
||||
.getBoolean("Readonly");
|
||||
if (readonly)
|
||||
editingIndex = -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -122,7 +127,7 @@ public class ClipboardScreen extends AbstractSimiScreen {
|
|||
addRenderableWidget(forward);
|
||||
addRenderableWidget(backward);
|
||||
|
||||
forward.visible = currentPage < 50;
|
||||
forward.visible = currentPage < 50 && (!readonly || currentPage + 1 < pages.size());
|
||||
backward.visible = currentPage > 0;
|
||||
}
|
||||
|
||||
|
@ -153,8 +158,9 @@ public class ClipboardScreen extends AbstractSimiScreen {
|
|||
for (int i = 0; i < currentEntries.size(); i++) {
|
||||
ClipboardEntry clipboardEntry = currentEntries.get(i);
|
||||
String text = clipboardEntry.text.getString();
|
||||
totalHeight += Math.max(12, font.split(Components.literal(text), 150)
|
||||
.size() * 9 + 3);
|
||||
totalHeight +=
|
||||
Math.max(12, font.split(Components.literal(text), clipboardEntry.icon.isEmpty() ? 150 : 130)
|
||||
.size() * 9 + 3);
|
||||
|
||||
if (totalHeight > my) {
|
||||
hoveredEntry = i;
|
||||
|
@ -211,17 +217,24 @@ public class ClipboardScreen extends AbstractSimiScreen {
|
|||
if (currentPage == previously)
|
||||
return;
|
||||
editingIndex = -1;
|
||||
if (pages.size() <= currentPage)
|
||||
if (pages.size() <= currentPage) {
|
||||
if (readonly) {
|
||||
currentPage = previously;
|
||||
return;
|
||||
}
|
||||
pages.add(new ArrayList<>());
|
||||
}
|
||||
currentEntries = pages.get(currentPage);
|
||||
if (currentEntries.isEmpty()) {
|
||||
currentEntries.add(new ClipboardEntry(false, Components.empty()));
|
||||
editingIndex = 0;
|
||||
editContext.setCursorToEnd();
|
||||
clearDisplayCacheAfterChange();
|
||||
if (!readonly) {
|
||||
editingIndex = 0;
|
||||
editContext.setCursorToEnd();
|
||||
clearDisplayCacheAfterChange();
|
||||
}
|
||||
}
|
||||
|
||||
forward.visible = currentPage < 50;
|
||||
forward.visible = currentPage < 50 && (!readonly || currentPage + 1 < pages.size());
|
||||
backward.visible = currentPage > 0;
|
||||
|
||||
if (next)
|
||||
|
@ -245,20 +258,24 @@ public class ClipboardScreen extends AbstractSimiScreen {
|
|||
for (int i = 0; i < currentEntries.size(); i++) {
|
||||
ClipboardEntry clipboardEntry = currentEntries.get(i);
|
||||
boolean checked = clipboardEntry.checked;
|
||||
int iconOffset = clipboardEntry.icon.isEmpty() ? 0 : 16;
|
||||
|
||||
font.draw(ms, "\u25A1", x + 45, y + 51, checked ? 0x668D7F6B : 0xff8D7F6B);
|
||||
if (checked)
|
||||
font.draw(ms, "\u2714", x + 45, y + 50, 0x31B25D);
|
||||
|
||||
List<FormattedCharSequence> split = font.split(clipboardEntry.text, 150);
|
||||
List<FormattedCharSequence> split = font.split(clipboardEntry.text, 150 - iconOffset);
|
||||
if (split.isEmpty()) {
|
||||
y += 12;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!clipboardEntry.icon.isEmpty())
|
||||
itemRenderer.renderGuiItem(clipboardEntry.icon, x + 54, y + 50);
|
||||
|
||||
for (FormattedCharSequence sequence : split) {
|
||||
if (i != editingIndex)
|
||||
font.draw(ms, sequence, x + 58, y + 50, checked ? 0x31B25D : 0x311A00);
|
||||
font.draw(ms, sequence, x + 58 + iconOffset, y + 50, checked ? 0x31B25D : 0x311A00);
|
||||
y += 9;
|
||||
}
|
||||
y += 3;
|
||||
|
@ -525,7 +542,7 @@ public class ClipboardScreen extends AbstractSimiScreen {
|
|||
return true;
|
||||
}
|
||||
|
||||
if (hoveredEntry != editingIndex) {
|
||||
if (hoveredEntry != editingIndex && !readonly) {
|
||||
editingIndex = hoveredEntry;
|
||||
if (hoveredEntry >= currentEntries.size()) {
|
||||
currentEntries.add(new ClipboardEntry(false, Components.empty()));
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
package com.simibubi.create.content.curiosities.clipboard;
|
||||
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.gui.screens.inventory.BookEditScreen;
|
||||
|
||||
public class ClipboardScreenHelper {
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -2,13 +2,16 @@ package com.simibubi.create.content.logistics.block.redstone;
|
|||
|
||||
import static net.minecraft.world.level.block.state.properties.BlockStateProperties.WATERLOGGED;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import com.simibubi.create.AllBlockEntityTypes;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.AllShapes;
|
||||
import com.simibubi.create.content.contraptions.wrench.IWrenchable;
|
||||
import com.simibubi.create.content.curiosities.clipboard.ClipboardEntry;
|
||||
import com.simibubi.create.content.schematics.ISpecialBlockItemRequirement;
|
||||
import com.simibubi.create.content.schematics.ItemRequirement;
|
||||
import com.simibubi.create.content.schematics.ItemRequirement.ItemUseType;
|
||||
|
@ -19,6 +22,7 @@ import net.minecraft.core.BlockPos;
|
|||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
|
@ -76,20 +80,31 @@ public class NixieTubeBlock extends DoubleFaceAttachedBlock
|
|||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
||||
boolean display = heldItem.getItem() == Items.NAME_TAG && heldItem.hasCustomHoverName();
|
||||
boolean display =
|
||||
heldItem.getItem() == Items.NAME_TAG && heldItem.hasCustomHoverName() || AllItems.CLIPBOARD.isIn(heldItem);
|
||||
DyeColor dye = DyeColor.getColor(heldItem);
|
||||
|
||||
if (!display && dye == null)
|
||||
return InteractionResult.PASS;
|
||||
if (world.isClientSide)
|
||||
return InteractionResult.SUCCESS;
|
||||
|
||||
CompoundTag tag = heldItem.getTagElement("display");
|
||||
String tagElement = tag != null && tag.contains("Name", Tag.TAG_STRING) ? tag.getString("Name") : null;
|
||||
|
||||
if (AllItems.CLIPBOARD.isIn(heldItem)) {
|
||||
List<ClipboardEntry> entries = ClipboardEntry.getLastViewedEntries(heldItem);
|
||||
for (int i = 0; i < entries.size();) {
|
||||
tagElement = Component.Serializer.toJson(entries.get(i).text);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (world.isClientSide)
|
||||
return InteractionResult.SUCCESS;
|
||||
|
||||
String tagUsed = tagElement;
|
||||
walkNixies(world, pos, (currentPos, rowPosition) -> {
|
||||
if (display)
|
||||
withBlockEntityDo(world, currentPos, be -> be.displayCustomText(tagElement, rowPosition));
|
||||
withBlockEntityDo(world, currentPos, be -> be.displayCustomText(tagUsed, rowPosition));
|
||||
if (dye != null)
|
||||
world.setBlockAndUpdate(currentPos, withColor(state, dye));
|
||||
});
|
||||
|
|
|
@ -8,12 +8,15 @@ import java.util.function.Predicate;
|
|||
|
||||
import com.simibubi.create.AllBlockEntityTypes;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.AllShapes;
|
||||
import com.simibubi.create.content.contraptions.base.HorizontalKineticBlock;
|
||||
import com.simibubi.create.content.contraptions.base.KineticBlockEntity;
|
||||
import com.simibubi.create.content.contraptions.relays.elementary.ICogWheel;
|
||||
import com.simibubi.create.content.contraptions.wrench.IWrenchable;
|
||||
import com.simibubi.create.content.curiosities.clipboard.ClipboardEntry;
|
||||
import com.simibubi.create.foundation.block.IBE;
|
||||
import com.simibubi.create.foundation.utility.Components;
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
import com.simibubi.create.foundation.utility.placement.IPlacementHelper;
|
||||
import com.simibubi.create.foundation.utility.placement.PlacementHelpers;
|
||||
|
@ -27,6 +30,7 @@ import net.minecraft.core.Direction.Axis;
|
|||
import net.minecraft.core.Direction.AxisDirection;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
|
@ -158,7 +162,8 @@ public class FlapDisplayBlock extends HorizontalKineticBlock
|
|||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
||||
boolean display = heldItem.getItem() == Items.NAME_TAG && heldItem.hasCustomHoverName();
|
||||
boolean display =
|
||||
heldItem.getItem() == Items.NAME_TAG && heldItem.hasCustomHoverName() || AllItems.CLIPBOARD.isIn(heldItem);
|
||||
DyeColor dye = DyeColor.getColor(heldItem);
|
||||
|
||||
if (!display && dye == null)
|
||||
|
@ -171,8 +176,20 @@ public class FlapDisplayBlock extends HorizontalKineticBlock
|
|||
CompoundTag tag = heldItem.getTagElement("display");
|
||||
String tagElement = tag != null && tag.contains("Name", Tag.TAG_STRING) ? tag.getString("Name") : null;
|
||||
|
||||
if (display)
|
||||
if (display) {
|
||||
if (AllItems.CLIPBOARD.isIn(heldItem)) {
|
||||
List<ClipboardEntry> entries = ClipboardEntry.getLastViewedEntries(heldItem);
|
||||
int line = lineIndex;
|
||||
for (int i = 0; i < entries.size(); i++) {
|
||||
for (String string : entries.get(i).text.getString()
|
||||
.split("\n"))
|
||||
flapBE.applyTextManually(line++, Component.Serializer.toJson(Components.literal(string)));
|
||||
}
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
||||
flapBE.applyTextManually(lineIndex, tagElement);
|
||||
}
|
||||
if (dye != null) {
|
||||
world.playSound(null, pos, SoundEvents.DYE_USE, SoundSource.BLOCKS, 1.0F, 1.0F);
|
||||
flapBE.setColour(lineIndex, dye);
|
||||
|
@ -315,7 +332,8 @@ public class FlapDisplayBlock extends HorizontalKineticBlock
|
|||
BlockPos relative = pPos.relative(d);
|
||||
BlockState adjacent = pLevel.getBlockState(relative);
|
||||
if (canConnect(pState, adjacent))
|
||||
KineticBlockEntity.switchToBlockState(pLevel, relative, updateColumn(pLevel, relative, adjacent, false));
|
||||
KineticBlockEntity.switchToBlockState(pLevel, relative,
|
||||
updateColumn(pLevel, relative, adjacent, false));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,10 @@ import java.util.List;
|
|||
import java.util.Locale;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.content.curiosities.clipboard.ClipboardEntry;
|
||||
import com.simibubi.create.content.curiosities.clipboard.ClipboardOverrides;
|
||||
import com.simibubi.create.content.curiosities.clipboard.ClipboardOverrides.ClipboardType;
|
||||
import com.simibubi.create.content.schematics.ItemRequirement.ItemUseType;
|
||||
import com.simibubi.create.foundation.utility.Components;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
|
@ -27,6 +31,7 @@ import net.minecraft.world.item.Items;
|
|||
public class MaterialChecklist {
|
||||
|
||||
public static final int MAX_ENTRIES_PER_PAGE = 5;
|
||||
public static final int MAX_ENTRIES_PER_CLIPBOARD_PAGE = 7;
|
||||
|
||||
public Object2IntMap<Item> gathered = new Object2IntArrayMap<>();
|
||||
public Object2IntMap<Item> required = new Object2IntArrayMap<>();
|
||||
|
@ -70,7 +75,7 @@ public class MaterialChecklist {
|
|||
gathered.put(item, stack.getCount());
|
||||
}
|
||||
|
||||
public ItemStack createItem() {
|
||||
public ItemStack createWrittenBook() {
|
||||
ItemStack book = new ItemStack(Items.WRITTEN_BOOK);
|
||||
|
||||
CompoundTag tag = book.getOrCreateTag();
|
||||
|
@ -88,9 +93,11 @@ public class MaterialChecklist {
|
|||
List<Item> keys = new ArrayList<>(Sets.union(required.keySet(), damageRequired.keySet()));
|
||||
Collections.sort(keys, (item1, item2) -> {
|
||||
Locale locale = Locale.ENGLISH;
|
||||
String name1 = item1.getDescription().getString()
|
||||
String name1 = item1.getDescription()
|
||||
.getString()
|
||||
.toLowerCase(locale);
|
||||
String name2 = item2.getDescription().getString()
|
||||
String name2 = item2.getDescription()
|
||||
.getString()
|
||||
.toLowerCase(locale);
|
||||
return name1.compareTo(name2);
|
||||
});
|
||||
|
@ -109,30 +116,33 @@ public class MaterialChecklist {
|
|||
|
||||
if (itemsWritten == MAX_ENTRIES_PER_PAGE) {
|
||||
itemsWritten = 0;
|
||||
textComponent.append(Components.literal("\n >>>").withStyle(ChatFormatting.BLUE));
|
||||
textComponent.append(Components.literal("\n >>>")
|
||||
.withStyle(ChatFormatting.BLUE));
|
||||
pages.add(StringTag.valueOf(Component.Serializer.toJson(textComponent)));
|
||||
textComponent = Components.empty();
|
||||
}
|
||||
|
||||
itemsWritten++;
|
||||
textComponent.append(entry(new ItemStack(item), amount, true));
|
||||
textComponent.append(entry(new ItemStack(item), amount, true, true));
|
||||
}
|
||||
|
||||
for (Item item : completed) {
|
||||
if (itemsWritten == MAX_ENTRIES_PER_PAGE) {
|
||||
itemsWritten = 0;
|
||||
textComponent.append(Components.literal("\n >>>").withStyle(ChatFormatting.DARK_GREEN));
|
||||
textComponent.append(Components.literal("\n >>>")
|
||||
.withStyle(ChatFormatting.DARK_GREEN));
|
||||
pages.add(StringTag.valueOf(Component.Serializer.toJson(textComponent)));
|
||||
textComponent = Components.empty();
|
||||
}
|
||||
|
||||
itemsWritten++;
|
||||
textComponent.append(entry(new ItemStack(item), getRequiredAmount(item), false));
|
||||
textComponent.append(entry(new ItemStack(item), getRequiredAmount(item), false, true));
|
||||
}
|
||||
|
||||
pages.add(StringTag.valueOf(Component.Serializer.toJson(textComponent)));
|
||||
|
||||
tag.put("pages", pages);
|
||||
tag.putBoolean("readonly", true);
|
||||
tag.putString("author", "Schematicannon");
|
||||
tag.putString("title", ChatFormatting.BLUE + "Material Checklist");
|
||||
textComponent = Lang.translateDirect("materialChecklist")
|
||||
|
@ -145,6 +155,80 @@ public class MaterialChecklist {
|
|||
return book;
|
||||
}
|
||||
|
||||
public ItemStack createWrittenClipboard() {
|
||||
ItemStack clipboard = AllItems.CLIPBOARD.asStack();
|
||||
CompoundTag tag = clipboard.getOrCreateTag();
|
||||
int itemsWritten = 0;
|
||||
|
||||
List<List<ClipboardEntry>> pages = new ArrayList<>();
|
||||
List<ClipboardEntry> currentPage = new ArrayList<>();
|
||||
|
||||
if (blocksNotLoaded) {
|
||||
currentPage.add(new ClipboardEntry(false, Lang.translateDirect("materialChecklist.blocksNotLoaded")
|
||||
.withStyle(ChatFormatting.RED)));
|
||||
}
|
||||
|
||||
List<Item> keys = new ArrayList<>(Sets.union(required.keySet(), damageRequired.keySet()));
|
||||
Collections.sort(keys, (item1, item2) -> {
|
||||
Locale locale = Locale.ENGLISH;
|
||||
String name1 = item1.getDescription()
|
||||
.getString()
|
||||
.toLowerCase(locale);
|
||||
String name2 = item2.getDescription()
|
||||
.getString()
|
||||
.toLowerCase(locale);
|
||||
return name1.compareTo(name2);
|
||||
});
|
||||
|
||||
List<Item> completed = new ArrayList<>();
|
||||
for (Item item : keys) {
|
||||
int amount = getRequiredAmount(item);
|
||||
if (gathered.containsKey(item))
|
||||
amount -= gathered.getInt(item);
|
||||
|
||||
if (amount <= 0) {
|
||||
completed.add(item);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (itemsWritten == MAX_ENTRIES_PER_CLIPBOARD_PAGE) {
|
||||
itemsWritten = 0;
|
||||
currentPage.add(new ClipboardEntry(false, Components.literal(">>>")
|
||||
.withStyle(ChatFormatting.DARK_GRAY)));
|
||||
pages.add(currentPage);
|
||||
currentPage = new ArrayList<>();
|
||||
}
|
||||
|
||||
itemsWritten++;
|
||||
currentPage.add(new ClipboardEntry(false, entry(new ItemStack(item), amount, true, false))
|
||||
.displayItem(new ItemStack(item)));
|
||||
}
|
||||
|
||||
for (Item item : completed) {
|
||||
if (itemsWritten == MAX_ENTRIES_PER_PAGE) {
|
||||
itemsWritten = 0;
|
||||
currentPage.add(new ClipboardEntry(true, Components.literal(">>>")
|
||||
.withStyle(ChatFormatting.DARK_GREEN)));
|
||||
pages.add(currentPage);
|
||||
currentPage = new ArrayList<>();
|
||||
}
|
||||
|
||||
itemsWritten++;
|
||||
currentPage.add(new ClipboardEntry(true, entry(new ItemStack(item), getRequiredAmount(item), false, false))
|
||||
.displayItem(new ItemStack(item)));
|
||||
}
|
||||
|
||||
pages.add(currentPage);
|
||||
ClipboardEntry.saveAll(pages, clipboard);
|
||||
ClipboardOverrides.switchTo(ClipboardType.WRITTEN, clipboard);
|
||||
clipboard.getOrCreateTagElement("display")
|
||||
.putString("Name", Component.Serializer.toJson(Lang.translateDirect("materialChecklist")
|
||||
.setStyle(Style.EMPTY.withItalic(Boolean.FALSE))));
|
||||
tag.putBoolean("Readonly", true);
|
||||
clipboard.setTag(tag);
|
||||
return clipboard;
|
||||
}
|
||||
|
||||
public int getRequiredAmount(Item item) {
|
||||
int amount = required.getOrDefault(item, 0);
|
||||
if (damageRequired.containsKey(item))
|
||||
|
@ -152,7 +236,7 @@ public class MaterialChecklist {
|
|||
return amount;
|
||||
}
|
||||
|
||||
private Component entry(ItemStack item, int amount, boolean unfinished) {
|
||||
private MutableComponent entry(ItemStack item, int amount, boolean unfinished, boolean forBook) {
|
||||
int stacks = amount / 64;
|
||||
int remainder = amount % 64;
|
||||
MutableComponent tc = Components.empty();
|
||||
|
@ -160,11 +244,14 @@ public class MaterialChecklist {
|
|||
.setStyle(Style.EMPTY
|
||||
.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_ITEM, new HoverEvent.ItemStackInfo(item)))));
|
||||
|
||||
if (!unfinished)
|
||||
if (!unfinished && forBook)
|
||||
tc.append(" \u2714");
|
||||
tc.withStyle(unfinished ? ChatFormatting.BLUE : ChatFormatting.DARK_GREEN);
|
||||
return tc.append(Components.literal("\n" + " x" + amount).withStyle(ChatFormatting.BLACK))
|
||||
.append(Components.literal(" | " + stacks + "\u25A4 +" + remainder + "\n").withStyle(ChatFormatting.GRAY));
|
||||
if (!unfinished || forBook)
|
||||
tc.withStyle(unfinished ? ChatFormatting.BLUE : ChatFormatting.DARK_GREEN);
|
||||
return tc.append(Components.literal("\n" + " x" + amount)
|
||||
.withStyle(ChatFormatting.BLACK))
|
||||
.append(Components.literal(" | " + stacks + "\u25A4 +" + remainder + (forBook ? "\n" : ""))
|
||||
.withStyle(ChatFormatting.GRAY));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -700,8 +700,9 @@ public class SchematicannonBlockEntity extends SmartBlockEntity implements MenuP
|
|||
updateChecklist();
|
||||
|
||||
dontUpdateChecklist = true;
|
||||
inventory.extractItem(BookInput, 1, false);
|
||||
ItemStack stack = checklist.createItem();
|
||||
ItemStack extractItem = inventory.extractItem(BookInput, 1, false);
|
||||
ItemStack stack = AllItems.CLIPBOARD.isIn(extractItem) ? checklist.createWrittenClipboard()
|
||||
: checklist.createWrittenBook();
|
||||
stack.setCount(inventory.getStackInSlot(BookOutput)
|
||||
.getCount() + 1);
|
||||
inventory.setStackInSlot(BookOutput, stack);
|
||||
|
|
|
@ -28,7 +28,8 @@ public class SchematicannonInventory extends ItemStackHandler {
|
|||
case 1: // Blueprint output
|
||||
return false;
|
||||
case 2: // Book input
|
||||
return stack.sameItem(new ItemStack(Items.BOOK)) || stack.sameItem(new ItemStack(Items.WRITTEN_BOOK));
|
||||
return AllItems.CLIPBOARD.isIn(stack) || stack.sameItem(new ItemStack(Items.BOOK))
|
||||
|| stack.sameItem(new ItemStack(Items.WRITTEN_BOOK));
|
||||
case 3: // Material List output
|
||||
return false;
|
||||
case 4: // Gunpowder
|
||||
|
|
|
@ -1011,6 +1011,18 @@ public class StandardRecipeGen extends CreateRecipeProvider {
|
|||
.viaShapeless(b -> b.requires(I.wheatFlour())
|
||||
.requires(Items.WATER_BUCKET)),
|
||||
|
||||
CLIPBOARD = create(AllItems.CLIPBOARD).unlockedBy(I::andesite)
|
||||
.viaShaped(b -> b.define('G', I.planks())
|
||||
.define('P', Items.PAPER)
|
||||
.define('A', I.andesite())
|
||||
.pattern("A")
|
||||
.pattern("P")
|
||||
.pattern("G")),
|
||||
|
||||
CLIPBOARD_CLEAR = create(AllItems.CLIPBOARD).withSuffix("_clear")
|
||||
.unlockedBy(AllItems.CLIPBOARD::get)
|
||||
.viaShapeless(b -> b.requires(AllItems.CLIPBOARD.get())),
|
||||
|
||||
DIVING_HELMET = create(AllItems.COPPER_DIVING_HELMET).unlockedBy(I::copper)
|
||||
.viaShaped(b -> b.define('G', Tags.Items.GLASS)
|
||||
.define('P', I.copper())
|
||||
|
|
|
@ -357,7 +357,7 @@
|
|||
"create.gui.schematicannon.option.skipBlockEntities": "Protect Block Entities",
|
||||
|
||||
"create.gui.schematicannon.slot.gunpowder": "Add gunpowder to fuel the cannon",
|
||||
"create.gui.schematicannon.slot.listPrinter": "Place books here to print a Checklist for your Schematic",
|
||||
"create.gui.schematicannon.slot.listPrinter": "Place a Clipboard or Book here to print a Checklist for your Schematic",
|
||||
"create.gui.schematicannon.slot.schematic": "Add your Schematic here. Make sure it is deployed at a specific location.",
|
||||
|
||||
"create.gui.schematicannon.option.skipMissing.description": "If the cannon cannot find a required Block for placement, it will continue at the next Location.",
|
||||
|
|
Loading…
Reference in a new issue