Gui.java

net.minecraft.client.gui.Gui

信息

  • 全限定名:net.minecraft.client.gui.Gui
  • 类型:public class
  • 包:net.minecraft.client.gui
  • 源码路径:src/main/java/net/minecraft/client/gui/Gui.java
  • 起始行号:L84
  • 职责:

    TODO

字段/常量

  • CROSSHAIR_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L85
    • 说明:

      TODO

  • CROSSHAIR_ATTACK_INDICATOR_FULL_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L86
    • 说明:

      TODO

  • CROSSHAIR_ATTACK_INDICATOR_BACKGROUND_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L87
    • 说明:

      TODO

  • CROSSHAIR_ATTACK_INDICATOR_PROGRESS_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L88
    • 说明:

      TODO

  • EFFECT_BACKGROUND_AMBIENT_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L89
    • 说明:

      TODO

  • EFFECT_BACKGROUND_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L90
    • 说明:

      TODO

  • HOTBAR_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L91
    • 说明:

      TODO

  • HOTBAR_SELECTION_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L92
    • 说明:

      TODO

  • HOTBAR_OFFHAND_LEFT_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L93
    • 说明:

      TODO

  • HOTBAR_OFFHAND_RIGHT_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L94
    • 说明:

      TODO

  • HOTBAR_ATTACK_INDICATOR_BACKGROUND_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L95
    • 说明:

      TODO

  • HOTBAR_ATTACK_INDICATOR_PROGRESS_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L96
    • 说明:

      TODO

  • ARMOR_EMPTY_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L97
    • 说明:

      TODO

  • ARMOR_HALF_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L98
    • 说明:

      TODO

  • ARMOR_FULL_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L99
    • 说明:

      TODO

  • FOOD_EMPTY_HUNGER_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L100
    • 说明:

      TODO

  • FOOD_HALF_HUNGER_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L101
    • 说明:

      TODO

  • FOOD_FULL_HUNGER_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L102
    • 说明:

      TODO

  • FOOD_EMPTY_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L103
    • 说明:

      TODO

  • FOOD_HALF_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L104
    • 说明:

      TODO

  • FOOD_FULL_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L105
    • 说明:

      TODO

  • AIR_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L106
    • 说明:

      TODO

  • AIR_POPPING_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L107
    • 说明:

      TODO

  • AIR_EMPTY_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L108
    • 说明:

      TODO

  • HEART_VEHICLE_CONTAINER_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L109
    • 说明:

      TODO

  • HEART_VEHICLE_FULL_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L110
    • 说明:

      TODO

  • HEART_VEHICLE_HALF_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L111
    • 说明:

      TODO

  • VIGNETTE_LOCATION

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L112
    • 说明:

      TODO

  • NAUSEA_LOCATION

    • 类型: Identifier
    • 修饰符: public static final
    • 源码定位: L113
    • 说明:

      TODO

  • SPYGLASS_SCOPE_LOCATION

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L114
    • 说明:

      TODO

  • POWDER_SNOW_OUTLINE_LOCATION

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L115
    • 说明:

      TODO

  • SCORE_DISPLAY_ORDER

    • 类型: Comparator<PlayerScoreEntry>
    • 修饰符: private static final
    • 源码定位: L116
    • 说明:

      TODO

  • DEMO_EXPIRED_TEXT

    • 类型: Component
    • 修饰符: private static final
    • 源码定位: L119
    • 说明:

      TODO

  • SAVING_TEXT

    • 类型: Component
    • 修饰符: private static final
    • 源码定位: L120
    • 说明:

      TODO

  • MIN_CROSSHAIR_ATTACK_SPEED

    • 类型: float
    • 修饰符: private static final
    • 源码定位: L121
    • 说明:

      TODO

  • EXPERIENCE_BAR_DISPLAY_TICKS

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L122
    • 说明:

      TODO

  • NUM_HEARTS_PER_ROW

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L123
    • 说明:

      TODO

  • LINE_HEIGHT

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L124
    • 说明:

      TODO

  • SPACER

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L125
    • 说明:

      TODO

  • PORTAL_OVERLAY_ALPHA_MIN

    • 类型: float
    • 修饰符: private static final
    • 源码定位: L126
    • 说明:

      TODO

  • HEART_SIZE

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L127
    • 说明:

      TODO

  • HEART_SEPARATION

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L128
    • 说明:

      TODO

  • NUM_AIR_BUBBLES

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L129
    • 说明:

      TODO

  • AIR_BUBBLE_SIZE

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L130
    • 说明:

      TODO

  • AIR_BUBBLE_SEPERATION

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L131
    • 说明:

      TODO

  • AIR_BUBBLE_POPPING_DURATION

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L132
    • 说明:

      TODO

  • EMPTY_AIR_BUBBLE_DELAY_DURATION

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L133
    • 说明:

      TODO

  • AIR_BUBBLE_POP_SOUND_VOLUME_BASE

    • 类型: float
    • 修饰符: private static final
    • 源码定位: L134
    • 说明:

      TODO

  • AIR_BUBBLE_POP_SOUND_VOLUME_INCREMENT

    • 类型: float
    • 修饰符: private static final
    • 源码定位: L135
    • 说明:

      TODO

  • AIR_BUBBLE_POP_SOUND_PITCH_BASE

    • 类型: float
    • 修饰符: private static final
    • 源码定位: L136
    • 说明:

      TODO

  • AIR_BUBBLE_POP_SOUND_PITCH_INCREMENT

    • 类型: float
    • 修饰符: private static final
    • 源码定位: L137
    • 说明:

      TODO

  • NUM_AIR_BUBBLE_POPPED_BEFORE_SOUND_VOLUME_INCREASE

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L138
    • 说明:

      TODO

  • NUM_AIR_BUBBLE_POPPED_BEFORE_SOUND_PITCH_INCREASE

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L139
    • 说明:

      TODO

  • AUTOSAVE_FADE_SPEED_FACTOR

    • 类型: float
    • 修饰符: private static final
    • 源码定位: L140
    • 说明:

      TODO

  • SAVING_INDICATOR_WIDTH_PADDING_RIGHT

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L141
    • 说明:

      TODO

  • SAVING_INDICATOR_HEIGHT_PADDING_BOTTOM

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L142
    • 说明:

      TODO

  • random

    • 类型: RandomSource
    • 修饰符: private final
    • 源码定位: L143
    • 说明:

      TODO

  • minecraft

    • 类型: Minecraft
    • 修饰符: private final
    • 源码定位: L144
    • 说明:

      TODO

  • chat

    • 类型: ChatComponent
    • 修饰符: private final
    • 源码定位: L145
    • 说明:

      TODO

  • tickCount

    • 类型: int
    • 修饰符: private
    • 源码定位: L146
    • 说明:

      TODO

  • overlayMessageString

    • 类型: Component
    • 修饰符: private
    • 源码定位: L147
    • 说明:

      TODO

  • overlayMessageTime

    • 类型: int
    • 修饰符: private
    • 源码定位: L148
    • 说明:

      TODO

  • animateOverlayMessageColor

    • 类型: boolean
    • 修饰符: private
    • 源码定位: L149
    • 说明:

      TODO

  • vignetteBrightness

    • 类型: float
    • 修饰符: public
    • 源码定位: L150
    • 说明:

      TODO

  • toolHighlightTimer

    • 类型: int
    • 修饰符: private
    • 源码定位: L151
    • 说明:

      TODO

  • lastToolHighlight

    • 类型: ItemStack
    • 修饰符: private
    • 源码定位: L152
    • 说明:

      TODO

  • debugOverlay

    • 类型: DebugScreenOverlay
    • 修饰符: private final
    • 源码定位: L153
    • 说明:

      TODO

  • subtitleOverlay

    • 类型: SubtitleOverlay
    • 修饰符: private final
    • 源码定位: L154
    • 说明:

      TODO

  • spectatorGui

    • 类型: SpectatorGui
    • 修饰符: private final
    • 源码定位: L155
    • 说明:

      TODO

  • tabList

    • 类型: PlayerTabOverlay
    • 修饰符: private final
    • 源码定位: L156
    • 说明:

      TODO

  • bossOverlay

    • 类型: BossHealthOverlay
    • 修饰符: private final
    • 源码定位: L157
    • 说明:

      TODO

  • titleTime

    • 类型: int
    • 修饰符: private
    • 源码定位: L158
    • 说明:

      TODO

  • title

    • 类型: Component
    • 修饰符: private
    • 源码定位: L159
    • 说明:

      TODO

  • subtitle

    • 类型: Component
    • 修饰符: private
    • 源码定位: L160
    • 说明:

      TODO

  • titleFadeInTime

    • 类型: int
    • 修饰符: private
    • 源码定位: L161
    • 说明:

      TODO

  • titleStayTime

    • 类型: int
    • 修饰符: private
    • 源码定位: L162
    • 说明:

      TODO

  • titleFadeOutTime

    • 类型: int
    • 修饰符: private
    • 源码定位: L163
    • 说明:

      TODO

  • lastHealth

    • 类型: int
    • 修饰符: private
    • 源码定位: L164
    • 说明:

      TODO

  • displayHealth

    • 类型: int
    • 修饰符: private
    • 源码定位: L165
    • 说明:

      TODO

  • lastHealthTime

    • 类型: long
    • 修饰符: private
    • 源码定位: L166
    • 说明:

      TODO

  • healthBlinkTime

    • 类型: long
    • 修饰符: private
    • 源码定位: L167
    • 说明:

      TODO

  • lastBubblePopSoundPlayed

    • 类型: int
    • 修饰符: private
    • 源码定位: L168
    • 说明:

      TODO

  • deferredSubtitles

    • 类型: Runnable
    • 修饰符: private
    • 源码定位: L169
    • 说明:

      TODO

  • autosaveIndicatorValue

    • 类型: float
    • 修饰符: private
    • 源码定位: L170
    • 说明:

      TODO

  • lastAutosaveIndicatorValue

    • 类型: float
    • 修饰符: private
    • 源码定位: L171
    • 说明:

      TODO

  • contextualInfoBar

    • 类型: Pair<Gui.ContextualInfo,ContextualBarRenderer>
    • 修饰符: private
    • 源码定位: L172
    • 说明:

      TODO

  • contextualInfoBarRenderers

    • 类型: Map<Gui.ContextualInfo,Supplier<ContextualBarRenderer>>
    • 修饰符: private final
    • 源码定位: L173
    • 说明:

      TODO

  • scopeScale

    • 类型: float
    • 修饰符: private
    • 源码定位: L174
    • 说明:

      TODO

内部类/嵌套类型

  • net.minecraft.client.gui.Gui.DisplayEntry

    • 类型: record
    • 修饰符: package-private
    • 源码定位: L664
    • 说明:

      TODO

  • net.minecraft.client.gui.Gui.ContextualInfo

    • 类型: enum
    • 修饰符: static
    • 源码定位: L1330
    • 说明:

      TODO

  • net.minecraft.client.gui.Gui.HeartType

    • 类型: enum
    • 修饰符: private static
    • 源码定位: L1338
    • 说明:

      TODO

构造器

public Gui(Minecraft minecraft) @ L176

  • 构造器名:Gui
  • 源码定位:L176
  • 修饰符:public

参数:

  • minecraft: Minecraft

说明:

TODO

方法

下面的方法块按源码顺序生成。

public void resetTitleTimes() @ L197

  • 方法名:resetTitleTimes
  • 源码定位:L197
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public void extractRenderState(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker) @ L203

  • 方法名:extractRenderState
  • 源码定位:L203
  • 返回类型:void
  • 修饰符:public

参数:

  • graphics: GuiGraphicsExtractor
  • deltaTracker: DeltaTracker

说明:

TODO

private void extractBossOverlay(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker) @ L229

  • 方法名:extractBossOverlay
  • 源码定位:L229
  • 返回类型:void
  • 修饰符:private

参数:

  • graphics: GuiGraphicsExtractor
  • deltaTracker: DeltaTracker

说明:

TODO

public void extractDebugOverlay(GuiGraphicsExtractor graphics) @ L233

  • 方法名:extractDebugOverlay
  • 源码定位:L233
  • 返回类型:void
  • 修饰符:public

参数:

  • graphics: GuiGraphicsExtractor

说明:

TODO

private void extractSubtitleOverlay(GuiGraphicsExtractor graphics, boolean deferRendering) @ L237

  • 方法名:extractSubtitleOverlay
  • 源码定位:L237
  • 返回类型:void
  • 修饰符:private

