playeraffixes-2.0.0.jar
Curse Maven Snippet
What's new
Added / 新增
-
Multiple talent pages (多天赋页): a talent tree is now a list of pages instead of one flat list. Every page has its own id, name, tab icon, background and prerequisites, plus a "shown while locked" switch: while the prerequisites are unmet the whole page is gated (its talents cannot be unlocked, on the server too) and the tab is either shown as locked or hidden entirely. Players get a tab strip at the top of the talent tree; the editor gets a tab strip (with a
+to add a page) and a page section in the property panel with new/copy/delete/reorder buttons. Cross-page references (a talent on page B requiring one on page A) are supported; ids stay unique document wide. 天赋树现在由多个天赋页组成,而不是一条扁平列表。每页有自己的 ID、名称、页签图标、背景与前置天赋,以及「未解锁时是否显示」开关:前置未满足时整页被封印(该页天赋无法解锁,服务端同样校验),页签可以显示为锁定或直接隐藏。玩家端天赋树顶部有页签栏,编辑器有页签栏(末尾+新建页)和属性栏里的页面段(新建/复制/删除/前后移动)。支持跨页引用(B 页天赋以前置 A 页天赋),ID 在整个文件内保持唯一。 -
In-game visual talent editor (
/talent editor, OP level 2): a GUI page that replaces hand-writing talent datapacks. The left side is the actual talent tree — the same frames, icons and link lines the in-game page draws — but editable: drag a node to place it (with 16px grid snapping), drag empty space to pan, scroll to zoom, click to select, use the link/prerequisite mode to connect nodes by clicking, right-click to drop a relationship, and New/Copy/Delete buttons for the nodes themselves. The right side is a live-bound property panel (every widget writes into the model as you type, so there is no "submit" step that can lose an edit) where ids are never typed by hand: items (with icons), attributes, mob effects, affixes, professions and references to other talents are all chosen from a searchable picker. Then press Save & Reload: the mod writes a real datapack and hot reloads it. The file lands in<game dir>/config/playeraffixes/talents/<file>.jsonand is registered as the editor store, so it survives restarts and can be copied into another pack./talent editor <player>opens it for somebody else. The permission is checked again on the server for every save, and the payload is sanitised with every correction logged. -
新增游戏内可视化天赋编辑器(
/talent editor,需要 OP 等级 2):左侧画的就是游戏里那张天赋树,但可以直接编辑:拖动节点改位置(可对齐 16px 网格)、拖空白平移、滚轮缩放、点击选中;切到「连线/前置」模式后点击另一个节点即可建立或取消关系,右键可删除两个节点间的全部关系,工具栏可新建/复制/删除节点。右侧是实时绑定的属性栏,并且基本不需要手打 ID:物品(带图标)、属性、状态效果、词条、职业、以及对其他天赋的引用全部从可搜索的选择器里挑。最后点 保存并热加载:模组写出文件并立即生效。文件位于<游戏目录>/config/playeraffixes/talents/<文件名>.json,作为编辑器存储由模组自己读取,重启后依然生效,也可以拷到别处使用。/talent editor <玩家>可以为他人打开。每次保存都会在服务端重新校验权限并清洗数据,每一处修正都会写入日志。 -
Deterministic datapack load order (确定性的数据包加载顺序):
TalentTreeManagernow applies talent files in a sorted order, so when two datapacks define the same talent id the winner no longer depends onMapiteration order. Duplicate ids now log a warning instead of silently overwriting each other. 当两个数据包定义同一个天赋 ID 时,现在由固定顺序决定谁生效,重复 ID 会输出警告日志,不再取决于Map的迭代顺序。 -
/talent reloadnow re-scans the datapack folders (现在会重新扫描数据包目录): a pack dropped into the world/datapack folder while the game is running is discovered without restarting. 游戏运行期间放进数据包目录的数据包不再需要重启即可被识别。
Changed / 变更
-
The player talent tree now uses the vanilla advancements UI (玩家端天赋树改用原版成就界面那套 UI): the hand-drawn dark panel and the text tabs are gone. The tree is drawn inside the vanilla advancements window (
textures/gui/advancements/window.png, 252x140 with a 234x113 inside area), every talent page gets an icon-only tab above the window using the vanilla tab sprites (tabs.png), more than 8 pages paginate with</>buttons and ann / mindicator, and the page background is tiled with the scroll offset inside a pose translated to the inside area and clipped to it - all of it mirrored fromAdvancementsScreen/AdvancementTab. Hovering a tab shows the page name (plus the missing prerequisites while it is locked), and a locked page dims the window and lists what is still needed. 玩家端不再使用自绘的深色面板与文字页签:天赋树画在原版成就窗口里(window.png,252×140,内部可用区 234×113),每个天赋页是窗口上方一个纯图标页签(原版tabs.png贴图),超过 8 页用</>按钮翻页并显示n / m,页背景在平移到内部区域原点的坐标系里按滚动偏移平铺并剪裁——全部照抄AdvancementsScreen/AdvancementTab的做法。悬浮页签显示页名(锁定时附带缺少的前置天赋),锁定页整页压暗并列出还缺什么。 -
The editor's page tabs use the vanilla button sprite (编辑器页签改用原版按钮贴图): the tab strip is painted with
textures/gui/widgets.png(the same spriteButtonuses) instead of hand-drawn rectangles, while keeping the text labels so an admin can still tell the pages apart. 编辑器页签改用原版widgets.png按钮贴图(与Button同一套),保留文字标签以便分辨页。 -
Editor storage moved out of the datapack system (编辑器存储不再走数据包): the generated-datapack approach did not hot reload reliably. The editor now writes plain files to
<game dir>/config/playeraffixes/talents/<file>.jsonand the mod reads them itself.TalentTreeManagerkeeps two layers - datapacks and the editor store - and overlays them by page: an editor page replaces the datapack page with the same id (keeping its position in the tab order), new ids are appended. Files written before pages existed (a file levelbackgroundplus a flattalentsarray) still load, as a single page with idmain. Saving is now just "write file + re-read the store + resync". Editor storage 改为模组自己的 config 目录(不再依赖数据包),两层按页合并:编辑器保存的页整体替换同 ID 的数据包页,旧格式文件(顶层background+ 扁平talents)仍然兼容,会被当成 ID 为main的单页。 -
The tree sync now carries pages (同步协议改为下发页面):
S2CSyncTalentTreePacketsends the page list (with fully qualified ids) and the client rebuilds it with the sameTalentPage/TalentNodeparsers.PROTOCOL_VERSIONis now"3". 同步包改为下发页面列表(ID 全部带命名空间),客户端用同一套解析器还原;PROTOCOL_VERSION升到"3"。 -
Node frames are drawn by one shared renderer (节点外框由同一个渲染器绘制):
TalentFrameRenderernow owns the frame shapes, sizes and hit boxes used by both the talent tree page and the editor, so the editor can never place a node where the tree does not actually draw it.TalentIconsowns theiconfield parsing for both as well; a malformedtexture:path now yields no icon instead of throwing during rendering.TalentFrameRenderer统一了天赋树界面与编辑器的外框形状、尺寸与点击判定,避免两处画法不一致;TalentIcons统一了icon字段解析,非法的texture:路径不再在渲染时抛异常。 -
Client/server requirement checks are consistent: the client now scans the offhand as well (the server scans the entire inventory), so a material held in the offhand is usable. 客户端现在也会扫描副手(服务端扫描整个背包)。
-
Talent tree UI no longer uses a stale data reference: the screen resolves the live player talent data every frame, so states stay correct after a respawn or dimension change. 界面每帧读取实时的玩家天赋数据。
Fixed / 修复
-
Editor property rows were cut off at the panel edge (编辑器属性行被面板右边缘裁掉): a row's widget widths used each weight directly as a fraction of the full row, so any row whose weights summed to more than 1 spilled past the panel and everything beyond its right edge was clipped away by the panel scissor - the second "background size" box, the "pick icon" button and the whole page-actions row were effectively invisible. Rows now normalise their weights against their sum, the last widget takes exactly the leftover width, and a 10px gutter is reserved for the scroll indicator. 属性行的控件宽度原先直接把权重当成整行宽度比例,权重之和大于 1 的行就会溢出面板,超出部分被面板剪裁掉——"背景宽高"的第二个输入框、"选择图标"按钮以及整排"页操作"按钮实际上都看不见。现在按权重之和归一化、最后一个控件吃掉剩余宽度,并给滚动条预留 10px 边距。
-
Talent tooltips could be painted over by item icons (天赋提示框会被物品图标盖住): item models are their own render type and are always flushed after the gui/text batches of a frame. The tooltip pass now flushes first and is drawn on a pushed z layer with depth test enabled, exactly like
AdvancementsScreen#renderTooltips. 物品模型属于独立 render type,总在本帧 gui/text 批次之后才刷新。现在提示框先flush(),再在推高的 z 层上开启深度测试绘制,与原版AdvancementsScreen#renderTooltips一致。 -
Editor panel jumped back to the top on every button press (编辑器点按钮就把属性栏拉回最上方): the deferred panel rebuild used to reset the scroll position unconditionally. Rebuilds now keep the scroll position, and only selection changes scroll on purpose (to the node section). 属性栏重建不再无条件重置滚动位置;只有切换选中/切换页才会主动滚动(滚到节点段或回顶部)。
-
Dragging moved the previously grabbed node (拖动会移动上次点过的节点): a drag whose release was never delivered (button let go outside the window, click swallowed by the picker) left
movingIndexset, so the next drag anywhere moved that node. The drag state is now cleared on every press and ignored while a modal is open. 一次没有收到释放事件的拖拽会残留movingIndex,导致之后在别处拖动时移动"上次抓的节点"。现在每次按下都会清空拖拽状态,弹窗打开时也不再处理拖拽。 -
The editor's picker popup was covered by item icons (编辑器的选择弹窗被物品图标盖住): item models live in their own render type, so they are flushed after the gui/text batches of the frame no matter what order they were submitted in. The modal now calls
graphics.flush()first and is drawn on a pushed depth layer. 物品模型属于独立 render type,会在本帧 gui/text 批次之后才刷新,所以以前会盖在弹窗上。现在弹窗先graphics.flush()再在推高的深度层上绘制。 -
Sanitising no longer deletes data (清洗不再丢数据): a page or talent with an unusable or duplicated id used to be dropped (which could silently delete a whole page worth of talents). Both are now renamed instead (
page/talent, or_2/_3suffixes, checked document wide); only unresolvable references (item/attribute/effect/affix ids) are still dropped, because a dead reference would just make the talent permanently un-unlockable. 之前页或天赋的 ID 无法修复/重复时会被直接丢弃(可能整页消失)。现在改为自动改名(page/talent或追加_2/_3,全文档查重),只有无法解析的引用(物品/属性/效果/词条 ID)仍然丢弃。 -
CRITICAL — Talents wiped when returning from the End (从末地返回主世界天赋全部清零):
PlayerEvent.Cloneis fired by Forge for both a death respawn and for leaving the End through the exit portal. The exit-portal case reportsisWasDeath() == false, and the clone handler only copied the talent data whenisWasDeath()was true, so the brand new player entity always started with an empty talent tree. The copy now happens for every clone. -
【严重】从末地返回主世界时天赋清零: Forge 的
PlayerEvent.Clone事件在“死亡重生”和“从末地返回主世界”两种情况下都会触发,而从末地返回时isWasDeath()为false。旧代码只在isWasDeath()为 true 时复制天赋数据,因此返回主世界后新建的玩家实体天赋永远是空的。现在无论哪种情况都会复制。 -
Persistent backup for talent data (天赋数据持久化备份): The talent data is now mirrored into the player's persistent (ForgeData) NBT whenever it changes, and restored from that backup if the live capability ever comes back empty.
copyFromalso deep-copies the affix state (getPersistentData()), which was previously dropped on every player clone. -
天赋数据持久化备份: 天赋数据发生变化时会同步写入玩家的持久化(ForgeData)NBT;若实时数据意外为空则自动从备份恢复。同时
copyFrom现在会深拷贝词条状态(getPersistentData()),此前该状态在每次玩家克隆时都会丢失。 -
Silent unlock failures are now visible (解锁失败不再是“无反应”): The server logs exactly what a failed unlock was missing, and the client tells the player which materials/levels are short instead of doing nothing. Item ids that do not resolve to a registered item now log a warning.
-
解锁失败不再静默: 服务端会记录解锁失败时缺少的具体材料/等级,客户端也会把缺少的材料与经验提示给玩家。数据包中不存在(或没有对应物品)的物品 ID 现在会输出警告日志。
-
Unlock costs are only consumed after all checks pass (消耗材料前先完成校验):
TalentUnlockEvent.Preis now fired before XP and items are removed, so a listener cancelling the unlock no longer eats the materials. -
先校验后扣材料:
TalentUnlockEvent.Pre现在在扣除经验与物品之前触发,若事件被取消则不会吞掉玩家的材料。
This mod has no additional files

