Skip to content

界面与展示 ​

玩家看到的仓库界面由这几处决定: config.yml 的 gui 与 display 两段, gui/storage_gui.yml 模板的结构, 以及各种点击的含义

容量与槽位数量见容量与缩容, config.yml 的其余键见配置详解

gui ​

yaml
gui:
  storage_rows: 5
  deposit_feedback: actionbar
  require_empty_cursor_for_withdraw: false
字段类型必填默认值取值范围说明
storage_rowsint否5加载时钳制到 1–5 (越界会记 warning)展示区的行数. 功能区永远独占最后一行, 所以实际窗口的行数 = storage_rows + 1; 每页的展示格数 = storage_rows × 9
deposit_feedbackenum否actionbaractionbar / message / none存入成功之后用什么方式给反馈. 填了不认识的值会退回 actionbar. 它只影响成功和部分存入的反馈, 失败提示一直走聊天
require_empty_cursor_for_withdrawboolean否falsetrue / false取出时是否要求光标为空. 见下面的说明

建议: deposit_feedback 不要设为 none. 两种存入方式混用时, 物品按条目顺序摆放, 可能落到别的页上; 关掉反馈玩家会以为物品消失了

require_empty_cursor_for_withdraw 是防手滑的开关. 你设为 true 时, 光标上拿着物品去点展示区槽位不再存入, 而是变成不做任何事, 并提示 gui.deposit.cursor_guard, 用来堵住"本想取出, 但光标里还有残留物品"这个误操作的口子; 代价是少了"拿着物品点条目就存入"这条快捷路径. 设为 false (默认) 时保留这个快捷存入. 你要存入仍然可以用固定投入口或者 deposit_all

比如这样把窗口缩到 3 行展示区, 并让存入反馈走聊天消息

yaml
gui:
  storage_rows: 3
  deposit_feedback: message
  require_empty_cursor_for_withdraw: true

storage_rows 换算表 ​

模板文件里的 slots 只是占位值, 不用管它. 真实槽位号在加载时按 gui.storage_rows 换算:

text
storageRows  = clamp (gui.storage_rows, 1, 5)
totalRows    = storageRows + 1
functionBase = storageRows * 9
展示区槽位    = 0 .. functionBase - 1
功能区槽位    = functionBase + offset
storage_rowstotalRows每页格数展示区槽位功能区槽位 (offset 0–8)
1290–89–17
23180–1718–26
34270–2627–35
45360–3536–44
56450–4445–53

超出范围会自动收回: 填 >= 6 会被夹到 5 并记 warning; 填 <= 0 会被夹到 1 并记 warning. totalRows 最大是 6, 正好在 CoreLib 的 1–6 范围内

storage_gui.yml 模板结构 ​

yaml
id: storage_gui
gui_type: CHEST
title: "<gradient:#4DA6FF:#FFD166>绘卷仓库</gradient>"

slots:
  storage_slot:
    type: storage_slot
    slots: [0]
    item:
      source: "gray_stained_glass_pane"

  page_prev:
    type: page_prev
    offset: 0
    slots: [0]
    item:
      source: "arrow"
字段类型必填默认值取值范围说明
idstring是发货值 storage_gui必须为 storage_gui模板 id, 插件按这个 id 去找模板. 写成别的值时找不到模板, 界面打不开并记 warning
gui_typestring否发货值 CHESTBukkit InventoryType 名称容器的类型. 重建布局时窗口一定会被重建成 CHEST, 所以这个键决定不了最终的窗口类型
rowsinteger否发货文件未声明被忽略通用模板里的行数字段. 仓库布局在加载时会用 gui.storage_rows + 1 重建模板, 这个键不起作用; 要改行数请改 gui.storage_rows
titlestring / object否发货值 "<gradient:#4DA6FF:#FFD166>绘卷仓库</gradient>"支持 MiniMessage 格式字符串或 TextConfig 对象窗口的标题
slotsmap否发货值含 9 个条目键为槽位条目的 key槽位条目的表.必须包含 storage_slot, 否则展示区建不起来, 整份模板解析失败
slots.<key>.typestring否由条目 key 小写推导见下方槽位类型表槽位类型的标签. 不写时会按 key 推算; 写了认不出来的类型时, 这个槽位还在, 但点它没有任何反应
slots.<key>.offsetinteger否—0–8功能区条目在这一行里的偏移. 缺失, 不是数字或者超出范围时, 这个条目会被拒绝并记 warning; 同一个 offset 被两个条目占用时, 后一个会被拒绝. storage_slot 不用这个键
slots.<key>.slotslist<integer>否——通用模板要求的格子索引. 功能区条目的这个键在加载时会被 offset 换算出来的结果覆盖, 写什么都不起作用
slots.<key>.itemsection否—共享物品定义键集 (source, amount, components 等), 见 CoreLib GUI条目的外观. 在 storage_slot 上配置的物品, 只用来当"还没解锁的槽位"的占位外观

你能用的一共是 slots 下这 9 个槽位类型:

槽位类型作用
storage_slot展示区的原型. 必需项, 缺了它展示区建不起来, 整份模板解析失败
deposit_slot固定投入口. 光标上带着物品点它就存入
page_prev上一页
page_info当前页的信息, 只是展示
page_next下一页
search打开搜索输入; 搜索时右键可以清除过滤
sort切换排序, Shift 点击是反向切换
deposit_all一键存入, 会把背包 36 格都遍历一遍
unlock付费扩容的入口

条目的 type 你也可以明确写出来; 不写就按条目 key 的小写来推算, 所以把条目命名成对应类型名就行

offset 与 slots 的关系 ​