参数:

  • graphics: GuiGraphicsExtractor
  • deferRendering: boolean

说明:

TODO

public void extractDeferredSubtitles() @ L246

  • 方法名:extractDeferredSubtitles
  • 源码定位:L246
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

private void extractCameraOverlays(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker) @ L253

  • 方法名:extractCameraOverlays
  • 源码定位:L253
  • 返回类型:void
  • 修饰符:private

参数:

  • graphics: GuiGraphicsExtractor
  • deltaTracker: DeltaTracker

说明:

TODO

private void extractSleepOverlay(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker) @ L295

  • 方法名:extractSleepOverlay
  • 源码定位:L295
  • 返回类型:void
  • 修饰符:private

参数:

  • graphics: GuiGraphicsExtractor
  • deltaTracker: DeltaTracker

说明:

TODO

private void extractOverlayMessage(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker) @ L311

  • 方法名:extractOverlayMessage
  • 源码定位:L311
  • 返回类型:void
  • 修饰符:private

参数:

  • graphics: GuiGraphicsExtractor
  • deltaTracker: DeltaTracker

说明:

TODO

private void extractTitle(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker) @ L341

  • 方法名:extractTitle
  • 源码定位:L341
  • 返回类型:void
  • 修饰符:private

参数:

  • graphics: GuiGraphicsExtractor
  • deltaTracker: DeltaTracker

说明:

TODO

private void extractChat(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker) @ L382

  • 方法名:extractChat
  • 源码定位:L382
  • 返回类型:void
  • 修饰符:private

参数:

  • graphics: GuiGraphicsExtractor
  • deltaTracker: DeltaTracker

说明:

TODO

private void extractScoreboardSidebar(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker) @ L392

  • 方法名:extractScoreboardSidebar
  • 源码定位:L392
  • 返回类型:void
  • 修饰符:private

参数:

  • graphics: GuiGraphicsExtractor
  • deltaTracker: DeltaTracker

说明:

TODO

private void extractTabList(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker) @ L410

  • 方法名:extractTabList
  • 源码定位:L410
  • 返回类型:void
  • 修饰符:private

参数:

  • graphics: GuiGraphicsExtractor
  • deltaTracker: DeltaTracker

说明:

TODO

private void extractCrosshair(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker) @ L423

  • 方法名:extractCrosshair
  • 源码定位:L423
  • 返回类型:void
  • 修饰符:private

参数:

  • graphics: GuiGraphicsExtractor
  • deltaTracker: DeltaTracker

说明:

TODO

private boolean canRenderCrosshairForSpectator(HitResult hitResult) @ L459

  • 方法名:canRenderCrosshairForSpectator
  • 源码定位:L459
  • 返回类型:boolean
  • 修饰符:private

参数:

  • hitResult: HitResult

说明:

TODO

private void extractEffects(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker) @ L473

  • 方法名:extractEffects
  • 源码定位:L473
  • 返回类型:void
  • 修饰符:private

参数:

  • graphics: GuiGraphicsExtractor
  • deltaTracker: DeltaTracker

说明:

TODO

public static Identifier getMobEffectSprite(Holder<MobEffect> effect) @ L517

  • 方法名:getMobEffectSprite
  • 源码定位:L517
  • 返回类型:Identifier
  • 修饰符:public static

参数:

  • effect: Holder

说明:

TODO

private void extractHotbarAndDecorations(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker) @ L521

  • 方法名:extractHotbarAndDecorations
  • 源码定位:L521
  • 返回类型:void
  • 修饰符:private

参数:

  • graphics: GuiGraphicsExtractor
  • deltaTracker: DeltaTracker

说明:

TODO

private void extractItemHotbar(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker) @ L551

  • 方法名:extractItemHotbar
  • 源码定位:L551
  • 返回类型:void
  • 修饰符:private

参数:

  • graphics: GuiGraphicsExtractor
  • deltaTracker: DeltaTracker

说明:

TODO

private void extractSelectedItemName(GuiGraphicsExtractor graphics) @ L612

  • 方法名:extractSelectedItemName
  • 源码定位:L612
  • 返回类型:void
  • 修饰符:private

参数:

  • graphics: GuiGraphicsExtractor

说明:

TODO

private void extractDemoOverlay(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker) @ L637

  • 方法名:extractDemoOverlay
  • 源码定位:L637
  • 返回类型:void
  • 修饰符:private

参数:

  • graphics: GuiGraphicsExtractor
  • deltaTracker: DeltaTracker

说明:

TODO

private void displayScoreboardSidebar(GuiGraphicsExtractor graphics, Objective objective) @ L659

  • 方法名:displayScoreboardSidebar
  • 源码定位:L659
  • 返回类型:void
  • 修饰符:private

参数:

  • graphics: GuiGraphicsExtractor
  • objective: Objective

说明:

TODO

private Player getCameraPlayer() @ L711

  • 方法名:getCameraPlayer
  • 源码定位:L711
  • 返回类型:Player
  • 修饰符:private

参数:

说明:

TODO

private LivingEntity getPlayerVehicleWithHealth() @ L715

  • 方法名:getPlayerVehicleWithHealth
  • 源码定位:L715
  • 返回类型:LivingEntity
  • 修饰符:private

参数:

说明:

TODO

private int getVehicleMaxHearts(LivingEntity vehicle) @ L731

  • 方法名:getVehicleMaxHearts
  • 源码定位:L731
  • 返回类型:int
  • 修饰符:private

参数:

  • vehicle: LivingEntity

说明:

TODO

private int getVisibleVehicleHeartRows(int hearts) @ L745

  • 方法名:getVisibleVehicleHeartRows
  • 源码定位:L745
  • 返回类型:int
  • 修饰符:private

参数:

  • hearts: int

说明:

TODO

private void extractPlayerHealth(GuiGraphicsExtractor graphics) @ L749

  • 方法名:extractPlayerHealth
  • 源码定位:L749
  • 返回类型:void
  • 修饰符:private

参数:

  • graphics: GuiGraphicsExtractor

说明:

TODO

private static void extractArmor(GuiGraphicsExtractor graphics, Player player, int yLineBase, int numHealthRows, int healthRowHeight, int xLeft) @ L804

  • 方法名:extractArmor
  • 源码定位:L804
  • 返回类型:void
  • 修饰符:private static

参数:

  • graphics: GuiGraphicsExtractor
  • player: Player
  • yLineBase: int
  • numHealthRows: int
  • healthRowHeight: int
  • xLeft: int

说明:

TODO

  • 方法名:extractHearts
  • 源码定位:L826
  • 返回类型:void
  • 修饰符:private

参数:

  • graphics: GuiGraphicsExtractor
  • player: Player
  • xLeft: int
  • yLineBase: int
  • healthRowHeight: int
  • heartOffsetIndex: int
  • maxHealth: float
  • currentHealth: int
  • oldHealth: int
  • absorption: int
  • blink: boolean

说明:

TODO

  • 方法名:extractHeart
  • 源码定位:L881
  • 返回类型:void
  • 修饰符:private

参数:

  • graphics: GuiGraphicsExtractor
  • type: Gui.HeartType
  • xo: int
  • yo: int
  • isHardcore: boolean
  • blinks: boolean
  • half: boolean

说明:

TODO

private void extractAirBubbles(GuiGraphicsExtractor graphics, Player player, int vehicleHearts, int yLineAir, int xRight) @ L885

  • 方法名:extractAirBubbles
  • 源码定位:L885
  • 返回类型:void
  • 修饰符:private

参数:

  • graphics: GuiGraphicsExtractor
  • player: Player
  • vehicleHearts: int
  • yLineAir: int
  • xRight: int

说明:

TODO

private int getAirBubbleYLine(int vehicleHearts, int yLineAir) @ L915

  • 方法名:getAirBubbleYLine
  • 源码定位:L915
  • 返回类型:int
  • 修饰符:private

参数:

  • vehicleHearts: int
  • yLineAir: int

说明:

TODO

private static int getCurrentAirSupplyBubble(int currentAirSupplyTicks, int maxAirSupplyTicks, int tickOffset) @ L920

  • 方法名:getCurrentAirSupplyBubble
  • 源码定位:L920
  • 返回类型:int
  • 修饰符:private static

参数:

  • currentAirSupplyTicks: int
  • maxAirSupplyTicks: int
  • tickOffset: int

说明:

TODO

private static int getEmptyBubbleDelayDuration(int currentAirSupplyTicks, boolean isUnderWater) @ L924

  • 方法名:getEmptyBubbleDelayDuration
  • 源码定位:L924
  • 返回类型:int
  • 修饰符:private static

参数:

  • currentAirSupplyTicks: int
  • isUnderWater: boolean

说明:

TODO

private void playAirBubblePoppedSound(int bubble, Player player, int emptyAirBubbles) @ L928

  • 方法名:playAirBubblePoppedSound
  • 源码定位:L928
  • 返回类型:void
  • 修饰符:private

参数:

  • bubble: int
  • player: Player
  • emptyAirBubbles: int

说明:

TODO

private void extractFood(GuiGraphicsExtractor graphics, Player player, int yLineBase, int xRight) @ L937

  • 方法名:extractFood
  • 源码定位:L937
  • 返回类型:void
  • 修饰符:private

参数:

  • graphics: GuiGraphicsExtractor
  • player: Player
  • yLineBase: int
  • xRight: int

说明:

TODO

private void extractVehicleHealth(GuiGraphicsExtractor graphics) @ L972

  • 方法名:extractVehicleHealth
  • 源码定位:L972
  • 返回类型:void
  • 修饰符:private

参数:

  • graphics: GuiGraphicsExtractor

说明:

TODO

private void extractTextureOverlay(GuiGraphicsExtractor graphics, Identifier texture, float alpha) @ L1005

  • 方法名:extractTextureOverlay
  • 源码定位:L1005
  • 返回类型:void
  • 修饰符:private

参数:

  • graphics: GuiGraphicsExtractor
  • texture: Identifier
  • alpha: float

说明:

TODO

private void extractSpyglassOverlay(GuiGraphicsExtractor graphics, float scale) @ L1022

  • 方法名:extractSpyglassOverlay
  • 源码定位:L1022
  • 返回类型:void
  • 修饰符:private

参数:

  • graphics: GuiGraphicsExtractor
  • scale: float

说明:

TODO

private void updateVignetteBrightness(Entity camera) @ L1038

  • 方法名:updateVignetteBrightness
  • 源码定位:L1038
  • 返回类型:void
  • 修饰符:private

参数:

  • camera: Entity

说明:

TODO

private void extractVignette(GuiGraphicsExtractor graphics, Entity camera) @ L1045

  • 方法名:extractVignette
  • 源码定位:L1045
  • 返回类型:void
  • 修饰符:private

参数:

  • graphics: GuiGraphicsExtractor
  • camera: Entity

说明:

TODO

private void extractPortalOverlay(GuiGraphicsExtractor graphics, float alpha) @ L1085

  • 方法名:extractPortalOverlay
  • 源码定位:L1085
  • 返回类型:void
  • 修饰符:private

参数:

  • graphics: GuiGraphicsExtractor
  • alpha: float

说明:

TODO

private void extractConfusionOverlay(GuiGraphicsExtractor graphics, float strength) @ L1101

  • 方法名:extractConfusionOverlay
  • 源码定位:L1101
  • 返回类型:void
  • 修饰符:private

参数:

  • graphics: GuiGraphicsExtractor
  • strength: float

说明:

TODO

private void extractSlot(GuiGraphicsExtractor graphics, int x, int y, DeltaTracker deltaTracker, Player player, ItemStack itemStack, int seed) @ L1128

  • 方法名:extractSlot
  • 源码定位:L1128
  • 返回类型:void
  • 修饰符:private

参数:

  • graphics: GuiGraphicsExtractor
  • x: int
  • y: int
  • deltaTracker: DeltaTracker
  • player: Player
  • itemStack: ItemStack
  • seed: int

说明:

TODO

public void tick(boolean pause) @ L1148

  • 方法名:tick
  • 源码定位:L1148
  • 返回类型:void
  • 修饰符:public

参数:

  • pause: boolean

说明:

TODO

private void tick() @ L1155

  • 方法名:tick
  • 源码定位:L1155
  • 返回类型:void
  • 修饰符:private

参数:

说明:

TODO

private void tickAutosaveIndicator() @ L1192

  • 方法名:tickAutosaveIndicator
  • 源码定位:L1192
  • 返回类型:void
  • 修饰符:private

