RecipeButton.java
net.minecraft.client.gui.screens.recipebook.RecipeButton
信息
- 全限定名:net.minecraft.client.gui.screens.recipebook.RecipeButton
- 类型:public class
- 包:net.minecraft.client.gui.screens.recipebook
- 源码路径:src/main/java/net/minecraft/client/gui/screens/recipebook/RecipeButton.java
- 起始行号:L25
- 继承:AbstractWidget
- 职责:
TODO
字段/常量
-
SLOT_MANY_CRAFTABLE_SPRITE- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L26 - 说明:
TODO
- 类型:
-
SLOT_CRAFTABLE_SPRITE- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L27 - 说明:
TODO
- 类型:
-
SLOT_MANY_UNCRAFTABLE_SPRITE- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L28 - 说明:
TODO
- 类型:
-
SLOT_UNCRAFTABLE_SPRITE- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L29 - 说明:
TODO
- 类型:
-
ANIMATION_TIME- 类型:
float - 修饰符:
private static final - 源码定位:
L30 - 说明:
TODO
- 类型:
-
BACKGROUND_SIZE- 类型:
int - 修饰符:
private static final - 源码定位:
L31 - 说明:
TODO
- 类型:
-
MORE_RECIPES_TOOLTIP- 类型:
Component - 修饰符:
private static final - 源码定位:
L32 - 说明:
TODO
- 类型:
-
collection- 类型:
RecipeCollection - 修饰符:
private - 源码定位:
L33 - 说明:
TODO
- 类型:
-
selectedEntries- 类型:
List<RecipeButton.ResolvedEntry> - 修饰符:
private - 源码定位:
L34 - 说明:
TODO
- 类型:
-
allRecipesHaveSameResultDisplay- 类型:
boolean - 修饰符:
private - 源码定位:
L35 - 说明:
TODO
- 类型:
-
slotSelectTime- 类型:
SlotSelectTime - 修饰符:
private final - 源码定位:
L36 - 说明:
TODO
- 类型:
-
animationTime- 类型:
float - 修饰符:
private - 源码定位:
L37 - 说明:
TODO
- 类型:
内部类/嵌套类型
net.minecraft.client.gui.screens.recipebook.RecipeButton.ResolvedEntry- 类型:
record - 修饰符:
private - 源码定位:
L172 - 说明:
TODO
- 类型:
构造器
public RecipeButton(SlotSelectTime slotSelectTime) @ L39
- 构造器名:RecipeButton
- 源码定位:L39
- 修饰符:public
参数:
- slotSelectTime: SlotSelectTime
说明:
TODO
方法
下面的方法块按源码顺序生成。
public void init(RecipeCollection collection, boolean isFiltering, RecipeBookPage page, ContextMap resolutionContext) @ L44
- 方法名:init
- 源码定位:L44
- 返回类型:void
- 修饰符:public
参数:
- collection: RecipeCollection
- isFiltering: boolean
- page: RecipeBookPage
- resolutionContext: ContextMap
说明:
TODO
private static boolean allRecipesHaveSameResultDisplay(List<RecipeButton.ResolvedEntry> entries) @ L58
- 方法名:allRecipesHaveSameResultDisplay
- 源码定位:L58
- 返回类型:boolean
- 修饰符:private static
参数:
- entries: List<RecipeButton.ResolvedEntry>
说明:
TODO
public RecipeCollection getCollection() @ L76
- 方法名:getCollection
- 源码定位:L76
- 返回类型:RecipeCollection
- 修饰符:public
参数:
- 无
说明:
TODO
public void extractWidgetRenderState(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float a) @ L80
- 方法名:extractWidgetRenderState
- 源码定位:L80
- 返回类型:void
- 修饰符:public
参数:
- graphics: GuiGraphicsExtractor
- mouseX: int
- mouseY: int
- a: float
说明:
TODO
private boolean hasMultipleRecipes() @ L119
- 方法名:hasMultipleRecipes
- 源码定位:L119
- 返回类型:boolean
- 修饰符:private
参数:
- 无
说明:
TODO
public boolean isOnlyOption() @ L123
- 方法名:isOnlyOption
- 源码定位:L123
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public RecipeDisplayId getCurrentRecipe() @ L127
- 方法名:getCurrentRecipe
- 源码定位:L127
- 返回类型:RecipeDisplayId
- 修饰符:public
参数:
- 无
说明:
TODO
public ItemStack getDisplayStack() @ L132
- 方法名:getDisplayStack
- 源码定位:L132
- 返回类型:ItemStack
- 修饰符:public
参数:
- 无
说明:
TODO
public List<Component> getTooltipText(ItemStack displayStack) @ L140
- 方法名:getTooltipText
- 源码定位:L140
- 返回类型:List
- 修饰符:public
参数:
- displayStack: ItemStack
说明:
TODO
public void updateWidgetNarration(NarrationElementOutput output) @ L149
- 方法名:updateWidgetNarration
- 源码定位:L149
- 返回类型:void
- 修饰符:public
参数:
- output: NarrationElementOutput
说明:
TODO
public int getWidth() @ L161
- 方法名:getWidth
- 源码定位:L161
- 返回类型:int
- 修饰符:public
参数:
- 无
说明:
TODO
protected boolean isValidClickButton(MouseButtonInfo buttonInfo) @ L166
- 方法名:isValidClickButton
- 源码定位:L166
- 返回类型:boolean
- 修饰符:protected
参数:
- buttonInfo: MouseButtonInfo
说明:
TODO
代码
@OnlyIn(Dist.CLIENT)
public class RecipeButton extends AbstractWidget {
private static final Identifier SLOT_MANY_CRAFTABLE_SPRITE = Identifier.withDefaultNamespace("recipe_book/slot_many_craftable");
private static final Identifier SLOT_CRAFTABLE_SPRITE = Identifier.withDefaultNamespace("recipe_book/slot_craftable");
private static final Identifier SLOT_MANY_UNCRAFTABLE_SPRITE = Identifier.withDefaultNamespace("recipe_book/slot_many_uncraftable");
private static final Identifier SLOT_UNCRAFTABLE_SPRITE = Identifier.withDefaultNamespace("recipe_book/slot_uncraftable");
private static final float ANIMATION_TIME = 15.0F;
private static final int BACKGROUND_SIZE = 25;
private static final Component MORE_RECIPES_TOOLTIP = Component.translatable("gui.recipebook.moreRecipes");
private RecipeCollection collection = RecipeCollection.EMPTY;
private List<RecipeButton.ResolvedEntry> selectedEntries = List.of();
private boolean allRecipesHaveSameResultDisplay;
private final SlotSelectTime slotSelectTime;
private float animationTime;
public RecipeButton(SlotSelectTime slotSelectTime) {
super(0, 0, 25, 25, CommonComponents.EMPTY);
this.slotSelectTime = slotSelectTime;
}
public void init(RecipeCollection collection, boolean isFiltering, RecipeBookPage page, ContextMap resolutionContext) {
this.collection = collection;
List<RecipeDisplayEntry> fittingRecipes = collection.getSelectedRecipes(
isFiltering ? RecipeCollection.CraftableStatus.CRAFTABLE : RecipeCollection.CraftableStatus.ANY
);
this.selectedEntries = fittingRecipes.stream().map(entry -> new RecipeButton.ResolvedEntry(entry.id(), entry.resultItems(resolutionContext))).toList();
this.allRecipesHaveSameResultDisplay = allRecipesHaveSameResultDisplay(this.selectedEntries);
List<RecipeDisplayId> newlyShownRecipes = fittingRecipes.stream().map(RecipeDisplayEntry::id).filter(page.getRecipeBook()::willHighlight).toList();
if (!newlyShownRecipes.isEmpty()) {
newlyShownRecipes.forEach(page::recipeShown);
this.animationTime = 15.0F;
}
}
private static boolean allRecipesHaveSameResultDisplay(List<RecipeButton.ResolvedEntry> entries) {
Iterator<ItemStack> itemsIterator = entries.stream().flatMap(e -> e.displayItems().stream()).iterator();
if (!itemsIterator.hasNext()) {
return true;
} else {
ItemStack firstItem = itemsIterator.next();
while (itemsIterator.hasNext()) {
ItemStack nextItem = itemsIterator.next();
if (!ItemStack.isSameItemSameComponents(firstItem, nextItem)) {
return false;
}
}
return true;
}
}
public RecipeCollection getCollection() {
return this.collection;
}
@Override
public void extractWidgetRenderState(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float a) {
Identifier sprite;
if (this.collection.hasCraftable()) {
if (this.hasMultipleRecipes()) {
sprite = SLOT_MANY_CRAFTABLE_SPRITE;
} else {
sprite = SLOT_CRAFTABLE_SPRITE;
}
} else if (this.hasMultipleRecipes()) {
sprite = SLOT_MANY_UNCRAFTABLE_SPRITE;
} else {
sprite = SLOT_UNCRAFTABLE_SPRITE;
}
boolean shouldAnimate = this.animationTime > 0.0F;
if (shouldAnimate) {
float squeeze = 1.0F + 0.1F * (float)Math.sin(this.animationTime / 15.0F * (float) Math.PI);
graphics.pose().pushMatrix();
graphics.pose().translate(this.getX() + 8, this.getY() + 12);
graphics.pose().scale(squeeze, squeeze);
graphics.pose().translate(-(this.getX() + 8), -(this.getY() + 12));
this.animationTime -= a;
}
graphics.blitSprite(RenderPipelines.GUI_TEXTURED, sprite, this.getX(), this.getY(), this.width, this.height);
ItemStack currentItemStack = this.getDisplayStack();
int offset = 4;
if (this.hasMultipleRecipes() && this.allRecipesHaveSameResultDisplay) {
graphics.item(currentItemStack, this.getX() + offset + 1, this.getY() + offset + 1, 0);
offset--;
}
graphics.fakeItem(currentItemStack, this.getX() + offset, this.getY() + offset);
if (shouldAnimate) {
graphics.pose().popMatrix();
}
}
private boolean hasMultipleRecipes() {
return this.selectedEntries.size() > 1;
}
public boolean isOnlyOption() {
return this.selectedEntries.size() == 1;
}
public RecipeDisplayId getCurrentRecipe() {
int index = this.slotSelectTime.currentIndex() % this.selectedEntries.size();
return this.selectedEntries.get(index).id;
}
public ItemStack getDisplayStack() {
int currentIndex = this.slotSelectTime.currentIndex();
int entryCount = this.selectedEntries.size();
int offsetIndex = currentIndex / entryCount;
int entryIndex = currentIndex - entryCount * offsetIndex;
return this.selectedEntries.get(entryIndex).selectItem(offsetIndex);
}
public List<Component> getTooltipText(ItemStack displayStack) {
List<Component> texts = new ArrayList<>(Screen.getTooltipFromItem(Minecraft.getInstance(), displayStack));
if (this.hasMultipleRecipes()) {
texts.add(MORE_RECIPES_TOOLTIP);
}
return texts;
}
@Override
public void updateWidgetNarration(NarrationElementOutput output) {
output.add(NarratedElementType.TITLE, Component.translatable("narration.recipe", this.getDisplayStack().getHoverName()));
if (this.hasMultipleRecipes()) {
output.add(
NarratedElementType.USAGE, Component.translatable("narration.button.usage.hovered"), Component.translatable("narration.recipe.usage.more")
);
} else {
output.add(NarratedElementType.USAGE, Component.translatable("narration.button.usage.hovered"));
}
}
@Override
public int getWidth() {
return 25;
}
@Override
protected boolean isValidClickButton(MouseButtonInfo buttonInfo) {
return buttonInfo.button() == 0 || buttonInfo.button() == 1;
}
@OnlyIn(Dist.CLIENT)
private record ResolvedEntry(RecipeDisplayId id, List<ItemStack> displayItems) {
public ItemStack selectItem(int index) {
if (this.displayItems.isEmpty()) {
return ItemStack.EMPTY;
} else {
int offset = index % this.displayItems.size();
return this.displayItems.get(offset);
}
}
}
}引用的其他类
-
- 引用位置:
方法调用 - 关联成员:
Minecraft.getInstance()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
继承
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Screen.getTooltipFromItem()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数/字段/返回值
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
字段/方法调用/返回值 - 关联成员:
Component.translatable()
- 引用位置:
-
- 引用位置:
字段/方法调用 - 关联成员:
Identifier.withDefaultNamespace()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数/方法调用/返回值 - 关联成员:
ItemStack.isSameItemSameComponents()
- 引用位置:
-
- 引用位置:
返回值
- 引用位置: