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.CreateRegistrate;
import com.simibubi.create.foundation.data.ModelGen; import com.simibubi.create.foundation.data.ModelGen;
import com.simibubi.create.foundation.data.SharedProperties; 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.item.UncontainableBlockItem;
import com.simibubi.create.foundation.utility.ColorHandlers; import com.simibubi.create.foundation.utility.ColorHandlers;
import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Couple;
@ -286,7 +286,7 @@ import net.minecraftforge.common.Tags;
public class AllBlocks { public class AllBlocks {
static { static {
REGISTRATE.creativeModeTab(() -> Create.BASE_CREATIVE_TAB); REGISTRATE.creativeModeTab(() -> AllCreativeModeTabs.BASE_CREATIVE_TAB);
} }
// Schematics // Schematics
@ -573,7 +573,7 @@ public class AllBlocks {
.transform(axeOrPickaxe()) .transform(axeOrPickaxe())
.transform(BuilderTransformers.cuckooClock()) .transform(BuilderTransformers.cuckooClock())
.lang("Cuckoo Clock") .lang("Cuckoo Clock")
.onRegisterAfter(Registry.ITEM_REGISTRY, c -> ItemTooltipHandler.referTo(c, CUCKOO_CLOCK)) .onRegisterAfter(Registry.ITEM_REGISTRY, c -> ItemDescription.referKey(c, CUCKOO_CLOCK))
.register(); .register();
public static final BlockEntry<MillstoneBlock> MILLSTONE = REGISTRATE.block("millstone", MillstoneBlock::new) 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)) .unlockedBy("has_seat", RegistrateRecipeProvider.has(AllItemTags.SEATS.tag))
.save(p, Create.asResource("crafting/kinetics/" + c.getName() + "_from_other_seat")); .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) .tag(AllBlockTags.SEATS.tag)
.item() .item()
.tag(AllItemTags.SEATS.tag) .tag(AllItemTags.SEATS.tag)
@ -2007,7 +2007,7 @@ public class AllBlocks {
.withExistingParent(colourName + "_toolbox", p.modLoc("block/toolbox/block")) .withExistingParent(colourName + "_toolbox", p.modLoc("block/toolbox/block"))
.texture("0", p.modLoc("block/toolbox/" + colourName))); .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) .tag(AllBlockTags.TOOLBOXES.tag)
.item(UncontainableBlockItem::new) .item(UncontainableBlockItem::new)
.model((c, p) -> p.withExistingParent(colourName + "_toolbox", p.modLoc("block/toolbox/item")) .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.CreateRegistrate;
import com.simibubi.create.foundation.data.recipe.CompatMetals; import com.simibubi.create.foundation.data.recipe.CompatMetals;
import com.simibubi.create.foundation.item.HiddenIngredientItem; 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.simibubi.create.foundation.item.TagDependentIngredientItem;
import com.tterrag.registrate.util.entry.ItemEntry; import com.tterrag.registrate.util.entry.ItemEntry;
@ -69,7 +69,7 @@ import net.minecraftforge.common.Tags;
public class AllItems { public class AllItems {
static { static {
REGISTRATE.creativeModeTab(() -> Create.BASE_CREATIVE_TAB); REGISTRATE.creativeModeTab(() -> AllCreativeModeTabs.BASE_CREATIVE_TAB);
} }
// Materials // Materials
@ -275,7 +275,7 @@ public class AllItems {
public static final ItemEntry<SandPaperItem> RED_SAND_PAPER = REGISTRATE.item("red_sand_paper", SandPaperItem::new) public static final ItemEntry<SandPaperItem> RED_SAND_PAPER = REGISTRATE.item("red_sand_paper", SandPaperItem::new)
.tag(AllTags.AllItemTags.SANDPAPER.tag) .tag(AllTags.AllItemTags.SANDPAPER.tag)
.onRegister(s -> ItemTooltipHandler.referTo(s, SAND_PAPER)) .onRegister(s -> ItemDescription.referKey(s, SAND_PAPER))
.register(); .register();
public static final ItemEntry<WrenchItem> WRENCH = REGISTRATE.item("wrench", WrenchItem::new) 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.block.mechanicalArm.AllArmInteractionPointTypes;
import com.simibubi.create.content.logistics.trains.GlobalRailwayManager; import com.simibubi.create.content.logistics.trains.GlobalRailwayManager;
import com.simibubi.create.content.palettes.AllPaletteBlocks; 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.ServerSchematicLoader;
import com.simibubi.create.content.schematics.filtering.SchematicInstances; import com.simibubi.create.content.schematics.filtering.SchematicInstances;
import com.simibubi.create.foundation.advancement.AllAdvancements; 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.ProcessingRecipeGen;
import com.simibubi.create.foundation.data.recipe.SequencedAssemblyRecipeGen; import com.simibubi.create.foundation.data.recipe.SequencedAssemblyRecipeGen;
import com.simibubi.create.foundation.data.recipe.StandardRecipeGen; 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.networking.AllPackets;
import com.simibubi.create.foundation.utility.AttachedRegistry; import com.simibubi.create.foundation.utility.AttachedRegistry;
import com.simibubi.create.foundation.worldgen.AllFeatures; import com.simibubi.create.foundation.worldgen.AllFeatures;
@ -48,7 +50,6 @@ import net.minecraft.data.DataGenerator;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundEvent;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.common.ForgeMod; import net.minecraftforge.common.ForgeMod;
@ -81,8 +82,13 @@ public class Create {
public static final CreateRegistrate REGISTRATE = CreateRegistrate.create(ID); public static final CreateRegistrate REGISTRATE = CreateRegistrate.create(ID);
public static final CreativeModeTab BASE_CREATIVE_TAB = new BaseCreativeModeTab(); static {
public static final CreativeModeTab PALETTES_CREATIVE_TAB = new PalettesCreativeModeTab(); // 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 ServerSchematicLoader SCHEMATIC_RECEIVER = new ServerSchematicLoader();
public static final RedstoneLinkNetworkHandler REDSTONE_LINK_NETWORK_HANDLER = new RedstoneLinkNetworkHandler(); public static final RedstoneLinkNetworkHandler REDSTONE_LINK_NETWORK_HANDLER = new RedstoneLinkNetworkHandler();
@ -105,6 +111,7 @@ public class Create {
AllSoundEvents.prepare(); AllSoundEvents.prepare();
AllTags.init(); AllTags.init();
AllCreativeModeTabs.init();
AllBlocks.register(); AllBlocks.register();
AllItems.register(); AllItems.register();
AllFluids.register(); AllFluids.register();
@ -146,12 +153,12 @@ public class Create {
} }
public static void init(final FMLCommonSetupEvent event) { public static void init(final FMLCommonSetupEvent event) {
AttachedRegistry.unwrapAll();
AllPackets.registerPackets(); AllPackets.registerPackets();
SchematicInstances.register(); SchematicInstances.register();
BuiltinPotatoProjectileTypes.register(); BuiltinPotatoProjectileTypes.register();
event.enqueueWork(() -> { event.enqueueWork(() -> {
AttachedRegistry.unwrapAll();
AllAdvancements.register(); AllAdvancements.register();
AllTriggers.register(); AllTriggers.register();
BoilerHeaters.registerDefaults(); BoilerHeaters.registerDefaults();
@ -162,7 +169,7 @@ public class Create {
TagGen.datagen(); TagGen.datagen();
DataGenerator gen = event.getGenerator(); DataGenerator gen = event.getGenerator();
if (event.includeClient()) { 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)); gen.addProvider(AllSoundEvents.provider(gen));
} }
if (event.includeServer()) { 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.blockEntity.SmartBlockEntity;
import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.config.AllConfigs;
import com.simibubi.create.foundation.item.TooltipHelper; 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;
import com.simibubi.create.foundation.sound.SoundScapes.AmbienceGroup; import com.simibubi.create.foundation.sound.SoundScapes.AmbienceGroup;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
@ -396,7 +397,7 @@ public class KineticBlockEntity extends SmartBlockEntity implements IHaveGoggleI
.style(GOLD) .style(GOLD)
.forGoggles(tooltip); .forGoggles(tooltip);
Component hint = Lang.translateDirect("gui.contraptions.network_overstressed"); 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++) for (int i = 0; i < cutString.size(); i++)
Lang.builder() Lang.builder()
.add(cutString.get(i) .add(cutString.get(i)
@ -412,7 +413,7 @@ public class KineticBlockEntity extends SmartBlockEntity implements IHaveGoggleI
MutableComponent hint = MutableComponent hint =
Lang.translateDirect("gui.contraptions.not_fast_enough", I18n.get(getBlockState().getBlock() Lang.translateDirect("gui.contraptions.not_fast_enough", I18n.get(getBlockState().getBlock()
.getDescriptionId())); .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++) for (int i = 0; i < cutString.size(); i++)
Lang.builder() Lang.builder()
.add(cutString.get(i) .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.content.contraptions.goggles.IHaveGoggleInformation;
import com.simibubi.create.foundation.item.TooltipHelper; 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.Components;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
@ -27,7 +28,7 @@ public interface IDisplayAssemblyExceptions {
String text = e.component.getString(); String text = e.component.getString();
Arrays.stream(text.split("\n")) 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() .forEach(c -> tooltip.add(IHaveGoggleInformation.componentSpacing.plainCopy()
.append(c)))); .append(c))));

View File

@ -6,7 +6,7 @@ import java.util.List;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import com.simibubi.create.AllBlocks; 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.base.KineticBlockEntity;
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock; import com.simibubi.create.content.contraptions.relays.belt.BeltBlock;
import com.simibubi.create.content.contraptions.relays.belt.BeltPart; import com.simibubi.create.content.contraptions.relays.belt.BeltPart;
@ -50,7 +50,7 @@ public class BeltConnectorItem extends BlockItem {
@Override @Override
public void fillItemCategory(CreativeModeTab p_150895_1_, NonNullList<ItemStack> p_150895_2_) { 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; return;
super.fillItemCategory(p_150895_1_, p_150895_2_); 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.BlockEntityBehaviour;
import com.simibubi.create.foundation.blockEntity.behaviour.linked.LinkBehaviour; import com.simibubi.create.foundation.blockEntity.behaviour.linked.LinkBehaviour;
import com.simibubi.create.foundation.item.TooltipHelper; 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.networking.AllPackets;
import com.simibubi.create.foundation.utility.Components; import com.simibubi.create.foundation.utility.Components;
import com.simibubi.create.foundation.utility.ControlsUtil; import com.simibubi.create.foundation.utility.ControlsUtil;
@ -236,7 +237,7 @@ public class LinkedControllerClientHandler {
list.add(Lang.translateDirect("linked_controller.bind_mode") list.add(Lang.translateDirect("linked_controller.bind_mode")
.withStyle(ChatFormatting.GOLD)); .withStyle(ChatFormatting.GOLD));
list.addAll(TooltipHelper.cutTextComponent(Lang.translateDirect("linked_controller.press_keybind", keys), list.addAll(TooltipHelper.cutTextComponent(Lang.translateDirect("linked_controller.press_keybind", keys),
ChatFormatting.GRAY, ChatFormatting.GRAY)); Palette.ALL_GRAY));
int width = 0; int width = 0;
int height = list.size() * mc.font.lineHeight; int height = list.size() * mc.font.lineHeight;

View File

@ -1,7 +1,6 @@
package com.simibubi.create.content.logistics.item.filter; package com.simibubi.create.content.logistics.item.filter;
import static com.simibubi.create.foundation.gui.AllGuiTextures.PLAYER_INVENTORY; import static com.simibubi.create.foundation.gui.AllGuiTextures.PLAYER_INVENTORY;
import static net.minecraft.ChatFormatting.GRAY;
import java.util.Collections; import java.util.Collections;
import java.util.List; 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.IconButton;
import com.simibubi.create.foundation.gui.widget.Indicator; import com.simibubi.create.foundation.gui.widget.Indicator;
import com.simibubi.create.foundation.gui.widget.Indicator.State; 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;
import com.simibubi.create.foundation.item.TooltipHelper.Palette;
import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.networking.AllPackets;
import net.minecraft.client.renderer.Rect2i; import net.minecraft.client.renderer.Rect2i;
@ -142,7 +141,7 @@ public abstract class AbstractFilterScreen<F extends AbstractFilterMenu> extends
if (!button.isHoveredOrFocused()) if (!button.isHoveredOrFocused())
return; return;
List<Component> tip = button.getToolTip(); List<Component> tip = button.getToolTip();
tip.addAll(TooltipHelper.cutTextComponent(tooltip, GRAY, GRAY)); tip.addAll(TooltipHelper.cutTextComponent(tooltip, Palette.ALL_GRAY));
} }
protected void contentsCleared() {} 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.woodenWindowBlock;
import static com.simibubi.create.foundation.data.WindowGen.woodenWindowPane; import static com.simibubi.create.foundation.data.WindowGen.woodenWindowPane;
import com.simibubi.create.AllCreativeModeTabs;
import com.simibubi.create.AllSpriteShifts; import com.simibubi.create.AllSpriteShifts;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.foundation.block.connected.HorizontalCTBehaviour; import com.simibubi.create.foundation.block.connected.HorizontalCTBehaviour;
@ -30,7 +31,7 @@ import net.minecraftforge.common.Tags;
public class AllPaletteBlocks { public class AllPaletteBlocks {
static { static {
REGISTRATE.creativeModeTab(() -> Create.PALETTES_CREATIVE_TAB); REGISTRATE.creativeModeTab(() -> AllCreativeModeTabs.PALETTES_CREATIVE_TAB);
} }
// Windows and Glass // 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.IconButton;
import com.simibubi.create.foundation.gui.widget.Indicator; import com.simibubi.create.foundation.gui.widget.Indicator;
import com.simibubi.create.foundation.gui.widget.Indicator.State; 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;
import com.simibubi.create.foundation.item.TooltipHelper.Palette;
import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.networking.AllPackets;
import com.simibubi.create.foundation.utility.Components; import com.simibubi.create.foundation.utility.Components;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
@ -267,7 +267,7 @@ public class SchematicannonScreen extends AbstractSimiContainerScreen<Schematica
tip.add((enabled ? optionEnabled : optionDisabled).plainCopy() tip.add((enabled ? optionEnabled : optionDisabled).plainCopy()
.withStyle(BLUE)); .withStyle(BLUE));
tip.addAll(TooltipHelper 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 @Override
@ -357,13 +357,13 @@ public class SchematicannonScreen extends AbstractSimiContainerScreen<Schematica
if (hoveredSlot != null && !hoveredSlot.hasItem()) { if (hoveredSlot != null && !hoveredSlot.hasItem()) {
if (hoveredSlot.index == 0) if (hoveredSlot.index == 0)
renderComponentTooltip(matrixStack, 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) if (hoveredSlot.index == 2)
renderComponentTooltip(matrixStack, 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) if (hoveredSlot.index == 4)
renderComponentTooltip(matrixStack, 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) { if (be.missingItem != null) {

View File

@ -22,7 +22,7 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemp
public class SchematicInstances { public class SchematicInstances {
public static WorldAttached<Cache<Integer, SchematicWorld>> loadedSchematics; public static final WorldAttached<Cache<Integer, SchematicWorld>> loadedSchematics;
static { static {
loadedSchematics = new WorldAttached<>($ -> CacheBuilder.newBuilder() 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.AllConfigs;
import com.simibubi.create.foundation.config.ui.BaseConfigScreen; import com.simibubi.create.foundation.config.ui.BaseConfigScreen;
import com.simibubi.create.foundation.fluid.FluidHelper; 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.AllPackets;
import com.simibubi.create.foundation.networking.LeftClickPacket; import com.simibubi.create.foundation.networking.LeftClickPacket;
import com.simibubi.create.foundation.ponder.PonderTooltipHandler; 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.multiplayer.ClientLevel;
import net.minecraft.client.renderer.entity.EntityRenderDispatcher; import net.minecraft.client.renderer.entity.EntityRenderDispatcher;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.LevelAccessor;
@ -239,7 +240,12 @@ public class ClientEvents {
if (event.getPlayer() == null) if (event.getPlayer() == null)
return; 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); PonderTooltipHandler.addToTooltip(event);
SequencedAssemblyRecipe.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.element.TextStencilElement;
import com.simibubi.create.foundation.gui.widget.BoxWidget; import com.simibubi.create.foundation.gui.widget.BoxWidget;
import com.simibubi.create.foundation.item.TooltipHelper; 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.Components;
import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.Screen;
import net.minecraftforge.common.ForgeConfigSpec; import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.fml.config.ModConfig; import net.minecraftforge.fml.config.ModConfig;
@ -185,7 +185,7 @@ public class BaseConfigScreen extends ConfigScreen {
.addAll(TooltipHelper.cutTextComponent( .addAll(TooltipHelper.cutTextComponent(
Components.literal( Components.literal(
"Gameplay settings can only be accessed from the in-game menu after joining a World or Server."), "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 { } else {
serverConfigWidget.withCallback(() -> linkTo(new SubMenuConfigScreen(this, ModConfig.Type.SERVER, serverSpec))); serverConfigWidget.withCallback(() -> linkTo(new SubMenuConfigScreen(this, ModConfig.Type.SERVER, serverSpec)));
serverText.withElementRenderer(BoxWidget.gradientFactory.apply(serverConfigWidget)); 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.element.DelegatedStencilElement;
import com.simibubi.create.foundation.gui.widget.BoxWidget; import com.simibubi.create.foundation.gui.widget.BoxWidget;
import com.simibubi.create.foundation.item.TooltipHelper; 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.Components;
import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.Screen;
import net.minecraftforge.fml.ModList; import net.minecraftforge.fml.ModList;
import net.minecraftforge.forgespi.language.IModInfo; import net.minecraftforge.forgespi.language.IModInfo;
@ -113,7 +113,7 @@ public class ConfigModListScreen extends ConfigScreen {
button.updateColorsFromState(); button.updateColorsFromState();
button.modifyElement(e -> ((DelegatedStencilElement) e).withElementRenderer(BaseConfigScreen.DISABLED_RENDERER)); button.modifyElement(e -> ((DelegatedStencilElement) e).withElementRenderer(BaseConfigScreen.DISABLED_RENDERER));
labelTooltip.add(Components.literal(toHumanReadable(id))); 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); 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.element.DelegatedStencilElement;
import com.simibubi.create.foundation.gui.widget.BoxWidget; import com.simibubi.create.foundation.gui.widget.BoxWidget;
import com.simibubi.create.foundation.item.TooltipHelper; 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.networking.AllPackets;
import com.simibubi.create.foundation.utility.Color; import com.simibubi.create.foundation.utility.Color;
import com.simibubi.create.foundation.utility.Components; 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.showingElement(AllIcons.I_CONFIG_RESET.asStencil().withElementRenderer(BoxWidget.gradientFactory.apply(resetAll)));
resetAll.getToolTip().add(Components.literal("Reset All")); 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) saveChanges = new BoxWidget(listL - 30, yCenter - 25, 20, 20)
.withPadding(2, 2) .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.showingElement(AllIcons.I_CONFIG_SAVE.asStencil().withElementRenderer(BoxWidget.gradientFactory.apply(saveChanges)));
saveChanges.getToolTip().add(Components.literal("Save Changes")); 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) discardChanges = new BoxWidget(listL - 30, yCenter + 5, 20, 20)
.withPadding(2, 2) .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.showingElement(AllIcons.I_CONFIG_DISCARD.asStencil().withElementRenderer(BoxWidget.gradientFactory.apply(discardChanges)));
discardChanges.getToolTip().add(Components.literal("Discard Changes")); 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) goBack = new BoxWidget(listL - 30, yCenter + 65, 20, 20)
.withPadding(2, 2) .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)); stencil.withElementRenderer((ms, w, h, alpha) -> UIRenderHelper.angledGradient(ms, 90, 8, 0, 16, 16, red));
serverLocked.withBorderColors(red); serverLocked.withBorderColors(red);
serverLocked.getToolTip().add(Components.literal("Locked").withStyle(ChatFormatting.BOLD)); 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 { } else {
stencil.withStencilRenderer((ms, w, h, alpha) -> AllIcons.I_CONFIG_UNLOCKED.render(ms, 0, 0)); 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)); stencil.withElementRenderer((ms, w, h, alpha) -> UIRenderHelper.angledGradient(ms, 90, 8, 0, 16, 16, green));
serverLocked.withBorderColors(green); serverLocked.withBorderColors(green);
serverLocked.getToolTip().add(Components.literal("Unlocked").withStyle(ChatFormatting.BOLD)); 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); 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.element.DelegatedStencilElement;
import com.simibubi.create.foundation.gui.widget.BoxWidget; import com.simibubi.create.foundation.gui.widget.BoxWidget;
import com.simibubi.create.foundation.item.TooltipHelper; 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.Components;
import com.simibubi.create.foundation.utility.Pair; 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(Predicates.not(s -> s.startsWith("Range")))
.filter(s -> !s.equals(".")) .filter(s -> !s.equals("."))
.map(Components::literal) .map(Components::literal)
.flatMap(stc -> TooltipHelper.cutTextComponent(stc, ChatFormatting.GRAY, ChatFormatting.GRAY) .flatMap(stc -> TooltipHelper.cutTextComponent(stc, Palette.ALL_GRAY)
.stream()) .stream())
.collect(Collectors.toList())); .collect(Collectors.toList()));
if (annotations.containsKey(ConfigAnnotations.RequiresRelog.TRUE.getName())) 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())) 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)); 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.BiConsumer;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
import org.jetbrains.annotations.Nullable;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.CreateClient; import com.simibubi.create.CreateClient;
import com.simibubi.create.content.contraptions.fluids.VirtualFluid; import com.simibubi.create.content.contraptions.fluids.VirtualFluid;
import com.simibubi.create.content.contraptions.relays.encased.CasingConnectivity; import com.simibubi.create.content.contraptions.relays.encased.CasingConnectivity;
import com.simibubi.create.foundation.block.connected.CTModel; import com.simibubi.create.foundation.block.connected.CTModel;
import com.simibubi.create.foundation.block.connected.ConnectedTextureBehaviour; import com.simibubi.create.foundation.block.connected.ConnectedTextureBehaviour;
import com.simibubi.create.foundation.item.TooltipModifier;
import com.simibubi.create.foundation.utility.RegisteredObjects; import com.simibubi.create.foundation.utility.RegisteredObjects;
import com.tterrag.registrate.AbstractRegistrate; import com.tterrag.registrate.AbstractRegistrate;
import com.tterrag.registrate.builders.BlockBuilder; import com.tterrag.registrate.builders.BlockBuilder;
import com.tterrag.registrate.builders.BlockEntityBuilder.BlockEntityFactory; import com.tterrag.registrate.builders.BlockEntityBuilder.BlockEntityFactory;
import com.tterrag.registrate.builders.Builder;
import com.tterrag.registrate.builders.FluidBuilder; 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.NonNullBiFunction;
import com.tterrag.registrate.util.nullness.NonNullConsumer; import com.tterrag.registrate.util.nullness.NonNullConsumer;
import com.tterrag.registrate.util.nullness.NonNullFunction; import com.tterrag.registrate.util.nullness.NonNullFunction;
import com.tterrag.registrate.util.nullness.NonNullSupplier; import com.tterrag.registrate.util.nullness.NonNullSupplier;
import net.minecraft.client.resources.model.BakedModel; 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.resources.ResourceLocation;
import net.minecraft.tags.BlockTags; import net.minecraft.tags.BlockTags;
import net.minecraft.world.entity.Entity; 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.FluidAttributes;
import net.minecraftforge.fluids.ForgeFlowingFluid; import net.minecraftforge.fluids.ForgeFlowingFluid;
import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.registries.IForgeRegistryEntry;
import net.minecraftforge.registries.RegistryObject;
public class CreateRegistrate extends AbstractRegistrate<CreateRegistrate> { public class CreateRegistrate extends AbstractRegistrate<CreateRegistrate> {
@Nullable
protected Function<Item, TooltipModifier> currentTooltipModifierFactory;
protected CreateRegistrate(String modid) { protected CreateRegistrate(String modid) {
super(modid); super(modid);
} }
@ -49,11 +62,32 @@ public class CreateRegistrate extends AbstractRegistrate<CreateRegistrate> {
return new CreateRegistrate(modid); 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 @Override
public CreateRegistrate registerEventListeners(IEventBus bus) { public CreateRegistrate registerEventListeners(IEventBus bus) {
return super.registerEventListeners(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 @Override
public <T extends BlockEntity> CreateBlockEntityBuilder<T, CreateRegistrate> blockEntity(String name, public <T extends BlockEntity> CreateBlockEntityBuilder<T, CreateRegistrate> blockEntity(String name,
BlockEntityFactory<T> factory) { 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.BoxElement;
import com.simibubi.create.foundation.gui.element.GuiGameElement; import com.simibubi.create.foundation.gui.element.GuiGameElement;
import com.simibubi.create.foundation.item.TooltipHelper; 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.ponder.ui.PonderTagIndexScreen;
import com.simibubi.create.foundation.utility.Color; import com.simibubi.create.foundation.utility.Color;
import com.simibubi.create.foundation.utility.Components; import com.simibubi.create.foundation.utility.Components;
@ -179,8 +180,8 @@ public class CreateMainMenuScreen extends AbstractSimiScreen {
return; return;
if (mouseY < gettingStarted.y || mouseY > gettingStarted.y + 20) if (mouseY < gettingStarted.y || mouseY > gettingStarted.y + 20)
return; return;
renderComponentTooltip(ms, TooltipHelper.cutTextComponent(Lang.translateDirect("menu.only_ingame"), ChatFormatting.GRAY, renderComponentTooltip(ms, TooltipHelper.cutTextComponent(Lang.translateDirect("menu.only_ingame"), Palette.ALL_GRAY),
ChatFormatting.GRAY), mouseX, mouseY); 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.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.IdentityHashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import org.jetbrains.annotations.Nullable;
import com.google.common.collect.ImmutableList; 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.Components;
import com.simibubi.create.foundation.utility.Lang; 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.gui.screens.Screen;
import net.minecraft.client.resources.language.I18n; import net.minecraft.client.resources.language.I18n;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent; 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 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() { @Nullable
return new Builder(); public static ItemDescription create(Item item, Palette palette) {
return create(getTooltipTranslationKey(item), palette);
} }
public static ItemDescription create(Palette palette, String translationKey) { @Nullable
if (!I18n.exists(translationKey)) { public static ItemDescription create(String translationKey, Palette palette) {
return MISSING; if (!canFillBuilder(translationKey)) {
return null;
} }
Builder builder = builder(); Builder builder = new Builder(palette);
builder.palette(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 // Summary
String summaryKey = translationKey + ".summary"; String summaryKey = translationKey + ".summary";
if (I18n.exists(summaryKey)) { if (I18n.exists(summaryKey)) {
@ -58,38 +76,48 @@ public record ItemDescription(ImmutableList<Component> lines, ImmutableList<Comp
break; break;
builder.addAction(I18n.get(controlKey), I18n.get(actionKey)); 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()) { if (Screen.hasShiftDown()) {
tooltip.addAll(linesOnShift); return linesOnShift;
return; } 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 { public static class Builder {
protected final Palette palette;
protected final List<String> summary = new ArrayList<>(); protected final List<String> summary = new ArrayList<>();
protected final List<Pair<String, String>> behaviours = new ArrayList<>(); protected final List<Pair<String, String>> behaviours = new ArrayList<>();
protected final List<Pair<String, String>> actions = 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) { public Builder addSummary(String summaryLine) {
summary.add(summaryLine); summary.add(summaryLine);
@ -106,18 +134,13 @@ public record ItemDescription(ImmutableList<Component> lines, ImmutableList<Comp
return this; return this;
} }
public Builder palette(Palette palette) {
this.palette = palette;
return this;
}
public ItemDescription build() { public ItemDescription build() {
List<Component> lines = new ArrayList<>(); List<Component> lines = new ArrayList<>();
List<Component> linesOnShift = new ArrayList<>(); List<Component> linesOnShift = new ArrayList<>();
List<Component> linesOnCtrl = new ArrayList<>(); List<Component> linesOnCtrl = new ArrayList<>();
for (String summaryLine : summary) { for (String summaryLine : summary) {
linesOnShift.addAll(TooltipHelper.cutTextComponent(Components.literal(summaryLine), palette.primary(), palette.highlight())); linesOnShift.addAll(TooltipHelper.cutStringTextComponent(summaryLine, palette));
} }
if (!behaviours.isEmpty()) { 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)); 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 static net.minecraft.ChatFormatting.GRAY;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Supplier;
import org.jetbrains.annotations.Nullable; 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;
import com.simibubi.create.content.contraptions.base.IRotate.StressImpact; import com.simibubi.create.content.contraptions.base.IRotate.StressImpact;
import com.simibubi.create.content.contraptions.components.steam.SteamEngineBlock; 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.Lang;
import com.simibubi.create.foundation.utility.LangBuilder; import com.simibubi.create.foundation.utility.LangBuilder;
import net.minecraft.client.Minecraft;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.Item; 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.minecraft.world.level.block.Block;
import net.minecraftforge.event.entity.player.ItemTooltipEvent; import net.minecraftforge.event.entity.player.ItemTooltipEvent;
public class ItemTooltipHandler { public class KineticStats implements TooltipModifier {
private static final String ITEM_PREFIX = "item." + Create.ID; protected final Block block;
private static final String BLOCK_PREFIX = "block." + Create.ID;
private static final Map<Item, Function<ItemStack, String>> TOOLTIP_REFERRALS = new IdentityHashMap<>(); public KineticStats(Block block) {
private static final Map<String, ItemDescription> TOOLTIP_CACHE = new HashMap<>(); this.block = block;
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";
} }
@Nullable @Nullable
public static ItemDescription getOrCreateTooltip(ItemStack stack) { public static KineticStats create(Item item) {
checkLocale(); if (item instanceof BlockItem blockItem) {
Block block = blockItem.getBlock();
String key = getTooltipTranslationKey(stack); if (block instanceof IRotate || block instanceof SteamEngineBlock) {
ItemDescription desc = TOOLTIP_CACHE.get(key); return new KineticStats(block);
}
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);
} }
if (desc == ItemDescription.MISSING) {
return null; return null;
} }
return desc; @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);
}
} }
public static List<Component> getKineticStats(Block block, Player player) { 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.nbt.CompoundTag;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraftforge.common.util.INBTSerializable; import net.minecraftforge.common.util.INBTSerializable;
import net.minecraftforge.items.IItemHandlerModifiable;
import net.minecraftforge.items.ItemStackHandler; import net.minecraftforge.items.ItemStackHandler;
import net.minecraftforge.items.wrapper.RecipeWrapper; import net.minecraftforge.items.wrapper.RecipeWrapper;
public class SmartInventory extends RecipeWrapper public class SmartInventory extends RecipeWrapper
implements IItemHandlerModifiableIntermediate, INBTSerializable<CompoundTag> { implements IItemHandlerModifiable, INBTSerializable<CompoundTag> {
protected boolean extractionAllowed; protected boolean extractionAllowed;
protected boolean insertionAllowed; protected boolean insertionAllowed;
@ -100,13 +101,13 @@ public class SmartInventory extends RecipeWrapper
} }
@Override @Override
public void setStackInSlot(int slot, ItemStack stack) { public ItemStack getStackInSlot(int slot) {
inv.setStackInSlot(slot, stack); return inv.getStackInSlot(slot);
} }
@Override @Override
public ItemStack getItem(int slot) { public void setStackInSlot(int slot, ItemStack stack) {
return super.getItem(slot); inv.setStackInSlot(slot, stack);
} }
public int getStackLimit(int slot, @Nonnull ItemStack 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.google.common.base.Strings;
import com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation; 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.Components;
import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.FontHelper;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
import net.minecraft.ChatFormatting; import net.minecraft.ChatFormatting;
@ -18,13 +16,14 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font; import net.minecraft.client.gui.Font;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent; import net.minecraft.network.chat.MutableComponent;
import net.minecraft.network.chat.Style;
import net.minecraftforge.client.MinecraftForgeClient; import net.minecraftforge.client.MinecraftForgeClient;
public class TooltipHelper { public class TooltipHelper {
public static final int MAX_WIDTH_PER_LINE = 200; 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") return Lang.translateDirect("tooltip.holdForDescription", Lang.translateDirect("tooltip.keyShift")
.withStyle(ChatFormatting.GRAY)) .withStyle(ChatFormatting.GRAY))
.withStyle(ChatFormatting.DARK_GRAY); .withStyle(ChatFormatting.DARK_GRAY);
@ -36,7 +35,7 @@ public class TooltipHelper {
.append(Lang.translateDirect(hintKey + ".title")) .append(Lang.translateDirect(hintKey + ".title"))
.withStyle(ChatFormatting.GOLD)); .withStyle(ChatFormatting.GOLD));
Component hint = Lang.translateDirect(hintKey); 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) for (Component component : cutComponent)
tooltip.add(spacing.plainCopy() tooltip.add(spacing.plainCopy()
.append(component)); .append(component));
@ -52,71 +51,44 @@ public class TooltipHelper {
return bar + " "; return bar + " ";
} }
@Deprecated public static Style styleFromColor(ChatFormatting color) {
public static List<String> cutString(Component s, ChatFormatting defaultColor, ChatFormatting highlightColor) { return Style.EMPTY.applyFormat(color);
return cutString(s.getString(), defaultColor, highlightColor, 0);
} }
@Deprecated public static List<Component> cutStringTextComponent(String s, Palette palette) {
public static List<String> cutString(String s, ChatFormatting defaultColor, ChatFormatting highlightColor, return cutTextComponent(Components.literal(s), palette);
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; public static List<Component> cutTextComponent(Component c, Palette palette) {
List<String> lines = FontHelper.cutString(font, markedUp, MAX_WIDTH_PER_LINE); return cutTextComponent(c, palette.primary(), palette.highlight());
// 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 c, ChatFormatting defaultColor, public static List<Component> cutStringTextComponent(String s, Style primaryStyle,
ChatFormatting highlightColor) { Style highlightStyle) {
return cutTextComponent(Components.literal(c), defaultColor, highlightColor, 0); return cutTextComponent(Components.literal(s), primaryStyle, highlightStyle);
} }
public static List<Component> cutTextComponent(Component c, ChatFormatting defaultColor, public static List<Component> cutTextComponent(Component c, Style primaryStyle,
ChatFormatting highlightColor) { Style highlightStyle) {
return cutTextComponent(c, defaultColor, highlightColor, 0); return cutTextComponent(c, primaryStyle, highlightStyle, 0);
} }
public static List<Component> cutStringTextComponent(String c, ChatFormatting defaultColor, public static List<Component> cutStringTextComponent(String c, Style primaryStyle,
ChatFormatting highlightColor, int indent) { Style highlightStyle, int indent) {
return cutTextComponent(Components.literal(c), defaultColor, highlightColor, indent); return cutTextComponent(Components.literal(c), primaryStyle, highlightStyle, indent);
} }
public static List<Component> cutTextComponent(Component c, ChatFormatting defaultColor, public static List<Component> cutTextComponent(Component c, Style primaryStyle,
ChatFormatting highlightColor, int indent) { Style highlightStyle, int indent) {
String s = c.getString(); String s = c.getString();
// Apply markup
String markedUp = s;// .replaceAll("_([^_]+)_", highlightColor + "$1" + defaultColor);
// Split words // Split words
List<String> words = new LinkedList<>(); List<String> words = new LinkedList<>();
BreakIterator iterator = BreakIterator.getLineInstance(MinecraftForgeClient.getLocale()); BreakIterator iterator = BreakIterator.getLineInstance(MinecraftForgeClient.getLocale());
iterator.setText(markedUp); iterator.setText(s);
int start = iterator.first(); int start = iterator.first();
for (int end = iterator.next(); end != BreakIterator.DONE; start = end, end = iterator.next()) { 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); words.add(word);
} }
@ -147,16 +119,16 @@ public class TooltipHelper {
// Format // Format
MutableComponent lineStart = Components.literal(Strings.repeat(" ", indent)); MutableComponent lineStart = Components.literal(Strings.repeat(" ", indent));
lineStart.withStyle(defaultColor); lineStart.withStyle(primaryStyle);
List<Component> formattedLines = new ArrayList<>(lines.size()); List<Component> formattedLines = new ArrayList<>(lines.size());
Couple<ChatFormatting> f = Couple.create(highlightColor, defaultColor); Couple<Style> styles = Couple.create(highlightStyle, primaryStyle);
boolean currentlyHighlighted = false; boolean currentlyHighlighted = false;
for (String string : lines) { for (String string : lines) {
MutableComponent currentComponent = lineStart.plainCopy(); MutableComponent currentComponent = lineStart.plainCopy();
String[] split = string.split("_"); String[] split = string.split("_");
for (String part : 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; currentlyHighlighted = !currentlyHighlighted;
} }
@ -167,52 +139,23 @@ public class TooltipHelper {
return formattedLines; return formattedLines;
} }
// public static List<ITextComponent> cutTextComponentOld(ITextComponent c, TextFormatting defaultColor, public record Palette(Style primary, Style highlight) {
// TextFormatting highlightColor, int indent) { public static final Palette BLUE = ofColors(ChatFormatting.BLUE, ChatFormatting.AQUA);
// IFormattableTextComponent lineStart = StringTextComponent.EMPTY.copy(); public static final Palette GREEN = ofColors(ChatFormatting.DARK_GREEN, ChatFormatting.GREEN);
// for (int i = 0; i < indent; i++) public static final Palette YELLOW = ofColors(ChatFormatting.GOLD, ChatFormatting.YELLOW);
// lineStart.append(" "); public static final Palette RED = ofColors(ChatFormatting.DARK_RED, ChatFormatting.RED);
// lineStart.formatted(defaultColor); public static final Palette PURPLE = ofColors(ChatFormatting.DARK_PURPLE, ChatFormatting.LIGHT_PURPLE);
// public static final Palette GRAY = ofColors(ChatFormatting.DARK_GRAY, ChatFormatting.GRAY);
// 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;
// }
// private static int getComponentLength(ITextComponent component) { public static final Palette ALL_GRAY = ofColors(ChatFormatting.GRAY, ChatFormatting.GRAY);
// AtomicInteger l = new AtomicInteger(); public static final Palette GRAY_AND_BLUE = ofColors(ChatFormatting.GRAY, ChatFormatting.BLUE);
// TextProcessing.visitFormatted(component, Style.EMPTY, (s, style, charConsumer) -> { public static final Palette GRAY_AND_WHITE = ofColors(ChatFormatting.GRAY, ChatFormatting.WHITE);
// l.getAndIncrement(); public static final Palette GRAY_AND_GOLD = ofColors(ChatFormatting.GRAY, ChatFormatting.GOLD);
// return true; public static final Palette GRAY_AND_RED = ofColors(ChatFormatting.GRAY, ChatFormatting.RED);
// });
// return l.get(); 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.BoxElement;
import com.simibubi.create.foundation.gui.element.GuiGameElement; import com.simibubi.create.foundation.gui.element.GuiGameElement;
import com.simibubi.create.foundation.item.TooltipHelper; 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.PonderLocalization;
import com.simibubi.create.foundation.ponder.PonderRegistry; import com.simibubi.create.foundation.ponder.PonderRegistry;
import com.simibubi.create.foundation.ponder.PonderTag; 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.FontHelper;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.client.gui.components.events.GuiEventListener;
import net.minecraft.client.renderer.Rect2i; import net.minecraft.client.renderer.Rect2i;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
@ -213,7 +213,7 @@ public class PonderTagIndexScreen extends NavigatableSimiScreen {
if (hoveredItem != null) { if (hoveredItem != null) {
List<Component> list = TooltipHelper.cutStringTextComponent(hoveredItem.getDescription(), List<Component> list = TooltipHelper.cutStringTextComponent(hoveredItem.getDescription(),
ChatFormatting.GRAY, ChatFormatting.GRAY); Palette.ALL_GRAY);
list.add(0, Components.literal(hoveredItem.getTitle())); list.add(0, Components.literal(hoveredItem.getTitle()));
renderComponentTooltip(ms, list, mouseX, mouseY); renderComponentTooltip(ms, list, mouseX, mouseY);
} }

View File

@ -5,6 +5,7 @@ import java.util.HashMap;
import java.util.IdentityHashMap; import java.util.IdentityHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.Function;
import org.jetbrains.annotations.Nullable; 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<>(); private static final List<AttachedRegistry<?, ?>> ALL = new ArrayList<>();
protected final IForgeRegistry<K> objectRegistry; 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<K, V> objectMap = new IdentityHashMap<>();
protected final Map<ResourceLocation, Function<K, V>> deferredRegistrations = new HashMap<>();
protected boolean unwrapped = false; protected boolean unwrapped = false;
public AttachedRegistry(IForgeRegistry<K> objectRegistry) { public AttachedRegistry(IForgeRegistry<K> objectRegistry) {
@ -27,15 +29,15 @@ public class AttachedRegistry<K extends IForgeRegistryEntry<K>, V> {
ALL.add(this); ALL.add(this);
} }
public void register(ResourceLocation location, V value) { public void register(ResourceLocation id, V value) {
if (!unwrapped) { if (!unwrapped) {
locationMap.put(location, value); idMap.put(id, value);
} else { } else {
K object = objectRegistry.getValue(location); K object = objectRegistry.getValue(id);
if (object != null) { if (object != null) {
objectMap.put(object, value); objectMap.put(object, value);
} else { } 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) { if (unwrapped) {
objectMap.put(object, value); objectMap.put(object, value);
} else { } else {
ResourceLocation location = objectRegistry.getKey(object); ResourceLocation id = objectRegistry.getKey(object);
if (location != null) { if (id != null) {
locationMap.put(location, value); idMap.put(id, value);
} else { } 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 @Nullable
public V get(ResourceLocation location) { public V get(ResourceLocation id) {
if (!unwrapped) { if (!unwrapped) {
return locationMap.get(location); return idMap.get(id);
} else { } else {
K object = objectRegistry.getValue(location); K object = objectRegistry.getValue(id);
if (object != null) { if (object != null) {
return objectMap.get(object); return objectMap.get(object);
} else { } 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; return null;
} }
} }
@ -73,11 +101,11 @@ public class AttachedRegistry<K extends IForgeRegistryEntry<K>, V> {
if (unwrapped) { if (unwrapped) {
return objectMap.get(object); return objectMap.get(object);
} else { } else {
ResourceLocation location = objectRegistry.getKey(object); ResourceLocation id = objectRegistry.getKey(object);
if (location != null) { if (id != null) {
return locationMap.get(location); return idMap.get(id);
} else { } 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; return null;
} }
} }
@ -88,15 +116,26 @@ public class AttachedRegistry<K extends IForgeRegistryEntry<K>, V> {
} }
protected void unwrap() { protected void unwrap() {
for (Map.Entry<ResourceLocation, V> entry : locationMap.entrySet()) { deferredRegistrations.forEach((id, func) -> {
ResourceLocation location = entry.getKey(); K object = objectRegistry.getValue(id);
K object = objectRegistry.getValue(location);
if (object != null) { if (object != null) {
objectMap.put(object, entry.getValue()); objectMap.put(object, func.apply(object));
} else { } 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; unwrapped = true;
} }