参数:

说明:

TODO

public void setNowPlaying(Component string) @ L1199

  • 方法名:setNowPlaying
  • 源码定位:L1199
  • 返回类型:void
  • 修饰符:public

参数:

  • string: Component

说明:

TODO

public void setOverlayMessage(Component string, boolean animate) @ L1205

  • 方法名:setOverlayMessage
  • 源码定位:L1205
  • 返回类型:void
  • 修饰符:public

参数:

  • string: Component
  • animate: boolean

说明:

TODO

public void setTimes(int fadeInTime, int stayTime, int fadeOutTime) @ L1211

  • 方法名:setTimes
  • 源码定位:L1211
  • 返回类型:void
  • 修饰符:public

参数:

  • fadeInTime: int
  • stayTime: int
  • fadeOutTime: int

说明:

TODO

public void setSubtitle(Component subtitle) @ L1229

  • 方法名:setSubtitle
  • 源码定位:L1229
  • 返回类型:void
  • 修饰符:public

参数:

  • subtitle: Component

说明:

TODO

public void setTitle(Component title) @ L1233

  • 方法名:setTitle
  • 源码定位:L1233
  • 返回类型:void
  • 修饰符:public

参数:

  • title: Component

说明:

TODO

public void clearTitles() @ L1238

  • 方法名:clearTitles
  • 源码定位:L1238
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public ChatComponent getChat() @ L1244

  • 方法名:getChat
  • 源码定位:L1244
  • 返回类型:ChatComponent
  • 修饰符:public

参数:

说明:

TODO

public int getGuiTicks() @ L1248

  • 方法名:getGuiTicks
  • 源码定位:L1248
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public Font getFont() @ L1252

  • 方法名:getFont
  • 源码定位:L1252
  • 返回类型:Font
  • 修饰符:public

参数:

说明:

TODO

public SpectatorGui getSpectatorGui() @ L1256

  • 方法名:getSpectatorGui
  • 源码定位:L1256
  • 返回类型:SpectatorGui
  • 修饰符:public

参数:

说明:

TODO

public PlayerTabOverlay getTabList() @ L1260

  • 方法名:getTabList
  • 源码定位:L1260
  • 返回类型:PlayerTabOverlay
  • 修饰符:public

参数:

说明:

TODO

public void onDisconnected() @ L1264

  • 方法名:onDisconnected
  • 源码定位:L1264
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public BossHealthOverlay getBossOverlay() @ L1274

  • 方法名:getBossOverlay
  • 源码定位:L1274
  • 返回类型:BossHealthOverlay
  • 修饰符:public

参数:

说明:

TODO

public DebugScreenOverlay getDebugOverlay() @ L1278

  • 方法名:getDebugOverlay
  • 源码定位:L1278
  • 返回类型:DebugScreenOverlay
  • 修饰符:public

参数:

说明:

TODO

public void clearCache() @ L1282

  • 方法名:clearCache
  • 源码定位:L1282
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public void extractSavingIndicator(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker) @ L1286

  • 方法名:extractSavingIndicator
  • 源码定位:L1286
  • 返回类型:void
  • 修饰符:public

参数:

  • graphics: GuiGraphicsExtractor
  • deltaTracker: DeltaTracker

说明:

TODO

private boolean willPrioritizeExperienceInfo() @ L1303

  • 方法名:willPrioritizeExperienceInfo
  • 源码定位:L1303
  • 返回类型:boolean
  • 修饰符:private

参数:

说明:

TODO

private boolean willPrioritizeJumpInfo() @ L1307

  • 方法名:willPrioritizeJumpInfo
  • 源码定位:L1307
  • 返回类型:boolean
  • 修饰符:private

参数:

说明:

TODO

private Gui.ContextualInfo nextContextualInfoState() @ L1312

  • 方法名:nextContextualInfoState
  • 源码定位:L1312
  • 返回类型:Gui.ContextualInfo
  • 修饰符:private

参数:

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
public class Gui {
    private static final Identifier CROSSHAIR_SPRITE = Identifier.withDefaultNamespace("hud/crosshair");
    private static final Identifier CROSSHAIR_ATTACK_INDICATOR_FULL_SPRITE = Identifier.withDefaultNamespace("hud/crosshair_attack_indicator_full");
    private static final Identifier CROSSHAIR_ATTACK_INDICATOR_BACKGROUND_SPRITE = Identifier.withDefaultNamespace("hud/crosshair_attack_indicator_background");
    private static final Identifier CROSSHAIR_ATTACK_INDICATOR_PROGRESS_SPRITE = Identifier.withDefaultNamespace("hud/crosshair_attack_indicator_progress");
    private static final Identifier EFFECT_BACKGROUND_AMBIENT_SPRITE = Identifier.withDefaultNamespace("hud/effect_background_ambient");
    private static final Identifier EFFECT_BACKGROUND_SPRITE = Identifier.withDefaultNamespace("hud/effect_background");
    private static final Identifier HOTBAR_SPRITE = Identifier.withDefaultNamespace("hud/hotbar");
    private static final Identifier HOTBAR_SELECTION_SPRITE = Identifier.withDefaultNamespace("hud/hotbar_selection");
    private static final Identifier HOTBAR_OFFHAND_LEFT_SPRITE = Identifier.withDefaultNamespace("hud/hotbar_offhand_left");
    private static final Identifier HOTBAR_OFFHAND_RIGHT_SPRITE = Identifier.withDefaultNamespace("hud/hotbar_offhand_right");
    private static final Identifier HOTBAR_ATTACK_INDICATOR_BACKGROUND_SPRITE = Identifier.withDefaultNamespace("hud/hotbar_attack_indicator_background");
    private static final Identifier HOTBAR_ATTACK_INDICATOR_PROGRESS_SPRITE = Identifier.withDefaultNamespace("hud/hotbar_attack_indicator_progress");
    private static final Identifier ARMOR_EMPTY_SPRITE = Identifier.withDefaultNamespace("hud/armor_empty");
    private static final Identifier ARMOR_HALF_SPRITE = Identifier.withDefaultNamespace("hud/armor_half");
    private static final Identifier ARMOR_FULL_SPRITE = Identifier.withDefaultNamespace("hud/armor_full");
    private static final Identifier FOOD_EMPTY_HUNGER_SPRITE = Identifier.withDefaultNamespace("hud/food_empty_hunger");
    private static final Identifier FOOD_HALF_HUNGER_SPRITE = Identifier.withDefaultNamespace("hud/food_half_hunger");
    private static final Identifier FOOD_FULL_HUNGER_SPRITE = Identifier.withDefaultNamespace("hud/food_full_hunger");
    private static final Identifier FOOD_EMPTY_SPRITE = Identifier.withDefaultNamespace("hud/food_empty");
    private static final Identifier FOOD_HALF_SPRITE = Identifier.withDefaultNamespace("hud/food_half");
    private static final Identifier FOOD_FULL_SPRITE = Identifier.withDefaultNamespace("hud/food_full");
    private static final Identifier AIR_SPRITE = Identifier.withDefaultNamespace("hud/air");
    private static final Identifier AIR_POPPING_SPRITE = Identifier.withDefaultNamespace("hud/air_bursting");
    private static final Identifier AIR_EMPTY_SPRITE = Identifier.withDefaultNamespace("hud/air_empty");
    private static final Identifier HEART_VEHICLE_CONTAINER_SPRITE = Identifier.withDefaultNamespace("hud/heart/vehicle_container");
    private static final Identifier HEART_VEHICLE_FULL_SPRITE = Identifier.withDefaultNamespace("hud/heart/vehicle_full");
    private static final Identifier HEART_VEHICLE_HALF_SPRITE = Identifier.withDefaultNamespace("hud/heart/vehicle_half");
    private static final Identifier VIGNETTE_LOCATION = Identifier.withDefaultNamespace("textures/misc/vignette.png");
    public static final Identifier NAUSEA_LOCATION = Identifier.withDefaultNamespace("textures/misc/nausea.png");
    private static final Identifier SPYGLASS_SCOPE_LOCATION = Identifier.withDefaultNamespace("textures/misc/spyglass_scope.png");
    private static final Identifier POWDER_SNOW_OUTLINE_LOCATION = Identifier.withDefaultNamespace("textures/misc/powder_snow_outline.png");
    private static final Comparator<PlayerScoreEntry> SCORE_DISPLAY_ORDER = Comparator.comparing(PlayerScoreEntry::value)
        .reversed()
        .thenComparing(PlayerScoreEntry::owner, String.CASE_INSENSITIVE_ORDER);
    private static final Component DEMO_EXPIRED_TEXT = Component.translatable("demo.demoExpired");
    private static final Component SAVING_TEXT = Component.translatable("menu.savingLevel");
    private static final float MIN_CROSSHAIR_ATTACK_SPEED = 5.0F;
    private static final int EXPERIENCE_BAR_DISPLAY_TICKS = 100;
    private static final int NUM_HEARTS_PER_ROW = 10;
    private static final int LINE_HEIGHT = 10;
    private static final String SPACER = ": ";
    private static final float PORTAL_OVERLAY_ALPHA_MIN = 0.2F;
    private static final int HEART_SIZE = 9;
    private static final int HEART_SEPARATION = 8;
    private static final int NUM_AIR_BUBBLES = 10;
    private static final int AIR_BUBBLE_SIZE = 9;
    private static final int AIR_BUBBLE_SEPERATION = 8;
    private static final int AIR_BUBBLE_POPPING_DURATION = 2;
    private static final int EMPTY_AIR_BUBBLE_DELAY_DURATION = 1;
    private static final float AIR_BUBBLE_POP_SOUND_VOLUME_BASE = 0.5F;
    private static final float AIR_BUBBLE_POP_SOUND_VOLUME_INCREMENT = 0.1F;
    private static final float AIR_BUBBLE_POP_SOUND_PITCH_BASE = 1.0F;
    private static final float AIR_BUBBLE_POP_SOUND_PITCH_INCREMENT = 0.1F;
    private static final int NUM_AIR_BUBBLE_POPPED_BEFORE_SOUND_VOLUME_INCREASE = 3;
    private static final int NUM_AIR_BUBBLE_POPPED_BEFORE_SOUND_PITCH_INCREASE = 5;
    private static final float AUTOSAVE_FADE_SPEED_FACTOR = 0.2F;
    private static final int SAVING_INDICATOR_WIDTH_PADDING_RIGHT = 5;
    private static final int SAVING_INDICATOR_HEIGHT_PADDING_BOTTOM = 5;
    private final RandomSource random = RandomSource.create();
    private final Minecraft minecraft;
    private final ChatComponent chat;
    private int tickCount;
    private @Nullable Component overlayMessageString;
    private int overlayMessageTime;
    private boolean animateOverlayMessageColor;
    public float vignetteBrightness = 1.0F;
    private int toolHighlightTimer;
    private ItemStack lastToolHighlight = ItemStack.EMPTY;
    private final DebugScreenOverlay debugOverlay;
    private final SubtitleOverlay subtitleOverlay;
    private final SpectatorGui spectatorGui;
    private final PlayerTabOverlay tabList;
    private final BossHealthOverlay bossOverlay;
    private int titleTime;
    private @Nullable Component title;
    private @Nullable Component subtitle;
    private int titleFadeInTime;
    private int titleStayTime;
    private int titleFadeOutTime;
    private int lastHealth;
    private int displayHealth;
    private long lastHealthTime;
    private long healthBlinkTime;
    private int lastBubblePopSoundPlayed;
    private @Nullable Runnable deferredSubtitles;
    private float autosaveIndicatorValue;
    private float lastAutosaveIndicatorValue;
    private Pair<Gui.ContextualInfo, ContextualBarRenderer> contextualInfoBar = Pair.of(Gui.ContextualInfo.EMPTY, ContextualBarRenderer.EMPTY);
    private final Map<Gui.ContextualInfo, Supplier<ContextualBarRenderer>> contextualInfoBarRenderers;
    private float scopeScale;
 