记好一条: 功能区条目只配 offset (合法范围 0–8). 模板里的 slots 键只是为了能让通用模板解析通过才保留的, 加载时会被换算结果覆盖, 不能当成真实位置

  • offset 缺失, 非数字或越出 0–8 时, 该条目被拒绝并记 warning
  • 两个条目占用同一个 offset 时, 后者被拒绝并记 warning
  • 所有功能条目都被拒绝时记 warning, 翻页和存入按钮就用不了了

展示区的 storage_slot 是原型: 加载时会展开成 0 .. functionBase - 1 整个展示区. 你在它上面配置的物品只当"还没解锁的槽位"的占位外观, 不影响已经解锁的槽位怎么显示

你改了 gui.storage_rows 后, 功能区会自动跟着变, 不需要手动改任何槽位号

比如这样把标题换成自定义文本, 并把搜索按钮从默认偏移 4 挪到默认布局里唯一空出的偏移 2

yaml
title: "<gold>我的仓库</gold>"

slots:
  search:
    type: search
    offset: 2
    item:
      source: "compass"

挪动条目前先看一眼: 默认功能区占用偏移 0, 1, 3, 4, 5, 6, 7, 8, 偏移 2 是空位; 你要保证目标偏移不被别的条目占用, 否则被挪动的条目会被拒绝并记 warning

GUI 点击规则 ​

位置操作效果
展示区槽位光标带物品 + 左键把光标上的物品全部存入
展示区槽位光标带物品 + 右键存入 1 个
展示区槽位光标为空 + 左/右/Shift 左/Shift 右键按 withdraw_amounts 取出
展示区槽位光标为空 + 中键打开自定义数量输入 (受 behavior.withdraw_prompt.enabled 控制, 对话框或聊天输入由 behavior.withdraw_prompt.mode 决定)
deposit_slot光标带物品把光标上的物品全部存入
deposit_slot光标为空提示投入口是空的
deposit_all点击遍历背包 36 格批量存入
sort点击 / Shift 点击切换排序 / 反方向切换
search点击打开搜索输入; 搜索中右键清除过滤
page_prev / page_next点击翻页, 空页翻不进去
背包内物品Shift 点击把这次 Shift 点击转到投入口的逻辑上处理

下面这些点法一律不接受: 双击, 数字键, 副手交换键, 丢弃键, Ctrl + 丢弃键. 它们分别会跨槽聚合, 绕开光标的操作规则, 或者直接把物品丢掉, 没法给它们一个安全的含义, 所以点击时统一回报 gui.click.unsupported

注意: 处于搜索状态时展示区不允许存入 (翻页跟着过滤结果走, 展示区的槽位号不再对应真实槽位号), 但固定投入口仍然能用

取出数量, 排序默认值与存入过滤等行为键, 见配置详解的 behavior 段

display ​

yaml
display:
  amount_mode: percent
  percent_scale: 99
  compact_units: ["K", "M", "B", "T", "P", "E"]
  compact_decimals: 2
  show_exact_amount: true
  lore_position: bottom
字段类型必填默认值取值范围说明
amount_modeenum否percentpercent / one槽位物品 amount 字段的表达方式: percent 用 1–99 表示占用百分比, one 则恒为 1. 填了不认识的值会退回 percent
percent_scaleint否99使用前钳制到 1–99 (越界不报错)percent 模式下刻度的上限, 同时也是槽位物品 max_stack_size 组件取的值
compact_unitslist<string>否["K", "M", "B", "T", "P", "E"]最多 6 个元素; 空列表回退默认值紧凑数量的单位, 按顺序对应 10³... 10¹⁸. 列表为空时会按默认的六个单位处理, 而不是退回显示精确数字
compact_decimalsint否2≥ 0 (负值按 0 处理)紧凑格式保留几位小数, 向下取整之后再裁掉末尾的零
show_exact_amountboolean否truetrue / false是否在 lore 里额外显示带千分位的精确数量
lore_positionenum否bottomtop / bottom生成的那些展示信息相对模板自带 lore 插入的位置. 填了不认识的值会退回 bottom

比如这样关掉占用率渲染 (槽位物品恒显示 1), 少留一位小数, 并把生成行放到模板 lore 上方

yaml
display:
  amount_mode: "one"
  compact_decimals: 1
  show_exact_amount: false
  lore_position: top

1–99 刻度规则 ​

max_stack_size 组件只接受 1–99, 所以插件从不用 100 或更大的值, 也不涉及数据包技巧. 刻度边界是特意这么定的:

情形显示的 amount
amount_mode: one恒为 1
stackLimit 为不限制 (Long.MAX_VALUE) 或 <= 0退化为 1, 百分比对无限上限没有意义
存量 <= 01
存量 >= stackLimit (真正装满)percent_scale (默认 99)
部分装满clamp(round(amount / stackLimit * scale), 1, scale - 1), 即默认最多 98

为什么要有这些夹取: 没有它们, 几乎空的槽位会显示成 0 (看不见), 几乎装满的槽位和真正装满的就分不出来了

槽位上的百分比和 lore 里的文本算法不同: lore 里的百分比文本是按真实的 0–100 范围单独算的, 不跟着 1–99 的夹取走

紧凑单位 ​

compact_units 依次对应 10³, 10⁶, 10⁹, 10¹², 10¹⁵, 10¹⁸ 这六个阈值, 最多只取 6 个元素. Long.MAX_VALUE 大约是 9.22E, 所以 E 这个单位能覆盖整个 long 范围. 数量小于 1000 时直接输出原始数字. 你在配置里把列表写成空列表时, 解析阶段会退回默认的六个单位, 所以"空列表导致不用紧凑单位"这条路在配置层面根本走不到

相关页面 ​