GuiBetterAchievements
基本信息
| 属性 | 值 |
|---|---|
| 类名 | betterachievements.gui.GuiBetterAchievements |
| 父类 | net.minecraft.client.gui.GuiScreen |
| SideOnly | Side.CLIENT |
| 源文件 | src/main/java/betterachievements/gui/GuiBetterAchievements.java |
功能
完整重写后的成就界面。支持多 AchievementPage 切换、鼠标滚轮缩放、鼠标拖拽、自定义箭头颜色、Tooltip、彩虹模式颜色、游戏内中键改页签图标、创造模式右键直接解锁(含父链解锁)。
由 GuiOpenHandler 在 GuiOpenEvent 中拦截 GuiAchievements 替换而来,prevScreen 与 currentPage 通过反射从原版 GuiAchievements.field_146562_a 和 currentPage 字段读出,再将 currentPage + 1 作为参数传入构造函数(避免与 AchievementRegistry.mcPage 冲突)。
构造
public GuiBetterAchievements(GuiScreen currentScreen, int page)
| 参数 | 说明 |
|---|---|
| currentScreen | 原版父界面(用于 “Done” 按钮返回) |
| page | 1-based 页索引;0 表示恢复上次记忆的 lastPage(静态字段) |
关键常量
| 常量 | 值 | 说明 |
|---|---|---|
blockSize |
16 | 背景方块尺寸 |
maxTabs |
9 | 单页可见标签数 |
guiWidth / guiHeight |
252 / 202 | GUI 总尺寸 |
tabWidth / tabHeight |
28 / 32 | 标签尺寸 |
achievementSize / achievementInnerSize |
24 / 22 | 成就方框外/内尺寸 |
minDisplayColumn |
AchievementList.minDisplayColumn * 24 - 240 |
视图左边界 |
maxDisplayColumn |
AchievementList.maxDisplayColumn * 24 |
视图右边界 |
minDisplayRow |
AchievementList.minDisplayRow * 24 - 240 |
视图上边界 |
maxDisplayRow |
AchievementList.maxDisplayRow * 24 |
视图下边界 |
scaleJump |
0.25F | 缩放步进 |
minZoom |
1.0F | 默认最小缩放 |
maxZoom |
2.0F | 默认最大缩放 |
静态可配置字段(由 ConfigHandler 写入)
| 字段 | 默认 | 说明 |
|---|---|---|
colourUnlocked |
#A0A0A0 |
已解锁成就箭头颜色(int) |
colourCanUnlock |
#00FF00 |
可解锁成就箭头颜色(int) |
colourCantUnlock |
#000000 |
不可解锁成就箭头颜色(int) |
colourUnlockedRainbow 等 |
false | 是否启用彩虹模式(替代固定颜色) |
colourUnlockedRainbowSettings 等 |
null | 彩虹参数数组 |
scrollButtons |
true | 是否显示左右翻页按钮(“<” / “>”) |
iconReset |
false | 是否启用游戏中键改页签图标 |
userColourOverride |
false | 是否强制使用用户箭头颜色,覆盖 mod 提供方 |
交互
| 触发 | 行为 |
|---|---|
| ESC / 物品栏键 | 关闭 GUI(mc.displayGuiScreen(null)) |
| ← / → | 切换 AchievementPage(环绕跳转) |
| Done 按钮 | 返回 prevScreen |
| Old Screen 按钮 | 打开 GuiAchievementsOld(绕过拦截器) |
| 鼠标左键拖拽 | 平移视图(仅在内部区 inInnerScreen 内有效) |
| 鼠标滚轮(标签上方) | 滚动页签窗口(tabsOffset 增减) |
| 鼠标滚轮(成就区) | 缩放视图 |
| 鼠标左键点击标签 | 切换当前 AchievementPage |
| 鼠标悬停成就 + 左键 | 鼠标按住可解锁(仅 GuiOpenHandler 进入的新状态) |
| 鼠标悬停成就 + 右键 | 创造模式发送 AchievementUnlockMessage 解锁(含父链递归) |
鼠标悬停成就 + 中键 + iconReset |
把当前页签图标改为该成就图标 |
行为:成就渲染
drawAchievement(Achievement):
- 计算该成就到最近已解锁父节点的
depth = statFileWriter.func_150874_c(achievement)(0…5)。 - 若
depth >= 5跳过绘制(说明太远)。 - 计算亮度:
unlocked → 0.75F、canUnlock → 1.0F、depth<3 → 0.3F、depth<4 → 0.2F、depth<5 → 0.1F。 - 若成就实现
ICustomBackgroundColour,按其返回值上色;否则按亮度灰度上色。 - 绑定
sprites.png绘制 26×26 背景方块(special时换 sprite)。 - 若实现
ICustomIconRenderer,调用renderIcon;否则使用RenderItem绘制achievement.theItemStack,未解锁时降低亮度并禁用 color。
行为:箭头渲染
drawArrow(achievement, colourCantUnlock, colourCanUnlock, colourUnlocked):
- 仅当
depth < 5时绘制。 - 根据
unlocked/canUnlock选择颜色(顺序:unlocked → unlocked, canUnlock → canUnlock, 否则 → cantUnlock)。 - 画水平线 + 垂直线 + 箭头头部 sprite(4 个方向 sprite:
arrowRightX/Y/arrowLeftX/Y/arrowUpX/Y/arrowDownX/Y)。 - 优先顺序:
ICustomArrows.getColourFor*()覆盖(除非userColourOverride=true),否则使用配置/彩虹颜色。
行为:背景渲染
drawAchievementsBackground(page):
GL11.glTranslatef(left, top + borderWidthY, -200.0F)移动到内容区。- 若页实现
ICustomBackground,调用其drawBackground(drawBackground自己处理缩放)。 - 否则用方块纹理(
TextureMap.locationBlocksTexture)绘制伪地形背景:- 随机种子
session.getPlayerID().hashCode() + (dragY+y) + (dragX+x)*16 r = random.nextInt(1 + dragY + y) + (dragY + y) / 2r == 40→diamond_ore/redstone_ore(1/3 概率);r == 20→iron_ore;r == 12→coal_ore;r > 60→bedrock;r > 4→stone;r > 0→dirt;其余 →grass。- 颜色按
(dragY+y)/80.0F调暗:0.7F - dragY/80.0F。 - 缩放应用
1/scale。
- 随机种子
行为:Tooltip
drawMouseOverAchievement(mouseX, mouseY):
- 仅在鼠标在内部区时调用。
- 若实现
ICustomTooltip,调用renderTooltip(mouseX, mouseY, statFileWriter)。 - 否则按
defaultTooltipWidth=120绘制文本框:- 不可解锁且
depth>3→ 直接 return(不显示 tooltip)。 - 不可解锁时
desc = achievement.requires(parentTitle);depth==3时title = achievement.unknown。 - 已解锁时
tooltipHeight += lineSize以容纳 “Taken” 提示。 - 颜色:canUnlock →
(special ? -128 : -1);否则(special ? -8355776 : -8355712)。 - 描述用
-6250336灰色,已解锁achievement.taken用-7302913。
- 不可解锁且
- 释放
hoveredAchievement为 null。
缩放与拖拽
doDrag(mouseX, mouseY):
- 鼠标按住左键时若在
inInnerScreen:- 首次按下
newDrag=true,不移动,只记录prevMouseX/Y。 - 后续帧
xPos -= (mouseX - prevMouseX) * scale、yPos同理。
- 首次按下
- 鼠标松开时
newDrag=true。 - 视图被
minDisplayColumn/max/minDisplayRow/max夹紧。
doZoom(page):
- 滚轮:
scale += 0.25F或-= 0.25F。 - 范围:
ICustomScale.getMinScale()/getMaxScale()或默认1.0F / 2.0F。 - 缩放后维持视觉中心:
xPos -= (newW - prevW)/2,yPos同理。
doTabScroll():
- 在标签上方滚轮:
tabsOffset++或--。 - 范围:
[0, pages.size() - maxTabs/3*2]。
相关条目
- GuiAchievementsOld - “Old Screen” 按钮的跳转目标
- GuiOpenHandler - 拦截原版成就 GUI 的入口
- Configuration - 全部配置项
- ColourHelper - 颜色与彩虹计算
- ICustomBackground
- ICustomIcon
- ICustomPosition
- ICustomScale
- ICustomArrows
- ICustomBackgroundColour
- ICustomIconRenderer
- ICustomTooltip