    public Gui(Minecraft minecraft) {
        this.minecraft = minecraft;
        this.debugOverlay = new DebugScreenOverlay(minecraft);
        this.spectatorGui = new SpectatorGui(minecraft);
        this.chat = new ChatComponent(minecraft);
        this.tabList = new PlayerTabOverlay(minecraft, this);
        this.bossOverlay = new BossHealthOverlay(minecraft);
        this.subtitleOverlay = new SubtitleOverlay(minecraft);
        this.contextualInfoBarRenderers = ImmutableMap.of(
            Gui.ContextualInfo.EMPTY,
            () -> ContextualBarRenderer.EMPTY,
            Gui.ContextualInfo.EXPERIENCE,
            () -> new ExperienceBarRenderer(minecraft),
            Gui.ContextualInfo.LOCATOR,
            () -> new LocatorBarRenderer(minecraft),
            Gui.ContextualInfo.JUMPABLE_VEHICLE,
            () -> new JumpableVehicleBarRenderer(minecraft)
        );
        this.resetTitleTimes();
    }
 
    public void resetTitleTimes() {
        this.titleFadeInTime = 10;
        this.titleStayTime = 70;
        this.titleFadeOutTime = 20;
    }
 
    public void extractRenderState(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker) {
        if (!(this.minecraft.screen instanceof LevelLoadingScreen)) {
            if (!this.minecraft.options.hideGui) {
                this.extractCameraOverlays(graphics, deltaTracker);
                this.extractCrosshair(graphics, deltaTracker);
                graphics.nextStratum();
                this.extractHotbarAndDecorations(graphics, deltaTracker);
                this.extractEffects(graphics, deltaTracker);
                this.extractBossOverlay(graphics, deltaTracker);
            }
 
            this.extractSleepOverlay(graphics, deltaTracker);
            if (!this.minecraft.options.hideGui) {
                this.extractDemoOverlay(graphics, deltaTracker);
                this.extractScoreboardSidebar(graphics, deltaTracker);
                this.extractOverlayMessage(graphics, deltaTracker);
                this.extractTitle(graphics, deltaTracker);
                this.extractChat(graphics, deltaTracker);
                this.extractTabList(graphics, deltaTracker);
                this.extractSubtitleOverlay(graphics, this.minecraft.screen == null || this.minecraft.screen.isInGameUi());
            } else if (this.minecraft.screen != null && this.minecraft.screen.isInGameUi()) {
                this.extractSubtitleOverlay(graphics, true);
            }
        }
    }
 
    private void extractBossOverlay(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker) {
        this.bossOverlay.extractRenderState(graphics);
    }
 
    public void extractDebugOverlay(GuiGraphicsExtractor graphics) {
        this.debugOverlay.extractRenderState(graphics);
    }
 
    private void extractSubtitleOverlay(GuiGraphicsExtractor graphics, boolean deferRendering) {
        if (deferRendering) {
            this.deferredSubtitles = () -> this.subtitleOverlay.extractRenderState(graphics);
        } else {
            this.deferredSubtitles = null;
            this.subtitleOverlay.extractRenderState(graphics);
        }
    }
 
    public void extractDeferredSubtitles() {
        if (this.deferredSubtitles != null) {
            this.deferredSubtitles.run();
            this.deferredSubtitles = null;
        }
    }
 
    private void extractCameraOverlays(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker) {
        if (this.minecraft.options.vignette().get()) {
            this.extractVignette(graphics, this.minecraft.getCameraEntity());
        }
 
        LocalPlayer player = this.minecraft.player;
        float gameTimeDeltaTicks = deltaTracker.getGameTimeDeltaTicks();
        this.scopeScale = Mth.lerp(0.5F * gameTimeDeltaTicks, this.scopeScale, 1.125F);
        if (this.minecraft.options.getCameraType().isFirstPerson()) {
            if (player.isScoping()) {
                this.extractSpyglassOverlay(graphics, this.scopeScale);
            } else {
                this.scopeScale = 0.5F;
 
                for (EquipmentSlot slot : EquipmentSlot.values()) {
                    ItemStack item = player.getItemBySlot(slot);
                    Equippable equippable = item.get(DataComponents.EQUIPPABLE);
                    if (equippable != null && equippable.slot() == slot && equippable.cameraOverlay().isPresent()) {
                        this.extractTextureOverlay(graphics, equippable.cameraOverlay().get().withPath(p -> "textures/" + p + ".png"), 1.0F);
                    }
                }
            }
        }
 
        if (player.getTicksFrozen() > 0) {
            this.extractTextureOverlay(graphics, POWDER_SNOW_OUTLINE_LOCATION, player.getPercentFrozen());
        }
 
        float partialTicks = deltaTracker.getGameTimeDeltaPartialTick(false);
        float portalIntensity = Mth.lerp(partialTicks, player.oPortalEffectIntensity, player.portalEffectIntensity);
        float nauseaIntensity = player.getEffectBlendFactor(MobEffects.NAUSEA, partialTicks);
        if (portalIntensity > 0.0F) {
            this.extractPortalOverlay(graphics, portalIntensity);
        } else if (nauseaIntensity > 0.0F) {
            float screenEffectScale = this.minecraft.options.screenEffectScale().get().floatValue();
            if (screenEffectScale < 1.0F) {
                float overlayStrength = nauseaIntensity * (1.0F - screenEffectScale);
                this.extractConfusionOverlay(graphics, overlayStrength);
            }
        }
    }
 
    private void extractSleepOverlay(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker) {
        if (this.minecraft.player.getSleepTimer() > 0) {
            Profiler.get().push("sleep");
            graphics.nextStratum();
            float sleepTimer = this.minecraft.player.getSleepTimer();
            float amount = sleepTimer / 100.0F;
            if (amount > 1.0F) {
                amount = 1.0F - (sleepTimer - 100.0F) / 10.0F;
            }
 
            int color = (int)(220.0F * amount) << 24 | 1052704;
            graphics.fill(0, 0, graphics.guiWidth(), graphics.guiHeight(), color);
            Profiler.get().pop();
        }
    }
 
    private void extractOverlayMessage(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker) {
        Font font = this.getFont();
        if (this.overlayMessageString != null && this.overlayMessageTime > 0) {
            Profiler.get().push("overlayMessage");
            float t = this.overlayMessageTime - deltaTracker.getGameTimeDeltaPartialTick(false);
            int alpha = (int)(t * 255.0F / 20.0F);
            if (alpha > 255) {
                alpha = 255;
            }
 
            if (alpha > 0) {
                graphics.nextStratum();
                graphics.pose().pushMatrix();
                graphics.pose().translate(graphics.guiWidth() / 2, graphics.guiHeight() - 68);
                int color;
                if (this.animateOverlayMessageColor) {
                    color = Mth.hsvToArgb(t / 50.0F, 0.7F, 0.6F, alpha);
                } else {
                    color = ARGB.white(alpha);
                }
 
                int width = font.width(this.overlayMessageString);
                graphics.textWithBackdrop(font, this.overlayMessageString, -width / 2, -4, width, color);
                graphics.pose().popMatrix();
            }
 
            Profiler.get().pop();
        }
    }
 
    private void extractTitle(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker) {
        if (this.title != null && this.titleTime > 0) {
            Font font = this.getFont();
            Profiler.get().push("titleAndSubtitle");
            float t = this.titleTime - deltaTracker.getGameTimeDeltaPartialTick(false);
            int alpha = 255;
            if (this.titleTime > this.titleFadeOutTime + this.titleStayTime) {
                float time = this.titleFadeInTime + this.titleStayTime + this.titleFadeOutTime - t;
                alpha = (int)(time * 255.0F / this.titleFadeInTime);
            }
 
            if (this.titleTime <= this.titleFadeOutTime) {
                alpha = (int)(t * 255.0F / this.titleFadeOutTime);
            }
 
            alpha = Mth.clamp(alpha, 0, 255);
            if (alpha > 0) {
                graphics.nextStratum();
                graphics.pose().pushMatrix();
                graphics.pose().translate(graphics.guiWidth() / 2, graphics.guiHeight() / 2);
                graphics.pose().pushMatrix();
                graphics.pose().scale(4.0F, 4.0F);
                int titleWidth = font.width(this.title);
                int textColor = ARGB.white(alpha);
                graphics.textWithBackdrop(font, this.title, -titleWidth / 2, -10, titleWidth, textColor);
                graphics.pose().popMatrix();
                if (this.subtitle != null) {
                    graphics.pose().pushMatrix();
                    graphics.pose().scale(2.0F, 2.0F);
                    int subtitleWidth = font.width(this.subtitle);
                    graphics.textWithBackdrop(font, this.subtitle, -subtitleWidth / 2, 5, subtitleWidth, textColor);
                    graphics.pose().popMatrix();
                }
 
                graphics.pose().popMatrix();
            }
 
            Profiler.get().pop();
        }
    }
 
    private void extractChat(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker) {
        if (this.minecraft.player != null && !this.chat.isChatFocused()) {
            Window window = this.minecraft.getWindow();
            int mouseX = Mth.floor(this.minecraft.mouseHandler.getScaledXPos(window));
            int mouseY = Mth.floor(this.minecraft.mouseHandler.getScaledYPos(window));
            graphics.nextStratum();
            this.chat.extractRenderState(graphics, this.getFont(), this.tickCount, mouseX, mouseY, ChatComponent.DisplayMode.BACKGROUND, false);
        }
    }
 
    private void extractScoreboardSidebar(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker) {
        Scoreboard scoreboard = this.minecraft.level.getScoreboard();
        Objective teamObjective = null;
        PlayerTeam playerTeam = scoreboard.getPlayersTeam(this.minecraft.player.getScoreboardName());
        if (playerTeam != null) {
            DisplaySlot displaySlot = DisplaySlot.teamColorToSlot(playerTeam.getColor());
            if (displaySlot != null) {
                teamObjective = scoreboard.getDisplayObjective(displaySlot);
            }
        }
 
        Objective displayObjective = teamObjective != null ? teamObjective : scoreboard.getDisplayObjective(DisplaySlot.SIDEBAR);
        if (displayObjective != null) {
            graphics.nextStratum();
            this.displayScoreboardSidebar(graphics, displayObjective);
        }
    }
 
    private void extractTabList(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker) {
        Scoreboard scoreboard = this.minecraft.level.getScoreboard();
        Objective displayObjective = scoreboard.getDisplayObjective(DisplaySlot.LIST);
        if (!this.minecraft.options.keyPlayerList.isDown()
            || this.minecraft.isLocalServer() && this.minecraft.player.connection.getListedOnlinePlayers().size() <= 1 && displayObjective == null) {
            this.tabList.setVisible(false);
        } else {
            this.tabList.setVisible(true);
            graphics.nextStratum();
            this.tabList.extractRenderState(graphics, graphics.guiWidth(), scoreboard, displayObjective);
        }
    }
 
    private void extractCrosshair(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker) {
        Options options = this.minecraft.options;
        if (options.getCameraType().isFirstPerson()) {
            if (this.minecraft.gameMode.getPlayerMode() != GameType.SPECTATOR || this.canRenderCrosshairForSpectator(this.minecraft.hitResult)) {
                if (!this.minecraft.debugEntries.isCurrentlyEnabled(DebugScreenEntries.THREE_DIMENSIONAL_CROSSHAIR)) {
                    graphics.nextStratum();
                    int size = 15;
                    graphics.blitSprite(RenderPipelines.CROSSHAIR, CROSSHAIR_SPRITE, (graphics.guiWidth() - 15) / 2, (graphics.guiHeight() - 15) / 2, 15, 15);
                    if (this.minecraft.options.attackIndicator().get() == AttackIndicatorStatus.CROSSHAIR) {
                        float attackStrengthScale = this.minecraft.player.getAttackStrengthScale(0.0F);
                        boolean renderMaxAttackIndicator = false;
                        if (this.minecraft.crosshairPickEntity != null
                            && this.minecraft.crosshairPickEntity instanceof LivingEntity
                            && attackStrengthScale >= 1.0F) {
                            renderMaxAttackIndicator = this.minecraft.player.getCurrentItemAttackStrengthDelay() > 5.0F;
                            renderMaxAttackIndicator &= this.minecraft.crosshairPickEntity.isAlive();
                            AttackRange attackRange = this.minecraft.player.getActiveItem().get(DataComponents.ATTACK_RANGE);
                            renderMaxAttackIndicator &= attackRange == null
                                || attackRange.isInRange(this.minecraft.player, this.minecraft.hitResult.getLocation());
                        }
 
                        int y = graphics.guiHeight() / 2 - 7 + 16;
                        int x = graphics.guiWidth() / 2 - 8;
                        if (renderMaxAttackIndicator) {
                            graphics.blitSprite(RenderPipelines.CROSSHAIR, CROSSHAIR_ATTACK_INDICATOR_FULL_SPRITE, x, y, 16, 16);
                        } else if (attackStrengthScale < 1.0F) {
                            int progress = (int)(attackStrengthScale * 17.0F);
                            graphics.blitSprite(RenderPipelines.CROSSHAIR, CROSSHAIR_ATTACK_INDICATOR_BACKGROUND_SPRITE, x, y, 16, 4);
                            graphics.blitSprite(RenderPipelines.CROSSHAIR, CROSSHAIR_ATTACK_INDICATOR_PROGRESS_SPRITE, 16, 4, 0, 0, x, y, progress, 4);
                        }
                    }
                }
            }
        }
    }
 
