Advanced Tooltip Modification

- Finish refactor of item description tooltips and kinetic stat tooltips
- Change Palette to use Style instead of ChatFormatting
- Remove old code in TooltipHelper
- Add deferred registration capabilities to AttachedRegistry
- Move creative mode tabs to AllCreativeModeTabs
- Delete IItemHandlerModifiableIntermediate
- Delete StorageInterfaceMovement
This commit is contained in:
PepperCode1 2023-01-29 11:09:32 -08:00
parent f2b472f90d
commit 7dc6fc7576
28 changed files with 384 additions and 480 deletions

View file

@ -238,7 +238,7 @@ import com.simibubi.create.foundation.data.BuilderTransformers;
import com.simibubi.create.foundation.data.CreateRegistrate;
import com.simibubi.create.foundation.data.ModelGen;
import com.simibubi.create.foundation.data.SharedProperties;
import com.simibubi.create.foundation.item.ItemTooltipHandler;
import com.simibubi.create.foundation.item.ItemDescription;
import com.simibubi.create.foundation.item.UncontainableBlockItem;
import com.simibubi.create.foundation.utility.ColorHandlers;
import com.simibubi.create.foundation.utility.Couple;
@ -286,7 +286,7 @@ import net.minecraftforge.common.Tags;
public class AllBlocks {
static {
REGISTRATE.creativeModeTab(() -> Create.BASE_CREATIVE_TAB);
REGISTRATE.creativeModeTab(() -> AllCreativeModeTabs.BASE_CREATIVE_TAB);
}
// Schematics
@ -573,7 +573,7 @@ public class AllBlocks {
.transform(axeOrPickaxe())
.transform(BuilderTransformers.cuckooClock())
.lang("Cuckoo Clock")
.onRegisterAfter(Registry.ITEM_REGISTRY, c -> ItemTooltipHandler.referTo(c, CUCKOO_CLOCK))
.onRegisterAfter(Registry.ITEM_REGISTRY, c -> ItemDescription.referKey(c, CUCKOO_CLOCK))
.register();
public static final BlockEntry<MillstoneBlock> MILLSTONE = REGISTRATE.block("millstone", MillstoneBlock::new)
@ -1384,7 +1384,7 @@ public class AllBlocks {
.unlockedBy("has_seat", RegistrateRecipeProvider.has(AllItemTags.SEATS.tag))
.save(p, Create.asResource("crafting/kinetics/" + c.getName() + "_from_other_seat"));
})
.onRegisterAfter(Registry.ITEM_REGISTRY, v -> ItemTooltipHandler.referTo(v, "block.create.brown_seat"))
.onRegisterAfter(Registry.ITEM_REGISTRY, v -> ItemDescription.useKey(v, "block.create.seat"))
.tag(AllBlockTags.SEATS.tag)
.item()
.tag(AllItemTags.SEATS.tag)
@ -2007,7 +2007,7 @@ public class AllBlocks {
.withExistingParent(colourName + "_toolbox", p.modLoc("block/toolbox/block"))
.texture("0", p.modLoc("block/toolbox/" + colourName)));
})
.onRegisterAfter(Registry.ITEM_REGISTRY, v -> ItemTooltipHandler.referTo(v, "block.create.toolbox"))
.onRegisterAfter(Registry.ITEM_REGISTRY, v -> ItemDescription.useKey(v, "block.create.toolbox"))
.tag(AllBlockTags.TOOLBOXES.tag)
.item(UncontainableBlockItem::new)
.model((c, p) -> p.withExistingParent(colourName + "_toolbox", p.modLoc("block/toolbox/item"))

View file

@ -0,0 +1,14 @@
package com.simibubi.create;
import com.simibubi.create.content.palettes.PalettesCreativeModeTab;
import com.simibubi.create.foundation.item.BaseCreativeModeTab;
import net.minecraft.world.item.CreativeModeTab;
public class AllCreativeModeTabs {
public static final CreativeModeTab BASE_CREATIVE_TAB = new BaseCreativeModeTab();
public static final CreativeModeTab PALETTES_CREATIVE_TAB = new PalettesCreativeModeTab();
public static void init() {
}
}

View file

@ -54,7 +54,7 @@ import com.simibubi.create.foundation.data.AssetLookup;
import com.simibubi.create.foundation.data.CreateRegistrate;
import com.simibubi.create.foundation.data.recipe.CompatMetals;
import com.simibubi.create.foundation.item.HiddenIngredientItem;
import com.simibubi.create.foundation.item.ItemTooltipHandler;
import com.simibubi.create.foundation.item.ItemDescription;
import com.simibubi.create.foundation.item.TagDependentIngredientItem;
import com.tterrag.registrate.util.entry.ItemEntry;
@ -69,7 +69,7 @@ import net.minecraftforge.common.Tags;
public class AllItems {
static {
REGISTRATE.creativeModeTab(() -> Create.BASE_CREATIVE_TAB);
REGISTRATE.creativeModeTab(() -> AllCreativeModeTabs.BASE_CREATIVE_TAB);
}
// Materials
@ -275,7 +275,7 @@ public class AllItems {
public static final ItemEntry<SandPaperItem> RED_SAND_PAPER = REGISTRATE.item("red_sand_paper", SandPaperItem::new)
.tag(AllTags.AllItemTags.SANDPAPER.tag)
.onRegister(s -> ItemTooltipHandler.referTo(s, SAND_PAPER))
.onRegister(s -> ItemDescription.referKey(s, SAND_PAPER))
.register();
public static final ItemEntry<WrenchItem> WRENCH = REGISTRATE.item("wrench", WrenchItem::new)

View file

@ -19,7 +19,6 @@ import com.simibubi.create.content.logistics.block.display.AllDisplayBehaviours;
import com.simibubi.create.content.logistics.block.mechanicalArm.AllArmInteractionPointTypes;
import com.simibubi.create.content.logistics.trains.GlobalRailwayManager;
import com.simibubi.create.content.palettes.AllPaletteBlocks;
import com.simibubi.create.content.palettes.PalettesCreativeModeTab;
import com.simibubi.create.content.schematics.ServerSchematicLoader;
import com.simibubi.create.content.schematics.filtering.SchematicInstances;
import com.simibubi.create.foundation.advancement.AllAdvancements;
@ -36,7 +35,10 @@ import com.simibubi.create.foundation.data.recipe.MechanicalCraftingRecipeGen;
import com.simibubi.create.foundation.data.recipe.ProcessingRecipeGen;
import com.simibubi.create.foundation.data.recipe.SequencedAssemblyRecipeGen;
import com.simibubi.create.foundation.data.recipe.StandardRecipeGen;
import com.simibubi.create.foundation.item.BaseCreativeModeTab;
import com.simibubi.create.foundation.item.ItemDescription;
import com.simibubi.create.foundation.item.KineticStats;
import com.simibubi.create.foundation.item.TooltipHelper.Palette;
import com.simibubi.create.foundation.item.TooltipModifier;
import com.simibubi.create.foundation.networking.AllPackets;
import com.simibubi.create.foundation.utility.AttachedRegistry;
import com.simibubi.create.foundation.worldgen.AllFeatures;
@ -48,7 +50,6 @@ import net.minecraft.data.DataGenerator;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.level.Level;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.common.ForgeMod;
@ -81,8 +82,13 @@ public class Create {
public static final CreateRegistrate REGISTRATE = CreateRegistrate.create(ID);
public static final CreativeModeTab BASE_CREATIVE_TAB = new BaseCreativeModeTab();
public static final CreativeModeTab PALETTES_CREATIVE_TAB = new PalettesCreativeModeTab();
static {
// TODO 0.5.1: choose color palette
REGISTRATE.setTooltipModifierFactory(item -> {
return new ItemDescription.Modifier(item, Palette.BLUE)
.andThen(TooltipModifier.mapNull(KineticStats.create(item)));
});
}
public static final ServerSchematicLoader SCHEMATIC_RECEIVER = new ServerSchematicLoader();
public static final RedstoneLinkNetworkHandler REDSTONE_LINK_NETWORK_HANDLER = new RedstoneLinkNetworkHandler();
@ -105,6 +111,7 @@ public class Create {
AllSoundEvents.prepare();
AllTags.init();
AllCreativeModeTabs.init();
AllBlocks.register();
AllItems.register();
AllFluids.register();
@ -146,12 +153,12 @@ public class Create {
}
public static void init(final FMLCommonSetupEvent event) {
AttachedRegistry.unwrapAll();
AllPackets.registerPackets();
SchematicInstances.register();
BuiltinPotatoProjectileTypes.register();
event.enqueueWork(() -> {
AttachedRegistry.unwrapAll();
AllAdvancements.register();
AllTriggers.register();
BoilerHeaters.registerDefaults();
@ -162,7 +169,7 @@ public class Create {
TagGen.datagen();
DataGenerator gen = event.getGenerator();
if (event.includeClient()) {
gen.addProvider(new LangMerger(gen, ID, "Create", AllLangPartials.values()));
gen.addProvider(new LangMerger(gen, ID, NAME, AllLangPartials.values()));
gen.addProvider(AllSoundEvents.provider(gen));
}
if (event.includeServer()) {

View file

@ -22,6 +22,7 @@ import com.simibubi.create.foundation.blockEntity.BlockEntityBehaviour;
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
import com.simibubi.create.foundation.config.AllConfigs;
import com.simibubi.create.foundation.item.TooltipHelper;
import com.simibubi.create.foundation.item.TooltipHelper.Palette;
import com.simibubi.create.foundation.sound.SoundScapes;
import com.simibubi.create.foundation.sound.SoundScapes.AmbienceGroup;
import com.simibubi.create.foundation.utility.Lang;
@ -396,7 +397,7 @@ public class KineticBlockEntity extends SmartBlockEntity implements IHaveGoggleI
.style(GOLD)
.forGoggles(tooltip);
Component hint = Lang.translateDirect("gui.contraptions.network_overstressed");
List<Component> cutString = TooltipHelper.cutTextComponent(hint, GRAY, ChatFormatting.WHITE);
List<Component> cutString = TooltipHelper.cutTextComponent(hint, Palette.GRAY_AND_WHITE);
for (int i = 0; i < cutString.size(); i++)
Lang.builder()
.add(cutString.get(i)
@ -412,7 +413,7 @@ public class KineticBlockEntity extends SmartBlockEntity implements IHaveGoggleI
MutableComponent hint =
Lang.translateDirect("gui.contraptions.not_fast_enough", I18n.get(getBlockState().getBlock()
.getDescriptionId()));
List<Component> cutString = TooltipHelper.cutTextComponent(hint, GRAY, ChatFormatting.WHITE);
List<Component> cutString = TooltipHelper.cutTextComponent(hint, Palette.GRAY_AND_WHITE);
for (int i = 0; i < cutString.size(); i++)
Lang.builder()
.add(cutString.get(i)

View file

@ -1,157 +0,0 @@
//package com.simibubi.create.content.contraptions.components.actors;
//
//import java.util.function.Predicate;
//
//import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour;
//import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
//import com.simibubi.create.content.logistics.block.transposer.TransposerBlock;
//import com.simibubi.create.content.logistics.block.transposer.TransposerTileEntity;
//import com.simibubi.create.foundation.config.AllConfigs;
//import com.simibubi.create.foundation.item.ItemHelper;
//import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
//import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
//import com.simibubi.create.foundation.tileEntity.behaviour.inventory.SingleTargetAutoExtractingBehaviour;
//import com.simibubi.create.foundation.utility.VecHelper;
//
//import net.minecraft.item.ItemStack;
//import net.minecraft.nbt.NBTUtil;
//import net.minecraft.tileentity.TileEntity;
//import net.minecraft.core.Direction;
//import net.minecraft.core.Direction.Axis;
//import net.minecraft.util.math.BlockPos;
//import net.minecraft.util.math.vector.Vector3d;
//import net.minecraft.world.World;
//import net.minecraftforge.items.IItemHandlerModifiable;
//import net.minecraftforge.items.ItemHandlerHelper;
//
//public class StorageInterfaceMovement extends MovementBehaviour {
//
// private static final String _exporting_ = "Exporting";
// private static final String _delay_ = "Delay";
// private static final String _workingPos_ = "WorkingPos";
//
// @Override
// public Vector3d getActiveAreaOffset(MovementContext context) {
// return new Vector3d(context.state.get(PortableStorageInterfaceBlock.FACING).getDirectionVec()).scale(.85f);
// }
//
// @Override
// public void visitNewPosition(MovementContext context, BlockPos pos) {
// Direction currentFacing = getCurrentFacing(context);
// TransposerTileEntity transposer = getValidTransposer(context.world, pos, currentFacing.getAxis());
// if (transposer == null)
// return;
// context.data.put(_workingPos_, NBTUtil.writeBlockPos(pos));
// context.data.putBoolean(_exporting_,
// TransposerBlock.getBlockFacing(transposer.getBlockState()) != currentFacing);
// context.stall = true;
// }
//
// @Override
// public void tick(MovementContext context) {
// if (!context.data.contains(_workingPos_))
// return;
// if (context.world.isRemote)
// return;
//
// BlockPos pos = NBTUtil.readBlockPos(context.data.getCompound(_workingPos_));
// TransposerTileEntity transposer = getValidTransposer(context.world, pos, getCurrentFacing(context).getAxis());
// if (transposer == null) {
// reset(context);
// return;
// }
//
// int nextExtract = context.data.getInt(_delay_);
// if (nextExtract > 0) {
// nextExtract--;
// context.data.putInt(_delay_, nextExtract);
// return;
// }
//
// boolean extract = context.data.getBoolean(_exporting_);
// boolean success = false;
// IItemHandlerModifiable inv = context.contraption.inventory;
// SingleTargetAutoExtractingBehaviour extracting =
// TileEntityBehaviour.get(transposer, SingleTargetAutoExtractingBehaviour.TYPE);
// FilteringBehaviour filtering = TileEntityBehaviour.get(transposer, FilteringBehaviour.TYPE);
//
// if (extract) {
// // Export from Contraption
// Predicate<ItemStack> test = extracting.getFilterTest();
// int exactAmount = extracting.getAmountFromFilter();
// ItemStack itemExtracted = ItemStack.EMPTY;
// if (exactAmount != -1)
// itemExtracted = ItemHelper.extract(inv, test, exactAmount, false);
// else
// itemExtracted = ItemHelper.extract(inv, test, transposer::amountToExtract, false);
//
// if (!itemExtracted.isEmpty()) {
// transposer.onExtract(itemExtracted);
// success = exactAmount == -1;
// }
//
// } else {
// // Import to Contraption
// if (extracting != null) {
// extracting.setSynchronized(false);
// extracting.withAdditionalFilter(stack -> {
// if (filtering.anyAmount())
// return true;
// return ItemHandlerHelper.insertItemStacked(inv, stack, true).isEmpty();
// });
//
// extracting.withAmountThreshold(stack -> {
// ItemStack tester = stack.copy();
// tester.setCount(tester.getMaxStackSize());
// return stack.getCount() - ItemHandlerHelper.insertItemStacked(inv, stack, true).getCount();
// });
//
// extracting.setCallback(stack -> {
// ItemHandlerHelper.insertItemStacked(inv, stack, false);
// });
//
// success = extracting.extract() && filtering.anyAmount();
// extracting.setSynchronized(true);
// transposer.applyFilteringCallbacks();
// extracting.setCallback(transposer::onExtract);
// }
// }
//
// if (!success) {
// reset(context);
// return;
// }
//
// context.data.putInt(_delay_, AllConfigs.SERVER.logistics.extractorDelay.get());
// }
//
// @Override
// public void stopMoving(MovementContext context) {
// reset(context);
// }
//
// public void reset(MovementContext context) {
// context.data.remove(_workingPos_);
// context.data.remove(_delay_);
// context.data.remove(_exporting_);
// context.stall = false;
// }
//
// private TransposerTileEntity getValidTransposer(World world, BlockPos pos, Axis validAxis) {
// TileEntity te = world.getTileEntity(pos);
// if (!(te instanceof TransposerTileEntity))
// return null;
// if (TransposerBlock.getBlockFacing(world.getBlockState(pos)).getAxis() != validAxis)
// return null;
// if (world.isBlockPowered(pos))
// return null;
// return (TransposerTileEntity) te;
// }
//
// private Direction getCurrentFacing(MovementContext context) {
// Vector3d directionVec = new Vector3d(context.state.get(PortableStorageInterfaceBlock.FACING).getDirectionVec());
// directionVec = VecHelper.rotate(directionVec, context.rotation.x, context.rotation.y, context.rotation.z);
// return Direction.getFacingFromVector(directionVec.x, directionVec.y, directionVec.z);
// }
//
//}

View file

@ -5,6 +5,7 @@ import java.util.List;
import com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation;
import com.simibubi.create.foundation.item.TooltipHelper;
import com.simibubi.create.foundation.item.TooltipHelper.Palette;
import com.simibubi.create.foundation.utility.Components;
import com.simibubi.create.foundation.utility.Lang;
@ -27,7 +28,7 @@ public interface IDisplayAssemblyExceptions {
String text = e.component.getString();
Arrays.stream(text.split("\n"))
.forEach(l -> TooltipHelper.cutStringTextComponent(l, ChatFormatting.GRAY, ChatFormatting.WHITE)
.forEach(l -> TooltipHelper.cutStringTextComponent(l, Palette.GRAY_AND_WHITE)
.forEach(c -> tooltip.add(IHaveGoggleInformation.componentSpacing.plainCopy()
.append(c))));

View file

@ -6,7 +6,7 @@ import java.util.List;
import javax.annotation.Nonnull;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.Create;
import com.simibubi.create.AllCreativeModeTabs;
import com.simibubi.create.content.contraptions.base.KineticBlockEntity;
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock;
import com.simibubi.create.content.contraptions.relays.belt.BeltPart;
@ -50,7 +50,7 @@ public class BeltConnectorItem extends BlockItem {
@Override
public void fillItemCategory(CreativeModeTab p_150895_1_, NonNullList<ItemStack> p_150895_2_) {
if (p_150895_1_ == Create.BASE_CREATIVE_TAB)
if (p_150895_1_ == AllCreativeModeTabs.BASE_CREATIVE_TAB)
return;
super.fillItemCategory(p_150895_1_, p_150895_2_);
}

View file

@ -17,6 +17,7 @@ import com.simibubi.create.CreateClient;
import com.simibubi.create.foundation.blockEntity.BlockEntityBehaviour;
import com.simibubi.create.foundation.blockEntity.behaviour.linked.LinkBehaviour;
import com.simibubi.create.foundation.item.TooltipHelper;
import com.simibubi.create.foundation.item.TooltipHelper.Palette;
import com.simibubi.create.foundation.networking.AllPackets;
import com.simibubi.create.foundation.utility.Components;
import com.simibubi.create.foundation.utility.ControlsUtil;
@ -236,7 +237,7 @@ public class LinkedControllerClientHandler {
list.add(Lang.translateDirect("linked_controller.bind_mode")
.withStyle(ChatFormatting.GOLD));
list.addAll(TooltipHelper.cutTextComponent(Lang.translateDirect("linked_controller.press_keybind", keys),
ChatFormatting.GRAY, ChatFormatting.GRAY));
Palette.ALL_GRAY));
int width = 0;
int height = list.size() * mc.font.lineHeight;

View file

@ -1,7 +1,6 @@
package com.simibubi.create.content.logistics.item.filter;
import static com.simibubi.create.foundation.gui.AllGuiTextures.PLAYER_INVENTORY;
import static net.minecraft.ChatFormatting.GRAY;
import java.util.Collections;
import java.util.List;
@ -16,8 +15,8 @@ import com.simibubi.create.foundation.gui.menu.AbstractSimiContainerScreen;
import com.simibubi.create.foundation.gui.widget.IconButton;
import com.simibubi.create.foundation.gui.widget.Indicator;
import com.simibubi.create.foundation.gui.widget.Indicator.State;
import com.simibubi.create.foundation.item.ItemDescription.Palette;
import com.simibubi.create.foundation.item.TooltipHelper;
import com.simibubi.create.foundation.item.TooltipHelper.Palette;
import com.simibubi.create.foundation.networking.AllPackets;
import net.minecraft.client.renderer.Rect2i;
@ -142,7 +141,7 @@ public abstract class AbstractFilterScreen<F extends AbstractFilterMenu> extends
if (!button.isHoveredOrFocused())
return;
List<Component> tip = button.getToolTip();
tip.addAll(TooltipHelper.cutTextComponent(tooltip, GRAY, GRAY));
tip.addAll(TooltipHelper.cutTextComponent(tooltip, Palette.ALL_GRAY));
}
protected void contentsCleared() {}

View file

@ -8,6 +8,7 @@ import static com.simibubi.create.foundation.data.WindowGen.framedGlassPane;
import static com.simibubi.create.foundation.data.WindowGen.woodenWindowBlock;
import static com.simibubi.create.foundation.data.WindowGen.woodenWindowPane;
import com.simibubi.create.AllCreativeModeTabs;
import com.simibubi.create.AllSpriteShifts;
import com.simibubi.create.Create;
import com.simibubi.create.foundation.block.connected.HorizontalCTBehaviour;
@ -30,7 +31,7 @@ import net.minecraftforge.common.Tags;
public class AllPaletteBlocks {
static {
REGISTRATE.creativeModeTab(() -> Create.PALETTES_CREATIVE_TAB);
REGISTRATE.creativeModeTab(() -> AllCreativeModeTabs.PALETTES_CREATIVE_TAB);
}
// Windows and Glass

View file

@ -21,8 +21,8 @@ import com.simibubi.create.foundation.gui.menu.AbstractSimiContainerScreen;
import com.simibubi.create.foundation.gui.widget.IconButton;
import com.simibubi.create.foundation.gui.widget.Indicator;
import com.simibubi.create.foundation.gui.widget.Indicator.State;
import com.simibubi.create.foundation.item.ItemDescription.Palette;
import com.simibubi.create.foundation.item.TooltipHelper;
import com.simibubi.create.foundation.item.TooltipHelper.Palette;
import com.simibubi.create.foundation.networking.AllPackets;
import com.simibubi.create.foundation.utility.Components;
import com.simibubi.create.foundation.utility.Lang;
@ -267,7 +267,7 @@ public class SchematicannonScreen extends AbstractSimiContainerScreen<Schematica
tip.add((enabled ? optionEnabled : optionDisabled).plainCopy()
.withStyle(BLUE));
tip.addAll(TooltipHelper
.cutTextComponent(Lang.translateDirect("gui.schematicannon.option." + tooltipKey + ".description"), GRAY, GRAY));
.cutTextComponent(Lang.translateDirect("gui.schematicannon.option." + tooltipKey + ".description"), Palette.ALL_GRAY));
}
@Override
@ -357,13 +357,13 @@ public class SchematicannonScreen extends AbstractSimiContainerScreen<Schematica
if (hoveredSlot != null && !hoveredSlot.hasItem()) {
if (hoveredSlot.index == 0)
renderComponentTooltip(matrixStack,
TooltipHelper.cutTextComponent(Lang.translateDirect(_slotSchematic), GRAY, BLUE), mouseX, mouseY);
TooltipHelper.cutTextComponent(Lang.translateDirect(_slotSchematic), Palette.GRAY_AND_BLUE), mouseX, mouseY);
if (hoveredSlot.index == 2)
renderComponentTooltip(matrixStack,
TooltipHelper.cutTextComponent(Lang.translateDirect(_slotListPrinter), GRAY, BLUE), mouseX, mouseY);
TooltipHelper.cutTextComponent(Lang.translateDirect(_slotListPrinter), Palette.GRAY_AND_BLUE), mouseX, mouseY);
if (hoveredSlot.index == 4)
renderComponentTooltip(matrixStack,
TooltipHelper.cutTextComponent(Lang.translateDirect(_slotGunpowder), GRAY, BLUE), mouseX, mouseY);
TooltipHelper.cutTextComponent(Lang.translateDirect(_slotGunpowder), Palette.GRAY_AND_BLUE), mouseX, mouseY);
}
if (be.missingItem != null) {

View file

@ -22,7 +22,7 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemp
public class SchematicInstances {
public static WorldAttached<Cache<Integer, SchematicWorld>> loadedSchematics;
public static final WorldAttached<Cache<Integer, SchematicWorld>> loadedSchematics;
static {
loadedSchematics = new WorldAttached<>($ -> CacheBuilder.newBuilder()

View file

@ -49,7 +49,7 @@ import com.simibubi.create.foundation.blockEntity.behaviour.scrollvalue.ScrollVa
import com.simibubi.create.foundation.config.AllConfigs;
import com.simibubi.create.foundation.config.ui.BaseConfigScreen;
import com.simibubi.create.foundation.fluid.FluidHelper;
import com.simibubi.create.foundation.item.ItemTooltipHandler;
import com.simibubi.create.foundation.item.TooltipModifier;
import com.simibubi.create.foundation.networking.AllPackets;
import com.simibubi.create.foundation.networking.LeftClickPacket;
import com.simibubi.create.foundation.ponder.PonderTooltipHandler;
@ -66,6 +66,7 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.entity.EntityRenderDispatcher;
import net.minecraft.core.BlockPos;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
@ -239,7 +240,12 @@ public class ClientEvents {
if (event.getPlayer() == null)
return;
ItemTooltipHandler.addToTooltip(event);
Item item = event.getItemStack().getItem();
TooltipModifier modifier = TooltipModifier.REGISTRY.get(item);
if (modifier != null && modifier != TooltipModifier.EMPTY) {
modifier.modify(event);
}
PonderTooltipHandler.addToTooltip(event);
SequencedAssemblyRecipe.addToTooltip(event);
}

View file

@ -21,9 +21,9 @@ import com.simibubi.create.foundation.gui.element.DelegatedStencilElement;
import com.simibubi.create.foundation.gui.element.TextStencilElement;
import com.simibubi.create.foundation.gui.widget.BoxWidget;
import com.simibubi.create.foundation.item.TooltipHelper;
import com.simibubi.create.foundation.item.TooltipHelper.Palette;
import com.simibubi.create.foundation.utility.Components;
import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.screens.Screen;
import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.fml.config.ModConfig;
@ -185,7 +185,7 @@ public class BaseConfigScreen extends ConfigScreen {
.addAll(TooltipHelper.cutTextComponent(
Components.literal(
"Gameplay settings can only be accessed from the in-game menu after joining a World or Server."),
ChatFormatting.GRAY, ChatFormatting.GRAY));
Palette.ALL_GRAY));
} else {
serverConfigWidget.withCallback(() -> linkTo(new SubMenuConfigScreen(this, ModConfig.Type.SERVER, serverSpec)));
serverText.withElementRenderer(BoxWidget.gradientFactory.apply(serverConfigWidget));

View file

@ -13,9 +13,9 @@ import com.simibubi.create.foundation.gui.Theme;
import com.simibubi.create.foundation.gui.element.DelegatedStencilElement;
import com.simibubi.create.foundation.gui.widget.BoxWidget;
import com.simibubi.create.foundation.item.TooltipHelper;
import com.simibubi.create.foundation.item.TooltipHelper.Palette;
import com.simibubi.create.foundation.utility.Components;
import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.screens.Screen;
import net.minecraftforge.fml.ModList;
import net.minecraftforge.forgespi.language.IModInfo;
@ -113,7 +113,7 @@ public class ConfigModListScreen extends ConfigScreen {
button.updateColorsFromState();
button.modifyElement(e -> ((DelegatedStencilElement) e).withElementRenderer(BaseConfigScreen.DISABLED_RENDERER));
labelTooltip.add(Components.literal(toHumanReadable(id)));
labelTooltip.addAll(TooltipHelper.cutTextComponent(Components.literal("This Mod does not have any configs registered or is not using Forge's config system"), ChatFormatting.GRAY, ChatFormatting.GRAY));
labelTooltip.addAll(TooltipHelper.cutStringTextComponent("This Mod does not have any configs registered or is not using Forge's config system", Palette.ALL_GRAY));
}
listeners.add(button);

View file

@ -35,6 +35,7 @@ import com.simibubi.create.foundation.gui.UIRenderHelper;
import com.simibubi.create.foundation.gui.element.DelegatedStencilElement;
import com.simibubi.create.foundation.gui.widget.BoxWidget;
import com.simibubi.create.foundation.item.TooltipHelper;
import com.simibubi.create.foundation.item.TooltipHelper.Palette;
import com.simibubi.create.foundation.networking.AllPackets;
import com.simibubi.create.foundation.utility.Color;
import com.simibubi.create.foundation.utility.Components;
@ -193,7 +194,7 @@ public class SubMenuConfigScreen extends ConfigScreen {
resetAll.showingElement(AllIcons.I_CONFIG_RESET.asStencil().withElementRenderer(BoxWidget.gradientFactory.apply(resetAll)));
resetAll.getToolTip().add(Components.literal("Reset All"));
resetAll.getToolTip().addAll(TooltipHelper.cutStringTextComponent("Click here to reset all settings to their default value.", ChatFormatting.GRAY, ChatFormatting.GRAY));
resetAll.getToolTip().addAll(TooltipHelper.cutStringTextComponent("Click here to reset all settings to their default value.", Palette.ALL_GRAY));
saveChanges = new BoxWidget(listL - 30, yCenter - 25, 20, 20)
.withPadding(2, 2)
@ -213,7 +214,7 @@ public class SubMenuConfigScreen extends ConfigScreen {
});
saveChanges.showingElement(AllIcons.I_CONFIG_SAVE.asStencil().withElementRenderer(BoxWidget.gradientFactory.apply(saveChanges)));
saveChanges.getToolTip().add(Components.literal("Save Changes"));
saveChanges.getToolTip().addAll(TooltipHelper.cutStringTextComponent("Click here to save your current changes.", ChatFormatting.GRAY, ChatFormatting.GRAY));
saveChanges.getToolTip().addAll(TooltipHelper.cutStringTextComponent("Click here to save your current changes.", Palette.ALL_GRAY));
discardChanges = new BoxWidget(listL - 30, yCenter + 5, 20, 20)
.withPadding(2, 2)
@ -232,7 +233,7 @@ public class SubMenuConfigScreen extends ConfigScreen {
});
discardChanges.showingElement(AllIcons.I_CONFIG_DISCARD.asStencil().withElementRenderer(BoxWidget.gradientFactory.apply(discardChanges)));
discardChanges.getToolTip().add(Components.literal("Discard Changes"));
discardChanges.getToolTip().addAll(TooltipHelper.cutStringTextComponent("Click here to discard all the changes you made.", ChatFormatting.GRAY, ChatFormatting.GRAY));
discardChanges.getToolTip().addAll(TooltipHelper.cutStringTextComponent("Click here to discard all the changes you made.", Palette.ALL_GRAY));
goBack = new BoxWidget(listL - 30, yCenter + 65, 20, 20)
.withPadding(2, 2)
@ -332,13 +333,13 @@ public class SubMenuConfigScreen extends ConfigScreen {
stencil.withElementRenderer((ms, w, h, alpha) -> UIRenderHelper.angledGradient(ms, 90, 8, 0, 16, 16, red));
serverLocked.withBorderColors(red);
serverLocked.getToolTip().add(Components.literal("Locked").withStyle(ChatFormatting.BOLD));
serverLocked.getToolTip().addAll(TooltipHelper.cutStringTextComponent("You do not have enough permissions to edit the server config. You can still look at the current values here though.", ChatFormatting.GRAY, ChatFormatting.GRAY));
serverLocked.getToolTip().addAll(TooltipHelper.cutStringTextComponent("You do not have enough permissions to edit the server config. You can still look at the current values here though.", Palette.ALL_GRAY));
} else {
stencil.withStencilRenderer((ms, w, h, alpha) -> AllIcons.I_CONFIG_UNLOCKED.render(ms, 0, 0));
stencil.withElementRenderer((ms, w, h, alpha) -> UIRenderHelper.angledGradient(ms, 90, 8, 0, 16, 16, green));
serverLocked.withBorderColors(green);
serverLocked.getToolTip().add(Components.literal("Unlocked").withStyle(ChatFormatting.BOLD));
serverLocked.getToolTip().addAll(TooltipHelper.cutStringTextComponent("You have enough permissions to edit the server config. Changes you make here will be synced with the server when you save them.", ChatFormatting.GRAY, ChatFormatting.GRAY));
serverLocked.getToolTip().addAll(TooltipHelper.cutStringTextComponent("You have enough permissions to edit the server config. Changes you make here will be synced with the server when you save them.", Palette.ALL_GRAY));
}
addRenderableWidget(serverLocked);

View file

@ -18,6 +18,7 @@ import com.simibubi.create.foundation.gui.AllIcons;
import com.simibubi.create.foundation.gui.element.DelegatedStencilElement;
import com.simibubi.create.foundation.gui.widget.BoxWidget;
import com.simibubi.create.foundation.item.TooltipHelper;
import com.simibubi.create.foundation.item.TooltipHelper.Palette;
import com.simibubi.create.foundation.utility.Components;
import com.simibubi.create.foundation.utility.Pair;
@ -70,15 +71,15 @@ public class ValueEntry<T> extends ConfigScreenList.LabeledEntry {
.filter(Predicates.not(s -> s.startsWith("Range")))
.filter(s -> !s.equals("."))
.map(Components::literal)
.flatMap(stc -> TooltipHelper.cutTextComponent(stc, ChatFormatting.GRAY, ChatFormatting.GRAY)
.flatMap(stc -> TooltipHelper.cutTextComponent(stc, Palette.ALL_GRAY)
.stream())
.collect(Collectors.toList()));
if (annotations.containsKey(ConfigAnnotations.RequiresRelog.TRUE.getName()))
labelTooltip.addAll(TooltipHelper.cutTextComponent(Components.literal("Changing this value will require a _relog_ to take full effect"), ChatFormatting.GRAY, ChatFormatting.GOLD));
labelTooltip.addAll(TooltipHelper.cutStringTextComponent("Changing this value will require a _relog_ to take full effect", Palette.GRAY_AND_GOLD));
if (annotations.containsKey(ConfigAnnotations.RequiresRestart.CLIENT.getName()))
labelTooltip.addAll(TooltipHelper.cutTextComponent(Components.literal("Changing this value will require a _restart_ to take full effect"), ChatFormatting.GRAY, ChatFormatting.RED));
labelTooltip.addAll(TooltipHelper.cutStringTextComponent("Changing this value will require a _restart_ to take full effect", Palette.GRAY_AND_RED));
labelTooltip.add(Components.literal(ConfigScreen.modID + ":" + path.get(path.size() - 1)).withStyle(ChatFormatting.DARK_GRAY));
}

View file

@ -4,25 +4,33 @@ import static com.simibubi.create.foundation.data.TagGen.pickaxeOnly;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
import org.jetbrains.annotations.Nullable;
import com.simibubi.create.Create;
import com.simibubi.create.CreateClient;
import com.simibubi.create.content.contraptions.fluids.VirtualFluid;
import com.simibubi.create.content.contraptions.relays.encased.CasingConnectivity;
import com.simibubi.create.foundation.block.connected.CTModel;
import com.simibubi.create.foundation.block.connected.ConnectedTextureBehaviour;
import com.simibubi.create.foundation.item.TooltipModifier;
import com.simibubi.create.foundation.utility.RegisteredObjects;
import com.tterrag.registrate.AbstractRegistrate;
import com.tterrag.registrate.builders.BlockBuilder;
import com.tterrag.registrate.builders.BlockEntityBuilder.BlockEntityFactory;
import com.tterrag.registrate.builders.Builder;
import com.tterrag.registrate.builders.FluidBuilder;
import com.tterrag.registrate.util.entry.RegistryEntry;
import com.tterrag.registrate.util.nullness.NonNullBiFunction;
import com.tterrag.registrate.util.nullness.NonNullConsumer;
import com.tterrag.registrate.util.nullness.NonNullFunction;
import com.tterrag.registrate.util.nullness.NonNullSupplier;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.BlockTags;
import net.minecraft.world.entity.Entity;
@ -39,8 +47,13 @@ import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fluids.FluidAttributes;
import net.minecraftforge.fluids.ForgeFlowingFluid;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.registries.IForgeRegistryEntry;
import net.minecraftforge.registries.RegistryObject;
public class CreateRegistrate extends AbstractRegistrate<CreateRegistrate> {
@Nullable
protected Function<Item, TooltipModifier> currentTooltipModifierFactory;
protected CreateRegistrate(String modid) {
super(modid);
}
@ -49,11 +62,32 @@ public class CreateRegistrate extends AbstractRegistrate<CreateRegistrate> {
return new CreateRegistrate(modid);
}
public CreateRegistrate setTooltipModifierFactory(@Nullable Function<Item, TooltipModifier> factory) {
currentTooltipModifierFactory = factory;
return self();
}
@Nullable
public Function<Item, TooltipModifier> getTooltipModifierFactory() {
return currentTooltipModifierFactory;
}
@Override
public CreateRegistrate registerEventListeners(IEventBus bus) {
return super.registerEventListeners(bus);
}
@Override
protected <R extends IForgeRegistryEntry<R>, T extends R> RegistryEntry<T> accept(String name, ResourceKey<? extends Registry<R>> type, Builder<R, T, ?, ?> builder, NonNullSupplier<? extends T> creator, NonNullFunction<RegistryObject<T>, ? extends RegistryEntry<T>> entryFactory) {
RegistryEntry<T> entry = super.accept(name, type, builder, creator, entryFactory);
if (type.equals(Registry.ITEM_REGISTRY)) {
if (currentTooltipModifierFactory != null) {
TooltipModifier.REGISTRY.registerDeferred(entry.getId(), currentTooltipModifierFactory);
}
}
return entry;
}
@Override
public <T extends BlockEntity> CreateBlockEntityBuilder<T, CreateRegistrate> blockEntity(String name,
BlockEntityFactory<T> factory) {

View file

@ -10,6 +10,7 @@ import com.simibubi.create.foundation.config.ui.BaseConfigScreen;
import com.simibubi.create.foundation.gui.element.BoxElement;
import com.simibubi.create.foundation.gui.element.GuiGameElement;
import com.simibubi.create.foundation.item.TooltipHelper;
import com.simibubi.create.foundation.item.TooltipHelper.Palette;
import com.simibubi.create.foundation.ponder.ui.PonderTagIndexScreen;
import com.simibubi.create.foundation.utility.Color;
import com.simibubi.create.foundation.utility.Components;
@ -179,8 +180,8 @@ public class CreateMainMenuScreen extends AbstractSimiScreen {
return;
if (mouseY < gettingStarted.y || mouseY > gettingStarted.y + 20)
return;
renderComponentTooltip(ms, TooltipHelper.cutTextComponent(Lang.translateDirect("menu.only_ingame"), ChatFormatting.GRAY,
ChatFormatting.GRAY), mouseX, mouseY);
renderComponentTooltip(ms, TooltipHelper.cutTextComponent(Lang.translateDirect("menu.only_ingame"), Palette.ALL_GRAY),
mouseX, mouseY);
}
}

View file

@ -1,15 +0,0 @@
package com.simibubi.create.foundation.item;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.items.IItemHandlerModifiable;
interface IItemHandlerModifiableIntermediate extends IItemHandlerModifiable {
@Override
public default ItemStack getStackInSlot(int slot) {
return getStackInSlotIntermediate(slot);
}
public ItemStack getStackInSlotIntermediate(int slot);
}

View file

@ -6,35 +6,53 @@ import static net.minecraft.ChatFormatting.WHITE;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
import org.apache.commons.lang3.tuple.Pair;
import org.jetbrains.annotations.Nullable;
import com.google.common.collect.ImmutableList;
import com.mojang.bridge.game.Language;
import com.simibubi.create.foundation.item.TooltipHelper.Palette;
import com.simibubi.create.foundation.utility.Components;
import com.simibubi.create.foundation.utility.Lang;
import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.resources.language.I18n;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.ItemLike;
import net.minecraftforge.event.entity.player.ItemTooltipEvent;
public record ItemDescription(ImmutableList<Component> lines, ImmutableList<Component> linesOnShift, ImmutableList<Component> linesOnCtrl) {
public static final ItemDescription MISSING = new ItemDescription(ImmutableList.of(), ImmutableList.of(), ImmutableList.of());
private static final Map<Item, Supplier<String>> CUSTOM_TOOLTIP_KEYS = new IdentityHashMap<>();
public static Builder builder() {
return new Builder();
@Nullable
public static ItemDescription create(Item item, Palette palette) {
return create(getTooltipTranslationKey(item), palette);
}
public static ItemDescription create(Palette palette, String translationKey) {
if (!I18n.exists(translationKey)) {
return MISSING;
@Nullable
public static ItemDescription create(String translationKey, Palette palette) {
if (!canFillBuilder(translationKey)) {
return null;
}
Builder builder = builder();
builder.palette(palette);
Builder builder = new Builder(palette);
fillBuilder(builder, translationKey);
return builder.build();
}
public static boolean canFillBuilder(String translationKey) {
return I18n.exists(translationKey);
}
public static void fillBuilder(Builder builder, String translationKey) {
// Summary
String summaryKey = translationKey + ".summary";
if (I18n.exists(summaryKey)) {
@ -58,38 +76,48 @@ public record ItemDescription(ImmutableList<Component> lines, ImmutableList<Comp
break;
builder.addAction(I18n.get(controlKey), I18n.get(actionKey));
}
return builder.build();
}
public void addInformation(List<Component> tooltip) {
public static void useKey(Item item, Supplier<String> supplier) {
CUSTOM_TOOLTIP_KEYS.put(item, supplier);
}
public static void useKey(ItemLike item, String string) {
useKey(item.asItem(), () -> string);
}
public static void referKey(ItemLike item, Supplier<? extends ItemLike> otherItem) {
useKey(item.asItem(), () -> otherItem.get()
.asItem()
.getDescriptionId());
}
public static String getTooltipTranslationKey(Item item) {
if (CUSTOM_TOOLTIP_KEYS.containsKey(item)) {
return CUSTOM_TOOLTIP_KEYS.get(item).get() + ".tooltip";
}
return item.getDescriptionId() + ".tooltip";
}
public ImmutableList<Component> getCurrentLines() {
if (Screen.hasShiftDown()) {
tooltip.addAll(linesOnShift);
return;
return linesOnShift;
} else if (Screen.hasControlDown()) {
return linesOnCtrl;
} else {
return lines;
}
if (Screen.hasControlDown()) {
tooltip.addAll(linesOnCtrl);
return;
}
tooltip.addAll(lines);
}
public record Palette(ChatFormatting primary, ChatFormatting highlight) {
public static final Palette BLUE = new Palette(ChatFormatting.BLUE, ChatFormatting.AQUA);
public static final Palette GREEN = new Palette(ChatFormatting.DARK_GREEN, ChatFormatting.GREEN);
public static final Palette YELLOW = new Palette(ChatFormatting.GOLD, ChatFormatting.YELLOW);
public static final Palette RED = new Palette(ChatFormatting.DARK_RED, ChatFormatting.RED);
public static final Palette PURPLE = new Palette(ChatFormatting.DARK_PURPLE, ChatFormatting.LIGHT_PURPLE);
public static final Palette GRAY = new Palette(ChatFormatting.DARK_GRAY, ChatFormatting.GRAY);
}
public static class Builder {
protected final Palette palette;
protected final List<String> summary = new ArrayList<>();
protected final List<Pair<String, String>> behaviours = new ArrayList<>();
protected final List<Pair<String, String>> actions = new ArrayList<>();
protected Palette palette;
public Builder(Palette palette) {
this.palette = palette;
}
public Builder addSummary(String summaryLine) {
summary.add(summaryLine);
@ -106,18 +134,13 @@ public record ItemDescription(ImmutableList<Component> lines, ImmutableList<Comp
return this;
}
public Builder palette(Palette palette) {
this.palette = palette;
return this;
}
public ItemDescription build() {
List<Component> lines = new ArrayList<>();
List<Component> linesOnShift = new ArrayList<>();
List<Component> linesOnCtrl = new ArrayList<>();
for (String summaryLine : summary) {
linesOnShift.addAll(TooltipHelper.cutTextComponent(Components.literal(summaryLine), palette.primary(), palette.highlight()));
linesOnShift.addAll(TooltipHelper.cutStringTextComponent(summaryLine, palette));
}
if (!behaviours.isEmpty()) {
@ -194,4 +217,38 @@ public record ItemDescription(ImmutableList<Component> lines, ImmutableList<Comp
return new ItemDescription(ImmutableList.copyOf(lines), ImmutableList.copyOf(linesOnShift), ImmutableList.copyOf(linesOnCtrl));
}
}
public static class Modifier implements TooltipModifier {
protected final Item item;
protected final Palette palette;
protected Language cachedLanguage;
protected ItemDescription description;
public Modifier(Item item, Palette palette) {
this.item = item;
this.palette = palette;
}
@Override
public void modify(ItemTooltipEvent context) {
if (checkLocale()) {
description = create(item, palette);
}
if (description == null) {
return;
}
context.getToolTip().addAll(1, description.getCurrentLines());
}
protected boolean checkLocale() {
Language currentLanguage = Minecraft.getInstance()
.getLanguageManager()
.getSelected();
if (cachedLanguage != currentLanguage) {
cachedLanguage = currentLanguage;
return true;
}
return false;
}
}
}

View file

@ -4,17 +4,10 @@ import static net.minecraft.ChatFormatting.DARK_GRAY;
import static net.minecraft.ChatFormatting.GRAY;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Supplier;
import org.jetbrains.annotations.Nullable;
import com.mojang.bridge.game.Language;
import com.simibubi.create.Create;
import com.simibubi.create.content.contraptions.base.IRotate;
import com.simibubi.create.content.contraptions.base.IRotate.StressImpact;
import com.simibubi.create.content.contraptions.components.steam.SteamEngineBlock;
@ -27,101 +20,39 @@ import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.LangBuilder;
import net.minecraft.client.Minecraft;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.block.Block;
import net.minecraftforge.event.entity.player.ItemTooltipEvent;
public class ItemTooltipHandler {
private static final String ITEM_PREFIX = "item." + Create.ID;
private static final String BLOCK_PREFIX = "block." + Create.ID;
public class KineticStats implements TooltipModifier {
protected final Block block;
private static final Map<Item, Function<ItemStack, String>> TOOLTIP_REFERRALS = new IdentityHashMap<>();
private static final Map<String, ItemDescription> TOOLTIP_CACHE = new HashMap<>();
private static Language cachedLanguage;
public static void referTo(ItemLike item, Function<ItemStack, String> func) {
TOOLTIP_REFERRALS.put(item.asItem(), func);
}
public static void referTo(ItemLike item, Supplier<? extends ItemLike> itemWithTooltip) {
referTo(item, stack -> itemWithTooltip.get()
.asItem()
.getDescriptionId());
}
public static void referTo(ItemLike item, String string) {
referTo(item, stack -> string);
}
public static void addToTooltip(ItemTooltipEvent event) {
ItemStack stack = event.getItemStack();
List<Component> tooltip = event.getToolTip();
String translationKey = stack.getDescriptionId();
if (translationKey.startsWith(ITEM_PREFIX) || translationKey.startsWith(BLOCK_PREFIX)) {
ItemDescription desc = getOrCreateTooltip(stack);
if (desc != null) {
List<Component> descTooltip = new ArrayList<>();
desc.addInformation(descTooltip);
tooltip.addAll(1, descTooltip);
}
}
if (stack.getItem() instanceof BlockItem blockItem) {
Block block = blockItem.getBlock();
if (block instanceof IRotate || block instanceof SteamEngineBlock) {
List<Component> kineticStats = getKineticStats(block, event.getPlayer());
if (!kineticStats.isEmpty()) {
tooltip.add(Components.immutableEmpty());
tooltip.addAll(kineticStats);
}
}
}
}
private static void checkLocale() {
Language currentLanguage = Minecraft.getInstance()
.getLanguageManager()
.getSelected();
if (cachedLanguage != currentLanguage) {
cachedLanguage = currentLanguage;
TOOLTIP_CACHE.clear();
}
}
public static String getTooltipTranslationKey(ItemStack stack) {
Item item = stack.getItem();
if (TOOLTIP_REFERRALS.containsKey(item)) {
return TOOLTIP_REFERRALS.get(item)
.apply(stack) + ".tooltip";
}
return stack.getDescriptionId() + ".tooltip";
public KineticStats(Block block) {
this.block = block;
}
@Nullable
public static ItemDescription getOrCreateTooltip(ItemStack stack) {
checkLocale();
String key = getTooltipTranslationKey(stack);
ItemDescription desc = TOOLTIP_CACHE.get(key);
if (desc == null) {
// TODO 0.5.1: Decide on colors and defer creation to registered factory/type based on key or item
desc = ItemDescription.create(ItemDescription.Palette.GRAY, key);
TOOLTIP_CACHE.put(key, desc);
public static KineticStats create(Item item) {
if (item instanceof BlockItem blockItem) {
Block block = blockItem.getBlock();
if (block instanceof IRotate || block instanceof SteamEngineBlock) {
return new KineticStats(block);
}
}
return null;
}
if (desc == ItemDescription.MISSING) {
return null;
@Override
public void modify(ItemTooltipEvent context) {
List<Component> kineticStats = getKineticStats(block, context.getPlayer());
if (!kineticStats.isEmpty()) {
List<Component> tooltip = context.getToolTip();
tooltip.add(Components.immutableEmpty());
tooltip.addAll(kineticStats);
}
return desc;
}
public static List<Component> getKineticStats(Block block, Player player) {

View file

@ -9,11 +9,12 @@ import com.simibubi.create.foundation.blockEntity.SyncedBlockEntity;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.common.util.INBTSerializable;
import net.minecraftforge.items.IItemHandlerModifiable;
import net.minecraftforge.items.ItemStackHandler;
import net.minecraftforge.items.wrapper.RecipeWrapper;
public class SmartInventory extends RecipeWrapper
implements IItemHandlerModifiableIntermediate, INBTSerializable<CompoundTag> {
implements IItemHandlerModifiable, INBTSerializable<CompoundTag> {
protected boolean extractionAllowed;
protected boolean insertionAllowed;
@ -100,13 +101,13 @@ public class SmartInventory extends RecipeWrapper
}
@Override
public void setStackInSlot(int slot, ItemStack stack) {
inv.setStackInSlot(slot, stack);
public ItemStack getStackInSlot(int slot) {
return inv.getStackInSlot(slot);
}
@Override
public ItemStack getItem(int slot) {
return super.getItem(slot);
public void setStackInSlot(int slot, ItemStack stack) {
inv.setStackInSlot(slot, stack);
}
public int getStackLimit(int slot, @Nonnull ItemStack stack) {
@ -160,9 +161,4 @@ public class SmartInventory extends RecipeWrapper
}
@Override
public ItemStack getStackInSlotIntermediate(int slot) {
return getItem(slot);
}
}

View file

@ -7,10 +7,8 @@ import java.util.List;
import com.google.common.base.Strings;
import com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation;
import com.simibubi.create.foundation.item.ItemDescription.Palette;
import com.simibubi.create.foundation.utility.Components;
import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.FontHelper;
import com.simibubi.create.foundation.utility.Lang;
import net.minecraft.ChatFormatting;
@ -18,13 +16,14 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.network.chat.Style;
import net.minecraftforge.client.MinecraftForgeClient;
public class TooltipHelper {
public static final int MAX_WIDTH_PER_LINE = 200;
public static MutableComponent holdShift(Palette color, boolean highlighted) {
public static MutableComponent holdShift(Palette palette, boolean highlighted) {
return Lang.translateDirect("tooltip.holdForDescription", Lang.translateDirect("tooltip.keyShift")
.withStyle(ChatFormatting.GRAY))
.withStyle(ChatFormatting.DARK_GRAY);
@ -36,7 +35,7 @@ public class TooltipHelper {
.append(Lang.translateDirect(hintKey + ".title"))
.withStyle(ChatFormatting.GOLD));
Component hint = Lang.translateDirect(hintKey);
List<Component> cutComponent = TooltipHelper.cutTextComponent(hint, ChatFormatting.GRAY, ChatFormatting.WHITE);
List<Component> cutComponent = cutTextComponent(hint, Palette.GRAY_AND_WHITE);
for (Component component : cutComponent)
tooltip.add(spacing.plainCopy()
.append(component));
@ -52,71 +51,44 @@ public class TooltipHelper {
return bar + " ";
}
@Deprecated
public static List<String> cutString(Component s, ChatFormatting defaultColor, ChatFormatting highlightColor) {
return cutString(s.getString(), defaultColor, highlightColor, 0);
public static Style styleFromColor(ChatFormatting color) {
return Style.EMPTY.applyFormat(color);
}
@Deprecated
public static List<String> cutString(String s, ChatFormatting defaultColor, ChatFormatting highlightColor,
int indent) {
// Apply markup
String markedUp = s.replaceAll("_([^_]+)_", highlightColor + "$1" + defaultColor);
// Split words
List<String> words = new LinkedList<>();
BreakIterator iterator = BreakIterator.getLineInstance(MinecraftForgeClient.getLocale());
iterator.setText(markedUp);
int start = iterator.first();
for (int end = iterator.next(); end != BreakIterator.DONE; start = end, end = iterator.next()) {
String word = markedUp.substring(start, end);
words.add(word);
}
Font font = Minecraft.getInstance().font;
List<String> lines = FontHelper.cutString(font, markedUp, MAX_WIDTH_PER_LINE);
// Format
String lineStart = Strings.repeat(" ", indent);
List<String> formattedLines = new ArrayList<>(lines.size());
String format = defaultColor.toString();
for (String line : lines) {
String formattedLine = format + lineStart + line;
formattedLines.add(formattedLine);
// format = TextFormatting.getFormatString(formattedLine);
}
return formattedLines;
public static List<Component> cutStringTextComponent(String s, Palette palette) {
return cutTextComponent(Components.literal(s), palette);
}
public static List<Component> cutStringTextComponent(String c, ChatFormatting defaultColor,
ChatFormatting highlightColor) {
return cutTextComponent(Components.literal(c), defaultColor, highlightColor, 0);
public static List<Component> cutTextComponent(Component c, Palette palette) {
return cutTextComponent(c, palette.primary(), palette.highlight());
}
public static List<Component> cutTextComponent(Component c, ChatFormatting defaultColor,
ChatFormatting highlightColor) {
return cutTextComponent(c, defaultColor, highlightColor, 0);
public static List<Component> cutStringTextComponent(String s, Style primaryStyle,
Style highlightStyle) {
return cutTextComponent(Components.literal(s), primaryStyle, highlightStyle);
}
public static List<Component> cutStringTextComponent(String c, ChatFormatting defaultColor,
ChatFormatting highlightColor, int indent) {
return cutTextComponent(Components.literal(c), defaultColor, highlightColor, indent);
public static List<Component> cutTextComponent(Component c, Style primaryStyle,
Style highlightStyle) {
return cutTextComponent(c, primaryStyle, highlightStyle, 0);
}
public static List<Component> cutTextComponent(Component c, ChatFormatting defaultColor,
ChatFormatting highlightColor, int indent) {
public static List<Component> cutStringTextComponent(String c, Style primaryStyle,
Style highlightStyle, int indent) {
return cutTextComponent(Components.literal(c), primaryStyle, highlightStyle, indent);
}
public static List<Component> cutTextComponent(Component c, Style primaryStyle,
Style highlightStyle, int indent) {
String s = c.getString();
// Apply markup
String markedUp = s;// .replaceAll("_([^_]+)_", highlightColor + "$1" + defaultColor);
// Split words
List<String> words = new LinkedList<>();
BreakIterator iterator = BreakIterator.getLineInstance(MinecraftForgeClient.getLocale());
iterator.setText(markedUp);
iterator.setText(s);
int start = iterator.first();
for (int end = iterator.next(); end != BreakIterator.DONE; start = end, end = iterator.next()) {
String word = markedUp.substring(start, end);
String word = s.substring(start, end);
words.add(word);
}
@ -147,16 +119,16 @@ public class TooltipHelper {
// Format
MutableComponent lineStart = Components.literal(Strings.repeat(" ", indent));
lineStart.withStyle(defaultColor);
lineStart.withStyle(primaryStyle);
List<Component> formattedLines = new ArrayList<>(lines.size());
Couple<ChatFormatting> f = Couple.create(highlightColor, defaultColor);
Couple<Style> styles = Couple.create(highlightStyle, primaryStyle);
boolean currentlyHighlighted = false;
for (String string : lines) {
MutableComponent currentComponent = lineStart.plainCopy();
String[] split = string.split("_");
for (String part : split) {
currentComponent.append(Components.literal(part).withStyle(f.get(currentlyHighlighted)));
currentComponent.append(Components.literal(part).withStyle(styles.get(currentlyHighlighted)));
currentlyHighlighted = !currentlyHighlighted;
}
@ -167,52 +139,23 @@ public class TooltipHelper {
return formattedLines;
}
// public static List<ITextComponent> cutTextComponentOld(ITextComponent c, TextFormatting defaultColor,
// TextFormatting highlightColor, int indent) {
// IFormattableTextComponent lineStart = StringTextComponent.EMPTY.copy();
// for (int i = 0; i < indent; i++)
// lineStart.append(" ");
// lineStart.formatted(defaultColor);
//
// List<ITextComponent> lines = new ArrayList<>();
// String rawText = getUnformattedDeepText(c);
// String[] words = rawText.split(" ");
// String word;
// IFormattableTextComponent currentLine = lineStart.copy();
//
// boolean firstWord = true;
// boolean lastWord;
//
// // Apply hard wrap
// for (int i = 0; i < words.length; i++) {
// word = words[i];
// lastWord = i == words.length - 1;
//
// if (!lastWord && !firstWord && getComponentLength(currentLine) + word.length() > maxCharsPerLine) {
// lines.add(currentLine);
// currentLine = lineStart.copy();
// firstWord = true;
// }
//
// currentLine.append(new StringTextComponent((firstWord ? "" : " ") + word.replace("_", ""))
// .formatted(word.matches("_([^_]+)_") ? highlightColor : defaultColor));
// firstWord = false;
// }
//
// if (!firstWord) {
// lines.add(currentLine);
// }
//
// return lines;
// }
public record Palette(Style primary, Style highlight) {
public static final Palette BLUE = ofColors(ChatFormatting.BLUE, ChatFormatting.AQUA);
public static final Palette GREEN = ofColors(ChatFormatting.DARK_GREEN, ChatFormatting.GREEN);
public static final Palette YELLOW = ofColors(ChatFormatting.GOLD, ChatFormatting.YELLOW);
public static final Palette RED = ofColors(ChatFormatting.DARK_RED, ChatFormatting.RED);
public static final Palette PURPLE = ofColors(ChatFormatting.DARK_PURPLE, ChatFormatting.LIGHT_PURPLE);
public static final Palette GRAY = ofColors(ChatFormatting.DARK_GRAY, ChatFormatting.GRAY);
// private static int getComponentLength(ITextComponent component) {
// AtomicInteger l = new AtomicInteger();
// TextProcessing.visitFormatted(component, Style.EMPTY, (s, style, charConsumer) -> {
// l.getAndIncrement();
// return true;
// });
// return l.get();
// }
public static final Palette ALL_GRAY = ofColors(ChatFormatting.GRAY, ChatFormatting.GRAY);
public static final Palette GRAY_AND_BLUE = ofColors(ChatFormatting.GRAY, ChatFormatting.BLUE);
public static final Palette GRAY_AND_WHITE = ofColors(ChatFormatting.GRAY, ChatFormatting.WHITE);
public static final Palette GRAY_AND_GOLD = ofColors(ChatFormatting.GRAY, ChatFormatting.GOLD);
public static final Palette GRAY_AND_RED = ofColors(ChatFormatting.GRAY, ChatFormatting.RED);
public static Palette ofColors(ChatFormatting primary, ChatFormatting highlight) {
return new Palette(styleFromColor(primary), styleFromColor(highlight));
}
}
}

View file

@ -0,0 +1,43 @@
package com.simibubi.create.foundation.item;
import org.jetbrains.annotations.Nullable;
import com.simibubi.create.foundation.utility.AttachedRegistry;
import net.minecraft.world.item.Item;
import net.minecraftforge.event.entity.player.ItemTooltipEvent;
import net.minecraftforge.registries.ForgeRegistries;
public interface TooltipModifier {
AttachedRegistry<Item, TooltipModifier> REGISTRY = new AttachedRegistry<>(ForgeRegistries.ITEMS);
TooltipModifier EMPTY = new TooltipModifier() {
@Override
public void modify(ItemTooltipEvent context) {
}
@Override
public TooltipModifier andThen(TooltipModifier after) {
return after;
}
};
void modify(ItemTooltipEvent context);
default TooltipModifier andThen(TooltipModifier after) {
if (after == EMPTY) {
return this;
}
return tooltip -> {
modify(tooltip);
after.modify(tooltip);
};
}
static TooltipModifier mapNull(@Nullable TooltipModifier modifier) {
if (modifier == null) {
return EMPTY;
}
return modifier;
}
}

View file

@ -14,6 +14,7 @@ import com.simibubi.create.foundation.gui.UIRenderHelper;
import com.simibubi.create.foundation.gui.element.BoxElement;
import com.simibubi.create.foundation.gui.element.GuiGameElement;
import com.simibubi.create.foundation.item.TooltipHelper;
import com.simibubi.create.foundation.item.TooltipHelper.Palette;
import com.simibubi.create.foundation.ponder.PonderLocalization;
import com.simibubi.create.foundation.ponder.PonderRegistry;
import com.simibubi.create.foundation.ponder.PonderTag;
@ -21,7 +22,6 @@ import com.simibubi.create.foundation.utility.Components;
import com.simibubi.create.foundation.utility.FontHelper;
import com.simibubi.create.foundation.utility.Lang;
import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.components.events.GuiEventListener;
import net.minecraft.client.renderer.Rect2i;
import net.minecraft.network.chat.Component;
@ -213,7 +213,7 @@ public class PonderTagIndexScreen extends NavigatableSimiScreen {
if (hoveredItem != null) {
List<Component> list = TooltipHelper.cutStringTextComponent(hoveredItem.getDescription(),
ChatFormatting.GRAY, ChatFormatting.GRAY);
Palette.ALL_GRAY);
list.add(0, Components.literal(hoveredItem.getTitle()));
renderComponentTooltip(ms, list, mouseX, mouseY);
}

View file

@ -5,6 +5,7 @@ import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import org.jetbrains.annotations.Nullable;
@ -18,8 +19,9 @@ public class AttachedRegistry<K extends IForgeRegistryEntry<K>, V> {
private static final List<AttachedRegistry<?, ?>> ALL = new ArrayList<>();
protected final IForgeRegistry<K> objectRegistry;
protected final Map<ResourceLocation, V> locationMap = new HashMap<>();
protected final Map<ResourceLocation, V> idMap = new HashMap<>();
protected final Map<K, V> objectMap = new IdentityHashMap<>();
protected final Map<ResourceLocation, Function<K, V>> deferredRegistrations = new HashMap<>();
protected boolean unwrapped = false;
public AttachedRegistry(IForgeRegistry<K> objectRegistry) {
@ -27,15 +29,15 @@ public class AttachedRegistry<K extends IForgeRegistryEntry<K>, V> {
ALL.add(this);
}
public void register(ResourceLocation location, V value) {
public void register(ResourceLocation id, V value) {
if (!unwrapped) {
locationMap.put(location, value);
idMap.put(id, value);
} else {
K object = objectRegistry.getValue(location);
K object = objectRegistry.getValue(id);
if (object != null) {
objectMap.put(object, value);
} else {
Create.LOGGER.warn("Could not get object for location '" + location + "' in AttachedRegistry after unwrapping!");
Create.LOGGER.warn("Could not get object for id '" + id + "' in AttachedRegistry after unwrapping!");
}
}
}
@ -44,25 +46,51 @@ public class AttachedRegistry<K extends IForgeRegistryEntry<K>, V> {
if (unwrapped) {
objectMap.put(object, value);
} else {
ResourceLocation location = objectRegistry.getKey(object);
if (location != null) {
locationMap.put(location, value);
ResourceLocation id = objectRegistry.getKey(object);
if (id != null) {
idMap.put(id, value);
} else {
Create.LOGGER.warn("Could not get location of object '" + object + "' in AttachedRegistry before unwrapping!");
Create.LOGGER.warn("Could not get id of object '" + object + "' in AttachedRegistry before unwrapping!");
}
}
}
public void registerDeferred(ResourceLocation id, Function<K, V> func) {
if (!unwrapped) {
deferredRegistrations.put(id, func);
} else {
K object = objectRegistry.getValue(id);
if (object != null) {
objectMap.put(object, func.apply(object));
} else {
Create.LOGGER.warn("Could not get object for id '" + id + "' in AttachedRegistry after unwrapping!");
}
}
}
public void registerDeferred(K object, Function<K, V> func) {
if (unwrapped) {
objectMap.put(object, func.apply(object));
} else {
ResourceLocation id = objectRegistry.getKey(object);
if (id != null) {
deferredRegistrations.put(id, func);
} else {
Create.LOGGER.warn("Could not get id of object '" + object + "' in AttachedRegistry before unwrapping!");
}
}
}
@Nullable
public V get(ResourceLocation location) {
public V get(ResourceLocation id) {
if (!unwrapped) {
return locationMap.get(location);
return idMap.get(id);
} else {
K object = objectRegistry.getValue(location);
K object = objectRegistry.getValue(id);
if (object != null) {
return objectMap.get(object);
} else {
Create.LOGGER.warn("Could not get object for location '" + location + "' in AttachedRegistry after unwrapping!");
Create.LOGGER.warn("Could not get object for id '" + id + "' in AttachedRegistry after unwrapping!");
return null;
}
}
@ -73,11 +101,11 @@ public class AttachedRegistry<K extends IForgeRegistryEntry<K>, V> {
if (unwrapped) {
return objectMap.get(object);
} else {
ResourceLocation location = objectRegistry.getKey(object);
if (location != null) {
return locationMap.get(location);
ResourceLocation id = objectRegistry.getKey(object);
if (id != null) {
return idMap.get(id);
} else {
Create.LOGGER.warn("Could not get location of object '" + object + "' in AttachedRegistry before unwrapping!");
Create.LOGGER.warn("Could not get id of object '" + object + "' in AttachedRegistry before unwrapping!");
return null;
}
}
@ -88,15 +116,26 @@ public class AttachedRegistry<K extends IForgeRegistryEntry<K>, V> {
}
protected void unwrap() {
for (Map.Entry<ResourceLocation, V> entry : locationMap.entrySet()) {
ResourceLocation location = entry.getKey();
K object = objectRegistry.getValue(location);
deferredRegistrations.forEach((id, func) -> {
K object = objectRegistry.getValue(id);
if (object != null) {
objectMap.put(object, entry.getValue());
objectMap.put(object, func.apply(object));
} else {
Create.LOGGER.warn("Could not get object for location '" + location + "' in AttachedRegistry during unwrapping!");
Create.LOGGER.warn("Could not get object for id '" + id + "' in AttachedRegistry during unwrapping!");
}
}
});
idMap.forEach((id, value) -> {
K object = objectRegistry.getValue(id);
if (object != null) {
objectMap.put(object, value);
} else {
Create.LOGGER.warn("Could not get object for id '" + id + "' in AttachedRegistry during unwrapping!");
}
});
deferredRegistrations.clear();
idMap.clear();
unwrapped = true;
}