    private boolean canRenderCrosshairForSpectator(@Nullable HitResult hitResult) {
        if (hitResult == null) {
            return false;
        } else if (hitResult.getType() == HitResult.Type.ENTITY) {
            return ((EntityHitResult)hitResult).getEntity() instanceof MenuProvider;
        } else if (hitResult.getType() == HitResult.Type.BLOCK) {
            BlockPos pos = ((BlockHitResult)hitResult).getBlockPos();
            Level level = this.minecraft.level;
            return level.getBlockState(pos).getMenuProvider(level, pos) != null;
        } else {
            return false;
        }
    }
 
    private void extractEffects(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker) {
        Collection<MobEffectInstance> activeEffects = this.minecraft.player.getActiveEffects();
        if (!activeEffects.isEmpty() && (this.minecraft.screen == null || !this.minecraft.screen.showsActiveEffects())) {
            int beneficialCount = 0;
            int harmfulCount = 0;
 
            for (MobEffectInstance instance : Ordering.natural().reverse().sortedCopy(activeEffects)) {
                Holder<MobEffect> effect = instance.getEffect();
                if (instance.showIcon()) {
                    int x = graphics.guiWidth();
                    int y = 1;
                    if (this.minecraft.isDemo()) {
                        y += 15;
                    }
 
                    if (effect.value().isBeneficial()) {
                        beneficialCount++;
                        x -= 25 * beneficialCount;
                    } else {
                        harmfulCount++;
                        x -= 25 * harmfulCount;
                        y += 26;
                    }
 
                    float alpha = 1.0F;
                    if (instance.isAmbient()) {
                        graphics.blitSprite(RenderPipelines.GUI_TEXTURED, EFFECT_BACKGROUND_AMBIENT_SPRITE, x, y, 24, 24);
                    } else {
                        graphics.blitSprite(RenderPipelines.GUI_TEXTURED, EFFECT_BACKGROUND_SPRITE, x, y, 24, 24);
                        if (instance.endsWithin(200)) {
                            int remainingDuration = instance.getDuration();
                            int usedSeconds = 10 - remainingDuration / 20;
                            alpha = Mth.clamp(remainingDuration / 10.0F / 5.0F * 0.5F, 0.0F, 0.5F)
                                + Mth.cos(remainingDuration * (float) Math.PI / 5.0F) * Mth.clamp(usedSeconds / 10.0F * 0.25F, 0.0F, 0.25F);
                            alpha = Mth.clamp(alpha, 0.0F, 1.0F);
                        }
                    }
 
                    graphics.blitSprite(RenderPipelines.GUI_TEXTURED, getMobEffectSprite(effect), x + 3, y + 3, 18, 18, ARGB.white(alpha));
                }
            }
        }
    }
 
    public static Identifier getMobEffectSprite(Holder<MobEffect> effect) {
        return effect.unwrapKey().map(ResourceKey::identifier).map(id -> id.withPrefix("mob_effect/")).orElseGet(MissingTextureAtlasSprite::getLocation);
    }
 
    private void extractHotbarAndDecorations(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker) {
        if (this.minecraft.gameMode.getPlayerMode() == GameType.SPECTATOR) {
            this.spectatorGui.extractHotbar(graphics);
        } else {
            this.extractItemHotbar(graphics, deltaTracker);
        }
 
        if (this.minecraft.gameMode.canHurtPlayer()) {
            this.extractPlayerHealth(graphics);
        }
 
        this.extractVehicleHealth(graphics);
        Gui.ContextualInfo nextContextualInfo = this.nextContextualInfoState();
        if (nextContextualInfo != this.contextualInfoBar.getKey()) {
            this.contextualInfoBar = Pair.of(nextContextualInfo, this.contextualInfoBarRenderers.get(nextContextualInfo).get());
        }
 
        this.contextualInfoBar.getValue().extractBackground(graphics, deltaTracker);
        if (this.minecraft.gameMode.hasExperience() && this.minecraft.player.experienceLevel > 0) {
            ContextualBarRenderer.extractExperienceLevel(graphics, this.minecraft.font, this.minecraft.player.experienceLevel);
        }
 
        this.contextualInfoBar.getValue().extractRenderState(graphics, deltaTracker);
        if (this.minecraft.gameMode.getPlayerMode() != GameType.SPECTATOR) {
            this.extractSelectedItemName(graphics);
        } else if (this.minecraft.player.isSpectator()) {
            this.spectatorGui.extractAction(graphics);
        }
    }
 
    private void extractItemHotbar(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker) {
        Player player = this.getCameraPlayer();
        if (player != null) {
            ItemStack offhand = player.getOffhandItem();
            HumanoidArm offhandArm = player.getMainArm().getOpposite();
            int screenCenter = graphics.guiWidth() / 2;
            int hotbarWidth = 182;
            int halfHotbar = 91;
            graphics.blitSprite(RenderPipelines.GUI_TEXTURED, HOTBAR_SPRITE, screenCenter - 91, graphics.guiHeight() - 22, 182, 22);
            graphics.blitSprite(
                RenderPipelines.GUI_TEXTURED,
                HOTBAR_SELECTION_SPRITE,
                screenCenter - 91 - 1 + player.getInventory().getSelectedSlot() * 20,
                graphics.guiHeight() - 22 - 1,
                24,
                23
            );
            if (!offhand.isEmpty()) {
                if (offhandArm == HumanoidArm.LEFT) {
                    graphics.blitSprite(RenderPipelines.GUI_TEXTURED, HOTBAR_OFFHAND_LEFT_SPRITE, screenCenter - 91 - 29, graphics.guiHeight() - 23, 29, 24);
                } else {
                    graphics.blitSprite(RenderPipelines.GUI_TEXTURED, HOTBAR_OFFHAND_RIGHT_SPRITE, screenCenter + 91, graphics.guiHeight() - 23, 29, 24);
                }
            }
 
            int seed = 1;
 
            for (int i = 0; i < 9; i++) {
                int x = screenCenter - 90 + i * 20 + 2;
                int y = graphics.guiHeight() - 16 - 3;
                this.extractSlot(graphics, x, y, deltaTracker, player, player.getInventory().getItem(i), seed++);
            }
 
            if (!offhand.isEmpty()) {
                int y = graphics.guiHeight() - 16 - 3;
                if (offhandArm == HumanoidArm.LEFT) {
                    this.extractSlot(graphics, screenCenter - 91 - 26, y, deltaTracker, player, offhand, seed++);
                } else {
                    this.extractSlot(graphics, screenCenter + 91 + 10, y, deltaTracker, player, offhand, seed++);
                }
            }
 
            if (this.minecraft.options.attackIndicator().get() == AttackIndicatorStatus.HOTBAR) {
                float attackStrengthScale = this.minecraft.player.getAttackStrengthScale(0.0F);
                if (attackStrengthScale < 1.0F) {
                    int y = graphics.guiHeight() - 20;
                    int x = screenCenter + 91 + 6;
                    if (offhandArm == HumanoidArm.RIGHT) {
                        x = screenCenter - 91 - 22;
                    }
 
                    int progress = (int)(attackStrengthScale * 19.0F);
                    graphics.blitSprite(RenderPipelines.GUI_TEXTURED, HOTBAR_ATTACK_INDICATOR_BACKGROUND_SPRITE, x, y, 18, 18);
                    graphics.blitSprite(
                        RenderPipelines.GUI_TEXTURED, HOTBAR_ATTACK_INDICATOR_PROGRESS_SPRITE, 18, 18, 0, 18 - progress, x, y + 18 - progress, 18, progress
                    );
                }
            }
        }
    }
 
    private void extractSelectedItemName(GuiGraphicsExtractor graphics) {
        if (this.toolHighlightTimer > 0 && !this.lastToolHighlight.isEmpty()) {
            MutableComponent str = Component.empty().append(this.lastToolHighlight.getHoverName()).withStyle(this.lastToolHighlight.getRarity().color());
            if (this.lastToolHighlight.has(DataComponents.CUSTOM_NAME)) {
                str.withStyle(ChatFormatting.ITALIC);
            }
 
            int strWidth = this.getFont().width(str);
            int x = (graphics.guiWidth() - strWidth) / 2;
            int y = graphics.guiHeight() - 59;
            if (!this.minecraft.gameMode.canHurtPlayer()) {
                y += 14;
            }
 
            int alpha = (int)(this.toolHighlightTimer * 256.0F / 10.0F);
            if (alpha > 255) {
                alpha = 255;
            }
 
            if (alpha > 0) {
                graphics.textWithBackdrop(this.getFont(), str, x, y, strWidth, ARGB.white(alpha));
            }
        }
    }
 
    private void extractDemoOverlay(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker) {
        if (this.minecraft.isDemo()) {
            Profiler.get().push("demo");
            graphics.nextStratum();
            Component msg;
            if (this.minecraft.level.getGameTime() >= 120500L) {
                msg = DEMO_EXPIRED_TEXT;
            } else {
                msg = Component.translatable(
                    "demo.remainingTime",
                    StringUtil.formatTickDuration((int)(120500L - this.minecraft.level.getGameTime()), this.minecraft.level.tickRateManager().tickrate())
                );
            }
 
            int width = this.getFont().width(msg);
            int textX = graphics.guiWidth() - width - 10;
            int textY = 5;
            graphics.textWithBackdrop(this.getFont(), msg, textX, 5, width, -1);
            Profiler.get().pop();
        }
    }
 
    private void displayScoreboardSidebar(GuiGraphicsExtractor graphics, Objective objective) {
        Scoreboard scoreboard = objective.getScoreboard();
        NumberFormat objectiveScoreFormat = objective.numberFormatOrDefault(StyledFormat.SIDEBAR_DEFAULT);
 
        @OnlyIn(Dist.CLIENT)
        record DisplayEntry(Component name, Component score, int scoreWidth) {
        }
 
        DisplayEntry[] entriesToDisplay = scoreboard.listPlayerScores(objective)
            .stream()
            .filter(input -> !input.isHidden())
            .sorted(SCORE_DISPLAY_ORDER)
            .limit(15L)
            .map(score -> {
                PlayerTeam team = scoreboard.getPlayersTeam(score.owner());
                Component ownerName = score.ownerName();
                Component name = PlayerTeam.formatNameForTeam(team, ownerName);
                Component scoreString = score.formatValue(objectiveScoreFormat);
                int scoreWidth = this.getFont().width(scoreString);
                return new DisplayEntry(name, scoreString, scoreWidth);
            })
            .toArray(DisplayEntry[]::new);
        Component objectiveDisplayName = objective.getDisplayName();
        int objectiveDisplayNameWidth = this.getFont().width(objectiveDisplayName);
        int biggestWidth = objectiveDisplayNameWidth;
        int spacerWidth = this.getFont().width(": ");
 
        for (DisplayEntry entry : entriesToDisplay) {
            biggestWidth = Math.max(biggestWidth, this.getFont().width(entry.name) + (entry.scoreWidth > 0 ? spacerWidth + entry.scoreWidth : 0));
        }
 
        int entriesCount = entriesToDisplay.length;
        int height = entriesCount * 9;
        int bottom = graphics.guiHeight() / 2 + height / 3;
        int rightPadding = 3;
        int left = graphics.guiWidth() - biggestWidth - 3;
        int right = graphics.guiWidth() - 3 + 2;
        int backgroundColor = this.minecraft.options.getBackgroundColor(0.3F);
        int headerBackgroundColor = this.minecraft.options.getBackgroundColor(0.4F);
        int headerY = bottom - entriesCount * 9;
        graphics.fill(left - 2, headerY - 9 - 1, right, headerY - 1, headerBackgroundColor);
        graphics.fill(left - 2, headerY - 1, right, bottom, backgroundColor);
        graphics.text(this.getFont(), objectiveDisplayName, left + biggestWidth / 2 - objectiveDisplayNameWidth / 2, headerY - 9, -1, false);
 
        for (int i = 0; i < entriesCount; i++) {
            DisplayEntry e = entriesToDisplay[i];
            int y = bottom - (entriesCount - i) * 9;
            graphics.text(this.getFont(), e.name, left, y, -1, false);
            graphics.text(this.getFont(), e.score, right - e.scoreWidth, y, -1, false);
        }
    }
 
    private @Nullable Player getCameraPlayer() {
        return this.minecraft.getCameraEntity() instanceof Player player ? player : null;
    }
 
    private @Nullable LivingEntity getPlayerVehicleWithHealth() {
        Player player = this.getCameraPlayer();
        if (player != null) {
            Entity vehicle = player.getVehicle();
            if (vehicle == null) {
                return null;
            }
 
            if (vehicle instanceof LivingEntity) {
                return (LivingEntity)vehicle;
            }
        }
 
        return null;
    }
 
    private int getVehicleMaxHearts(@Nullable LivingEntity vehicle) {
        if (vehicle != null && vehicle.showVehicleHealth()) {
            float maxVehicleHealth = vehicle.getMaxHealth();
            int hearts = (int)(maxVehicleHealth + 0.5F) / 2;
            if (hearts > 30) {
                hearts = 30;
            }
 
            return hearts;
        } else {
            return 0;
        }
    }
 
    private int getVisibleVehicleHeartRows(int hearts) {
        return (int)Math.ceil(hearts / 10.0);
    }
 
    private void extractPlayerHealth(GuiGraphicsExtractor graphics) {
        Player player = this.getCameraPlayer();
        if (player != null) {
            int currentHealth = Mth.ceil(player.getHealth());
            boolean blink = this.healthBlinkTime > this.tickCount && (this.healthBlinkTime - this.tickCount) / 3L % 2L == 1L;
            long timeMillis = Util.getMillis();
            if (currentHealth < this.lastHealth && player.invulnerableTime > 0) {
                this.lastHealthTime = timeMillis;
                this.healthBlinkTime = this.tickCount + 20;
            } else if (currentHealth > this.lastHealth && player.invulnerableTime > 0) {
                this.lastHealthTime = timeMillis;
                this.healthBlinkTime = this.tickCount + 10;
            }
 
            if (timeMillis - this.lastHealthTime > 1000L) {
                this.displayHealth = currentHealth;
                this.lastHealthTime = timeMillis;
            }
 
            this.lastHealth = currentHealth;
            int oldHealth = this.displayHealth;
            this.random.setSeed(this.tickCount * 312871);
            int xLeft = graphics.guiWidth() / 2 - 91;
            int xRight = graphics.guiWidth() / 2 + 91;
            int yLineBase = graphics.guiHeight() - 39;
            float maxHealth = Math.max((float)player.getAttributeValue(Attributes.MAX_HEALTH), (float)Math.max(oldHealth, currentHealth));
            int totalAbsorption = Mth.ceil(player.getAbsorptionAmount());
            int numHealthRows = Mth.ceil((maxHealth + totalAbsorption) / 2.0F / 10.0F);
            int healthRowHeight = Math.max(10 - (numHealthRows - 2), 3);
            int yLineAir = yLineBase - 10;
            int heartOffsetIndex = -1;
            if (player.hasEffect(MobEffects.REGENERATION)) {
                heartOffsetIndex = this.tickCount % Mth.ceil(maxHealth + 5.0F);
            }
 
            Profiler.get().push("armor");
            extractArmor(graphics, player, yLineBase, numHealthRows, healthRowHeight, xLeft);
            Profiler.get().popPush("health");
            this.extractHearts(
                graphics, player, xLeft, yLineBase, healthRowHeight, heartOffsetIndex, maxHealth, currentHealth, oldHealth, totalAbsorption, blink
            );
            LivingEntity vehicleWithHearts = this.getPlayerVehicleWithHealth();
            int vehicleHearts = this.getVehicleMaxHearts(vehicleWithHearts);
            if (vehicleHearts == 0) {
                Profiler.get().popPush("food");
                this.extractFood(graphics, player, yLineBase, xRight);
                yLineAir -= 10;
            }
 
            Profiler.get().popPush("air");
            this.extractAirBubbles(graphics, player, vehicleHearts, yLineAir, xRight);
            Profiler.get().pop();
        }
    }
 
    private static void extractArmor(GuiGraphicsExtractor graphics, Player player, int yLineBase, int numHealthRows, int healthRowHeight, int xLeft) {
        int armor = player.getArmorValue();
        if (armor > 0) {
            int yLineArmor = yLineBase - (numHealthRows - 1) * healthRowHeight - 10;
 
            for (int i = 0; i < 10; i++) {
                int xo = xLeft + i * 8;
                if (i * 2 + 1 < armor) {
                    graphics.blitSprite(RenderPipelines.GUI_TEXTURED, ARMOR_FULL_SPRITE, xo, yLineArmor, 9, 9);
                }
 
                if (i * 2 + 1 == armor) {
                    graphics.blitSprite(RenderPipelines.GUI_TEXTURED, ARMOR_HALF_SPRITE, xo, yLineArmor, 9, 9);
                }
 
                if (i * 2 + 1 > armor) {
                    graphics.blitSprite(RenderPipelines.GUI_TEXTURED, ARMOR_EMPTY_SPRITE, xo, yLineArmor, 9, 9);
                }
            }
        }
    }
 
    private void extractHearts(
        GuiGraphicsExtractor graphics,
        Player player,
        int xLeft,
        int yLineBase,
        int healthRowHeight,
        int heartOffsetIndex,
        float maxHealth,
        int currentHealth,
        int oldHealth,
        int absorption,
        boolean blink
    ) {
        Gui.HeartType type = Gui.HeartType.forPlayer(player);
        boolean isHardcore = player.level().getLevelData().isHardcore();
        int healthContainerCount = Mth.ceil(maxHealth / 2.0);
        int absorptionContainerCount = Mth.ceil(absorption / 2.0);
        int maxHealthHalvesCount = healthContainerCount * 2;
 
        for (int containerIndex = healthContainerCount + absorptionContainerCount - 1; containerIndex >= 0; containerIndex--) {
            int row = containerIndex / 10;
            int column = containerIndex % 10;
            int xo = xLeft + column * 8;
            int yo = yLineBase - row * healthRowHeight;
            if (currentHealth + absorption <= 4) {
                yo += this.random.nextInt(2);
            }
 
            if (containerIndex < healthContainerCount && containerIndex == heartOffsetIndex) {
                yo -= 2;
            }
 
            this.extractHeart(graphics, Gui.HeartType.CONTAINER, xo, yo, isHardcore, blink, false);
            int halves = containerIndex * 2;
            boolean isAbsorptionHeart = containerIndex >= healthContainerCount;
            if (isAbsorptionHeart) {
                int absorptionHalves = halves - maxHealthHalvesCount;
                if (absorptionHalves < absorption) {
                    boolean halfHeart = absorptionHalves + 1 == absorption;
                    this.extractHeart(graphics, type == Gui.HeartType.WITHERED ? type : Gui.HeartType.ABSORBING, xo, yo, isHardcore, false, halfHeart);
                }
            }
 
            if (blink && halves < oldHealth) {
                boolean halfHeart = halves + 1 == oldHealth;
                this.extractHeart(graphics, type, xo, yo, isHardcore, true, halfHeart);
            }
 
            if (halves < currentHealth) {
                boolean halfHeart = halves + 1 == currentHealth;
                this.extractHeart(graphics, type, xo, yo, isHardcore, false, halfHeart);
            }
        }
    }
 
    private void extractHeart(GuiGraphicsExtractor graphics, Gui.HeartType type, int xo, int yo, boolean isHardcore, boolean blinks, boolean half) {
        graphics.blitSprite(RenderPipelines.GUI_TEXTURED, type.getSprite(isHardcore, half, blinks), xo, yo, 9, 9);
    }
 
    private void extractAirBubbles(GuiGraphicsExtractor graphics, Player player, int vehicleHearts, int yLineAir, int xRight) {
        int maxAirSupplyTicks = player.getMaxAirSupply();
        int currentAirSupplyTicks = Math.clamp((long)player.getAirSupply(), 0, maxAirSupplyTicks);
        boolean isUnderWater = player.isEyeInFluid(FluidTags.WATER);
        if (isUnderWater || currentAirSupplyTicks < maxAirSupplyTicks) {
            yLineAir = this.getAirBubbleYLine(vehicleHearts, yLineAir);
            int fullAirBubbles = getCurrentAirSupplyBubble(currentAirSupplyTicks, maxAirSupplyTicks, -2);
            int poppingAirBubblePosition = getCurrentAirSupplyBubble(currentAirSupplyTicks, maxAirSupplyTicks, 0);
            int emptyAirBubbles = 10
                - getCurrentAirSupplyBubble(currentAirSupplyTicks, maxAirSupplyTicks, getEmptyBubbleDelayDuration(currentAirSupplyTicks, isUnderWater));
            boolean isPoppingBubble = fullAirBubbles != poppingAirBubblePosition;
            if (!isUnderWater) {
                this.lastBubblePopSoundPlayed = 0;
            }
 
            for (int airBubble = 1; airBubble <= 10; airBubble++) {
                int airBubbleXPos = xRight - (airBubble - 1) * 8 - 9;
                if (airBubble <= fullAirBubbles) {
                    graphics.blitSprite(RenderPipelines.GUI_TEXTURED, AIR_SPRITE, airBubbleXPos, yLineAir, 9, 9);
                } else if (isPoppingBubble && airBubble == poppingAirBubblePosition && isUnderWater) {
                    graphics.blitSprite(RenderPipelines.GUI_TEXTURED, AIR_POPPING_SPRITE, airBubbleXPos, yLineAir, 9, 9);
                    this.playAirBubblePoppedSound(airBubble, player, emptyAirBubbles);
                } else if (airBubble > 10 - emptyAirBubbles) {
                    int wobbleYOffset = emptyAirBubbles == 10 && this.tickCount % 2 == 0 ? this.random.nextInt(2) : 0;
                    graphics.blitSprite(RenderPipelines.GUI_TEXTURED, AIR_EMPTY_SPRITE, airBubbleXPos, yLineAir + wobbleYOffset, 9, 9);
                }
            }
        }
    }
 
    private int getAirBubbleYLine(int vehicleHearts, int yLineAir) {
        int rowOffset = this.getVisibleVehicleHeartRows(vehicleHearts) - 1;
        return yLineAir - rowOffset * 10;
    }
 
    private static int getCurrentAirSupplyBubble(int currentAirSupplyTicks, int maxAirSupplyTicks, int tickOffset) {
        return Mth.ceil((float)((currentAirSupplyTicks + tickOffset) * 10) / maxAirSupplyTicks);
    }
 
    private static int getEmptyBubbleDelayDuration(int currentAirSupplyTicks, boolean isUnderWater) {
        return currentAirSupplyTicks != 0 && isUnderWater ? 1 : 0;
    }
 
    private void playAirBubblePoppedSound(int bubble, Player player, int emptyAirBubbles) {
        if (this.lastBubblePopSoundPlayed != bubble) {
            float soundVolume = 0.5F + 0.1F * Math.max(0, emptyAirBubbles - 3 + 1);
            float soundPitch = 1.0F + 0.1F * Math.max(0, emptyAirBubbles - 5 + 1);
            player.playSound(SoundEvents.BUBBLE_POP, soundVolume, soundPitch);
            this.lastBubblePopSoundPlayed = bubble;
        }
    }
 
    private void extractFood(GuiGraphicsExtractor graphics, Player player, int yLineBase, int xRight) {
        FoodData foodData = player.getFoodData();
        int food = foodData.getFoodLevel();
 
        for (int i = 0; i < 10; i++) {
            int yo = yLineBase;
            Identifier empty;
            Identifier half;
            Identifier full;
            if (player.hasEffect(MobEffects.HUNGER)) {
                empty = FOOD_EMPTY_HUNGER_SPRITE;
                half = FOOD_HALF_HUNGER_SPRITE;
                full = FOOD_FULL_HUNGER_SPRITE;
            } else {
                empty = FOOD_EMPTY_SPRITE;
                half = FOOD_HALF_SPRITE;
                full = FOOD_FULL_SPRITE;
            }
 
            if (player.getFoodData().getSaturationLevel() <= 0.0F && this.tickCount % (food * 3 + 1) == 0) {
                yo = yLineBase + (this.random.nextInt(3) - 1);
            }
 
            int xo = xRight - i * 8 - 9;
            graphics.blitSprite(RenderPipelines.GUI_TEXTURED, empty, xo, yo, 9, 9);
            if (i * 2 + 1 < food) {
                graphics.blitSprite(RenderPipelines.GUI_TEXTURED, full, xo, yo, 9, 9);
            }
 
            if (i * 2 + 1 == food) {
                graphics.blitSprite(RenderPipelines.GUI_TEXTURED, half, xo, yo, 9, 9);
            }
        }
    }
 
    private void extractVehicleHealth(GuiGraphicsExtractor graphics) {
        LivingEntity vehicleWithHearts = this.getPlayerVehicleWithHealth();
        if (vehicleWithHearts != null) {
            int hearts = this.getVehicleMaxHearts(vehicleWithHearts);
            if (hearts != 0) {
                int currentHealth = (int)Math.ceil(vehicleWithHearts.getHealth());
                Profiler.get().popPush("mountHealth");
                int yLine1 = graphics.guiHeight() - 39;
                int xRight = graphics.guiWidth() / 2 + 91;
                int yo = yLine1;
 
                for (int baseHealth = 0; hearts > 0; baseHealth += 20) {
                    int rowHearts = Math.min(hearts, 10);
                    hearts -= rowHearts;
 
                    for (int i = 0; i < rowHearts; i++) {
                        int xo = xRight - i * 8 - 9;
                        graphics.blitSprite(RenderPipelines.GUI_TEXTURED, HEART_VEHICLE_CONTAINER_SPRITE, xo, yo, 9, 9);
                        if (i * 2 + 1 + baseHealth < currentHealth) {
                            graphics.blitSprite(RenderPipelines.GUI_TEXTURED, HEART_VEHICLE_FULL_SPRITE, xo, yo, 9, 9);
                        }
 
                        if (i * 2 + 1 + baseHealth == currentHealth) {
                            graphics.blitSprite(RenderPipelines.GUI_TEXTURED, HEART_VEHICLE_HALF_SPRITE, xo, yo, 9, 9);
                        }
                    }
 
                    yo -= 10;
                }
            }
        }
    }
 
    private void extractTextureOverlay(GuiGraphicsExtractor graphics, Identifier texture, float alpha) {
        int color = ARGB.white(alpha);
        graphics.blit(
            RenderPipelines.GUI_TEXTURED,
            texture,
            0,
            0,
            0.0F,
            0.0F,
            graphics.guiWidth(),
            graphics.guiHeight(),
            graphics.guiWidth(),
            graphics.guiHeight(),
            color
        );
    }
 
    private void extractSpyglassOverlay(GuiGraphicsExtractor graphics, float scale) {
        float srcWidth = Math.min(graphics.guiWidth(), graphics.guiHeight());
        float ratio = Math.min(graphics.guiWidth() / srcWidth, graphics.guiHeight() / srcWidth) * scale;
        int width = Mth.floor(srcWidth * ratio);
        int height = Mth.floor(srcWidth * ratio);
        int left = (graphics.guiWidth() - width) / 2;
        int top = (graphics.guiHeight() - height) / 2;
        int right = left + width;
        int bottom = top + height;
        graphics.blit(RenderPipelines.GUI_TEXTURED, SPYGLASS_SCOPE_LOCATION, left, top, 0.0F, 0.0F, width, height, width, height);
        graphics.fill(RenderPipelines.GUI, 0, bottom, graphics.guiWidth(), graphics.guiHeight(), -16777216);
        graphics.fill(RenderPipelines.GUI, 0, 0, graphics.guiWidth(), top, -16777216);
        graphics.fill(RenderPipelines.GUI, 0, top, left, bottom, -16777216);
        graphics.fill(RenderPipelines.GUI, right, top, graphics.guiWidth(), bottom, -16777216);
    }
 
    private void updateVignetteBrightness(Entity camera) {
        BlockPos blockPos = BlockPos.containing(camera.getX(), camera.getEyeY(), camera.getZ());
        float levelBrightness = Lightmap.getBrightness(camera.level().dimensionType(), camera.level().getMaxLocalRawBrightness(blockPos));
        float brightness = Mth.clamp(1.0F - levelBrightness, 0.0F, 1.0F);
        this.vignetteBrightness = this.vignetteBrightness + (brightness - this.vignetteBrightness) * 0.01F;
    }
 
    private void extractVignette(GuiGraphicsExtractor graphics, @Nullable Entity camera) {
        WorldBorder worldBorder = this.minecraft.level.getWorldBorder();
        float borderWarningStrength = 0.0F;
        if (camera != null) {
            float distToBorder = (float)worldBorder.getDistanceToBorder(camera);
            double movingBlocksThreshold = Math.min(
                worldBorder.getLerpSpeed() * worldBorder.getWarningTime(), Math.abs(worldBorder.getLerpTarget() - worldBorder.getSize())
            );
            double warningDistance = Math.max((double)worldBorder.getWarningBlocks(), movingBlocksThreshold);
            if (distToBorder < warningDistance) {
                borderWarningStrength = 1.0F - (float)(distToBorder / warningDistance);
            }
        }
 
        float brightness = Mth.clamp(this.vignetteBrightness, 0.0F, 1.0F);
        int color;
        if (borderWarningStrength > 0.0F) {
            borderWarningStrength = Mth.clamp(borderWarningStrength, 0.0F, 1.0F);
            float red = brightness * (1.0F - borderWarningStrength);
            float greenBlue = brightness + (1.0F - brightness) * borderWarningStrength;
            color = ARGB.colorFromFloat(1.0F, red, greenBlue, greenBlue);
        } else {
            color = ARGB.colorFromFloat(1.0F, brightness, brightness, brightness);
        }
 
        graphics.blit(
            RenderPipelines.VIGNETTE,
            VIGNETTE_LOCATION,
            0,
            0,
            0.0F,
            0.0F,
            graphics.guiWidth(),
            graphics.guiHeight(),
            graphics.guiWidth(),
            graphics.guiHeight(),
            color
        );
    }
 
    private void extractPortalOverlay(GuiGraphicsExtractor graphics, float alpha) {
        if (alpha < 1.0F) {
            alpha *= alpha;
            alpha *= alpha;
            alpha = alpha * 0.8F + 0.2F;
        }
 
        int color = ARGB.white(alpha);
        TextureAtlasSprite slot = this.minecraft
            .getModelManager()
            .getBlockStateModelSet()
            .getParticleMaterial(Blocks.NETHER_PORTAL.defaultBlockState())
            .sprite();
        graphics.blitSprite(RenderPipelines.GUI_TEXTURED, slot, 0, 0, graphics.guiWidth(), graphics.guiHeight(), color);
    }
 
    private void extractConfusionOverlay(GuiGraphicsExtractor graphics, float strength) {
        int screenWidth = graphics.guiWidth();
        int screenHeight = graphics.guiHeight();
        graphics.pose().pushMatrix();
        float size = Mth.lerp(strength, 2.0F, 1.0F);
        graphics.pose().translate(screenWidth / 2.0F, screenHeight / 2.0F);
        graphics.pose().scale(size, size);
        graphics.pose().translate(-screenWidth / 2.0F, -screenHeight / 2.0F);
        float red = 0.2F * strength;
        float green = 0.4F * strength;
        float blue = 0.2F * strength;
        graphics.blit(
            RenderPipelines.GUI_NAUSEA_OVERLAY,
            NAUSEA_LOCATION,
            0,
            0,
            0.0F,
            0.0F,
            screenWidth,
            screenHeight,
            screenWidth,
            screenHeight,
            ARGB.colorFromFloat(1.0F, red, green, blue)
        );
        graphics.pose().popMatrix();
    }
 
    private void extractSlot(GuiGraphicsExtractor graphics, int x, int y, DeltaTracker deltaTracker, Player player, ItemStack itemStack, int seed) {
        if (!itemStack.isEmpty()) {
            float pop = itemStack.getPopTime() - deltaTracker.getGameTimeDeltaPartialTick(false);
            if (pop > 0.0F) {
                float squeeze = 1.0F + pop / 5.0F;
                graphics.pose().pushMatrix();
                graphics.pose().translate(x + 8, y + 12);
                graphics.pose().scale(1.0F / squeeze, (squeeze + 1.0F) / 2.0F);
                graphics.pose().translate(-(x + 8), -(y + 12));
            }
 
            graphics.item(player, itemStack, x, y, seed);
            if (pop > 0.0F) {
                graphics.pose().popMatrix();
            }
 
            graphics.itemDecorations(this.minecraft.font, itemStack, x, y);
        }
    }
 
    public void tick(boolean pause) {
        this.tickAutosaveIndicator();
        if (!pause) {
            this.tick();
        }
    }
 
    private void tick() {
        if (this.overlayMessageTime > 0) {
            this.overlayMessageTime--;
        }
 
        if (this.titleTime > 0) {
            this.titleTime--;
            if (this.titleTime <= 0) {
                this.title = null;
                this.subtitle = null;
            }
        }
 
        this.tickCount++;
        Entity camera = this.minecraft.getCameraEntity();
        if (camera != null) {
            this.updateVignetteBrightness(camera);
        }
 
        if (this.minecraft.player != null) {
            ItemStack selected = this.minecraft.player.getInventory().getSelectedItem();
            if (selected.isEmpty()) {
                this.toolHighlightTimer = 0;
            } else if (this.lastToolHighlight.isEmpty()
                || !selected.is(this.lastToolHighlight.getItem())
                || !selected.getHoverName().equals(this.lastToolHighlight.getHoverName())) {
                this.toolHighlightTimer = (int)(40.0 * this.minecraft.options.notificationDisplayTime().get());
            } else if (this.toolHighlightTimer > 0) {
                this.toolHighlightTimer--;
            }
 
            this.lastToolHighlight = selected;
        }
 
        this.chat.tick();
    }
 
    private void tickAutosaveIndicator() {
        MinecraftServer server = this.minecraft.getSingleplayerServer();
        boolean isAutosaving = server != null && server.isCurrentlySaving();
        this.lastAutosaveIndicatorValue = this.autosaveIndicatorValue;
        this.autosaveIndicatorValue = Mth.lerp(0.2F, this.autosaveIndicatorValue, isAutosaving ? 1.0F : 0.0F);
    }
 
    public void setNowPlaying(Component string) {
        Component message = Component.translatable("record.nowPlaying", string);
        this.setOverlayMessage(message, true);
        this.minecraft.getNarrator().saySystemNow(message);
    }
 
    public void setOverlayMessage(Component string, boolean animate) {
        this.overlayMessageString = string;
        this.overlayMessageTime = 60;
        this.animateOverlayMessageColor = animate;
    }
 
    public void setTimes(int fadeInTime, int stayTime, int fadeOutTime) {
        if (fadeInTime >= 0) {
            this.titleFadeInTime = fadeInTime;
        }
 
        if (stayTime >= 0) {
            this.titleStayTime = stayTime;
        }
 
        if (fadeOutTime >= 0) {
            this.titleFadeOutTime = fadeOutTime;
        }
 
        if (this.titleTime > 0) {
            this.titleTime = this.titleFadeInTime + this.titleStayTime + this.titleFadeOutTime;
        }
    }
 
    public void setSubtitle(Component subtitle) {
        this.subtitle = subtitle;
    }
 
    public void setTitle(Component title) {
        this.title = title;
        this.titleTime = this.titleFadeInTime + this.titleStayTime + this.titleFadeOutTime;
    }
 
    public void clearTitles() {
        this.title = null;
        this.subtitle = null;
        this.titleTime = 0;
    }
 
    public ChatComponent getChat() {
        return this.chat;
    }
 
    public int getGuiTicks() {
        return this.tickCount;
    }
 
    public Font getFont() {
        return this.minecraft.font;
    }
 
    public SpectatorGui getSpectatorGui() {
        return this.spectatorGui;
    }
 
    public PlayerTabOverlay getTabList() {
        return this.tabList;
    }
 
    public void onDisconnected() {
        this.tabList.reset();
        this.bossOverlay.reset();
        this.minecraft.getToastManager().clear();
        this.debugOverlay.reset();
        this.chat.clearMessages(true);
        this.clearTitles();
        this.resetTitleTimes();
    }
 
    public BossHealthOverlay getBossOverlay() {
        return this.bossOverlay;
    }
 
    public DebugScreenOverlay getDebugOverlay() {
        return this.debugOverlay;
    }
 
    public void clearCache() {
        this.debugOverlay.clearChunkCache();
    }
 
    public void extractSavingIndicator(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker) {
        if (this.minecraft.options.showAutosaveIndicator().get() && (this.autosaveIndicatorValue > 0.0F || this.lastAutosaveIndicatorValue > 0.0F)) {
            int alpha = Mth.floor(
                255.0F * Mth.clamp(Mth.lerp(deltaTracker.getRealtimeDeltaTicks(), this.lastAutosaveIndicatorValue, this.autosaveIndicatorValue), 0.0F, 1.0F)
            );
            if (alpha > 0) {
                Font font = this.getFont();
                int width = font.width(SAVING_TEXT);
                int color = ARGB.color(alpha, -1);
                int textX = graphics.guiWidth() - width - 5;
                int textY = graphics.guiHeight() - 9 - 5;
                graphics.nextStratum();
                graphics.textWithBackdrop(font, SAVING_TEXT, textX, textY, width, color);
            }
        }
    }
 
    private boolean willPrioritizeExperienceInfo() {
        return this.minecraft.player.experienceDisplayStartTick + 100 > this.minecraft.player.tickCount;
    }
 
    private boolean willPrioritizeJumpInfo() {
        return this.minecraft.player.getJumpRidingScale() > 0.0F
            || Optionull.mapOrDefault(this.minecraft.player.jumpableVehicle(), PlayerRideableJumping::getJumpCooldown, 0) > 0;
    }
 
    private Gui.ContextualInfo nextContextualInfoState() {
        boolean canShowLocatorInfo = this.minecraft.player.connection.getWaypointManager().hasWaypoints();
        boolean canShowVehicleJumpInfo = this.minecraft.player.jumpableVehicle() != null;
        boolean canShowExperienceInfo = this.minecraft.gameMode.hasExperience();
        if (canShowLocatorInfo) {
            if (canShowVehicleJumpInfo && this.willPrioritizeJumpInfo()) {
                return Gui.ContextualInfo.JUMPABLE_VEHICLE;
            } else {
                return canShowExperienceInfo && this.willPrioritizeExperienceInfo() ? Gui.ContextualInfo.EXPERIENCE : Gui.ContextualInfo.LOCATOR;
            }
        } else if (canShowVehicleJumpInfo) {
            return Gui.ContextualInfo.JUMPABLE_VEHICLE;
        } else {
            return canShowExperienceInfo ? Gui.ContextualInfo.EXPERIENCE : Gui.ContextualInfo.EMPTY;
        }
    }
 
    @OnlyIn(Dist.CLIENT)
    static enum ContextualInfo {
        EMPTY,
        EXPERIENCE,
        LOCATOR,
        JUMPABLE_VEHICLE;
    }
 
    @OnlyIn(Dist.CLIENT)
    private static enum HeartType {
        CONTAINER(
            Identifier.withDefaultNamespace("hud/heart/container"),
            Identifier.withDefaultNamespace("hud/heart/container_blinking"),
            Identifier.withDefaultNamespace("hud/heart/container"),
            Identifier.withDefaultNamespace("hud/heart/container_blinking"),
            Identifier.withDefaultNamespace("hud/heart/container_hardcore"),
            Identifier.withDefaultNamespace("hud/heart/container_hardcore_blinking"),
            Identifier.withDefaultNamespace("hud/heart/container_hardcore"),
            Identifier.withDefaultNamespace("hud/heart/container_hardcore_blinking")
        ),
        NORMAL(
            Identifier.withDefaultNamespace("hud/heart/full"),
            Identifier.withDefaultNamespace("hud/heart/full_blinking"),
            Identifier.withDefaultNamespace("hud/heart/half"),
            Identifier.withDefaultNamespace("hud/heart/half_blinking"),
            Identifier.withDefaultNamespace("hud/heart/hardcore_full"),
            Identifier.withDefaultNamespace("hud/heart/hardcore_full_blinking"),
            Identifier.withDefaultNamespace("hud/heart/hardcore_half"),
            Identifier.withDefaultNamespace("hud/heart/hardcore_half_blinking")
        ),
        POISIONED(
            Identifier.withDefaultNamespace("hud/heart/poisoned_full"),
            Identifier.withDefaultNamespace("hud/heart/poisoned_full_blinking"),
            Identifier.withDefaultNamespace("hud/heart/poisoned_half"),
            Identifier.withDefaultNamespace("hud/heart/poisoned_half_blinking"),
            Identifier.withDefaultNamespace("hud/heart/poisoned_hardcore_full"),
            Identifier.withDefaultNamespace("hud/heart/poisoned_hardcore_full_blinking"),
            Identifier.withDefaultNamespace("hud/heart/poisoned_hardcore_half"),
            Identifier.withDefaultNamespace("hud/heart/poisoned_hardcore_half_blinking")
        ),
        WITHERED(
            Identifier.withDefaultNamespace("hud/heart/withered_full"),
            Identifier.withDefaultNamespace("hud/heart/withered_full_blinking"),
            Identifier.withDefaultNamespace("hud/heart/withered_half"),
            Identifier.withDefaultNamespace("hud/heart/withered_half_blinking"),
            Identifier.withDefaultNamespace("hud/heart/withered_hardcore_full"),
            Identifier.withDefaultNamespace("hud/heart/withered_hardcore_full_blinking"),
            Identifier.withDefaultNamespace("hud/heart/withered_hardcore_half"),
            Identifier.withDefaultNamespace("hud/heart/withered_hardcore_half_blinking")
        ),
        ABSORBING(
            Identifier.withDefaultNamespace("hud/heart/absorbing_full"),
            Identifier.withDefaultNamespace("hud/heart/absorbing_full_blinking"),
            Identifier.withDefaultNamespace("hud/heart/absorbing_half"),
            Identifier.withDefaultNamespace("hud/heart/absorbing_half_blinking"),
            Identifier.withDefaultNamespace("hud/heart/absorbing_hardcore_full"),
            Identifier.withDefaultNamespace("hud/heart/absorbing_hardcore_full_blinking"),
            Identifier.withDefaultNamespace("hud/heart/absorbing_hardcore_half"),
            Identifier.withDefaultNamespace("hud/heart/absorbing_hardcore_half_blinking")
        ),
        FROZEN(
            Identifier.withDefaultNamespace("hud/heart/frozen_full"),
            Identifier.withDefaultNamespace("hud/heart/frozen_full_blinking"),
            Identifier.withDefaultNamespace("hud/heart/frozen_half"),
            Identifier.withDefaultNamespace("hud/heart/frozen_half_blinking"),
            Identifier.withDefaultNamespace("hud/heart/frozen_hardcore_full"),
            Identifier.withDefaultNamespace("hud/heart/frozen_hardcore_full_blinking"),
            Identifier.withDefaultNamespace("hud/heart/frozen_hardcore_half"),
            Identifier.withDefaultNamespace("hud/heart/frozen_hardcore_half_blinking")
        );
 
        private final Identifier full;
        private final Identifier fullBlinking;
        private final Identifier half;
        private final Identifier halfBlinking;
        private final Identifier hardcoreFull;
        private final Identifier hardcoreFullBlinking;
        private final Identifier hardcoreHalf;
        private final Identifier hardcoreHalfBlinking;
 
        private HeartType(
            Identifier full,
            Identifier fullBlinking,
            Identifier half,
            Identifier halfBlinking,
            Identifier hardcoreFull,
            Identifier hardcoreFullBlinking,
            Identifier hardcoreHalf,
            Identifier hardcoreHalfBlinking
        ) {
            this.full = full;
            this.fullBlinking = fullBlinking;
            this.half = half;
            this.halfBlinking = halfBlinking;
            this.hardcoreFull = hardcoreFull;
            this.hardcoreFullBlinking = hardcoreFullBlinking;
            this.hardcoreHalf = hardcoreHalf;
            this.hardcoreHalfBlinking = hardcoreHalfBlinking;
        }
 
        public Identifier getSprite(boolean isHardcore, boolean isHalf, boolean isBlink) {
            if (!isHardcore) {
                if (isHalf) {
                    return isBlink ? this.halfBlinking : this.half;
                } else {
                    return isBlink ? this.fullBlinking : this.full;
                }
            } else if (isHalf) {
                return isBlink ? this.hardcoreHalfBlinking : this.hardcoreHalf;
            } else {
                return isBlink ? this.hardcoreFullBlinking : this.hardcoreFull;
            }
        }
 
        private static Gui.HeartType forPlayer(Player player) {
            Gui.HeartType type;
            if (player.hasEffect(MobEffects.POISON)) {
                type = POISIONED;
            } else if (player.hasEffect(MobEffects.WITHER)) {
                type = WITHERED;
            } else if (player.isFullyFrozen()) {
                type = FROZEN;
            } else {
                type = NORMAL;
            }
 
            return type;
        }
    }
}

引用的其他类

  • Optionull

    • 引用位置: 方法调用
    • 关联成员: Optionull.mapOrDefault()
  • DeltaTracker

    • 引用位置: 参数
  • Minecraft

    • 引用位置: 参数/字段
  • Font

    • 引用位置: 返回值
  • GuiGraphicsExtractor

    • 引用位置: 参数
  • BossHealthOverlay

    • 引用位置: 字段/构造调用/返回值
    • 关联成员: BossHealthOverlay()
  • ChatComponent

    • 引用位置: 字段/构造调用/返回值
    • 关联成员: ChatComponent()
  • DebugScreenOverlay

    • 引用位置: 字段/构造调用/返回值
    • 关联成员: DebugScreenOverlay()
  • PlayerTabOverlay

    • 引用位置: 字段/构造调用/返回值
    • 关联成员: PlayerTabOverlay()
  • SubtitleOverlay

    • 引用位置: 字段/构造调用
    • 关联成员: SubtitleOverlay()
  • SpectatorGui

    • 引用位置: 字段/构造调用/返回值
    • 关联成员: SpectatorGui()
  • ContextualBarRenderer

    • 引用位置: 字段/方法调用
    • 关联成员: ContextualBarRenderer.extractExperienceLevel()
  • ExperienceBarRenderer

    • 引用位置: 构造调用
    • 关联成员: ExperienceBarRenderer()
  • JumpableVehicleBarRenderer

    • 引用位置: 构造调用
    • 关联成员: JumpableVehicleBarRenderer()
  • LocatorBarRenderer

    • 引用位置: 构造调用
    • 关联成员: LocatorBarRenderer()
  • Lightmap

    • 引用位置: 方法调用
    • 关联成员: Lightmap.getBrightness()
  • BlockPos

    • 引用位置: 方法调用
    • 关联成员: BlockPos.containing()
  • Holder

    • 引用位置: 参数
  • Component

    • 引用位置: 参数/字段/方法调用
    • 关联成员: Component.empty(), Component.translatable()
  • Identifier

    • 引用位置: 参数/字段/方法调用/返回值
    • 关联成员: Identifier.withDefaultNamespace()
  • ARGB

    • 引用位置: 方法调用
    • 关联成员: ARGB.color(), ARGB.colorFromFloat(), ARGB.white()
  • Mth

    • 引用位置: 方法调用
    • 关联成员: Mth.ceil(), Mth.clamp(), Mth.cos(), Mth.floor(), Mth.hsvToArgb(), Mth.lerp()
  • RandomSource

    • 引用位置: 字段/方法调用
    • 关联成员: RandomSource.create()
  • StringUtil

    • 引用位置: 方法调用
    • 关联成员: StringUtil.formatTickDuration()
  • Util

    • 引用位置: 方法调用
    • 关联成员: Util.getMillis()
  • Profiler

    • 引用位置: 方法调用
    • 关联成员: Profiler.get()
  • MobEffect

    • 引用位置: 参数
  • Entity

    • 引用位置: 参数
  • EquipmentSlot

    • 引用位置: 方法调用
    • 关联成员: EquipmentSlot.values()
  • LivingEntity

    • 引用位置: 参数/返回值
  • Player

    • 引用位置: 参数/返回值
  • ItemStack

    • 引用位置: 参数/字段
  • HitResult

    • 引用位置: 参数
  • DisplaySlot

    • 引用位置: 方法调用
    • 关联成员: DisplaySlot.teamColorToSlot()
  • Objective

    • 引用位置: 参数
  • PlayerScoreEntry

    • 引用位置: 字段
  • PlayerTeam

    • 引用位置: 方法调用
    • 关联成员: PlayerTeam.formatNameForTeam()