勘探者日志(Prospector’s Log)
本 mod 唯一注册的游戏物品。它不是容器也不是工具,而是一张「数据收据」:右键写入把自己的勘探数据打包上传给服务器,右键读取别人的数据下载到本地。最大堆叠 1,无耐久,无附魔。
基本信息
| 属性 | 值 |
|---|---|
| 注册名 | visualprospecting:visualprospecting.prospectorslog(HooksShared.java:101,getUnlocalizedName() 直接取自 ProspectorsLog.java:31) |
| 内部类 | com.sinthoras.visualprospecting.item.ProspectorsLog |
| 本地化名 | item.visualprospecting.prospectorslog.name = Prospector’s Log |
| 物品组 | GregTech 主物品栏(setCreativeTab(GregTechAPI.TAB_GREGTECH),ProspectorsLog.java:32) |
| 最大堆叠 | 1(构造时直接 maxStackSize = 1,非 setMaxStackSize) |
| 贴图 | visualprospecting:prospectorslog |
| 子类型 | 否 |
| 耐久度 | 无 |
| 合成配方 | 无 |
⚠️ 注册名含两个点号(visualprospecting.visualprospecting.prospectorslog),因为 setUnlocalizedName 传入的是 "visualprospecting.prospectorslog",而 Forge 会在其后拼 ".name" 查语言文件。写命令 / KubeJS 脚本时要注意这个双段结构。
两种状态
状态不靠 damage 值区分,而是靠 NBT。isFilledLog()(ProspectorsLog.java:101-105)判定 NBT 是否同时含 log_author 与 log_author_id 两个键:
| 状态 | NBT | tooltip |
|---|---|---|
| 空白 | 无 NBT | item.visualprospecting.prospectorslog.empty = “Use item to fill it.” |
| 已填写 | log_author(显示名)+ log_author_id(UUID 字符串) |
item.visualprospecting.prospectorslog.author = “Author: %s” |
右键行为
onItemRightClick(ProspectorsLog.java:37-86)永不消耗物品,恒 return item。
空白日志 → 写入自己的数据
客户端 world.isRemote 分支只发一个 SnapshotUploadTask;真正的判定在服务端:
VP.randomGeneration.nextInt(1000) < 5 → 失败:发灰色斜体消息 + destroyCurrentEquippedItem()(物品消失)
否则 → 成功:发 "creation.begin" 消息
写入失败率 0.5%(5/1000)。失败时消息取 item.visualprospecting.prospectorslog.creation.fail<random>,其中 <random> 是那个随机数本身。
已填写日志 → 读取对方数据
先比对 NBT 里的 log_author_id 与当前玩家 UUID。只有不是自己写的日志才继续(读自己的日志无任何反应)。且判定上限取决于对方数据是否已在本地:
TransferCache.instance.isClientDataAvailable(authorUuid) ? 1000 : 5
- 对方数据已在本地 → 5/1000 失败率,走
SnapshotDownloadTask; - 对方数据不在本地 → 必定失败(5/5),发
reading.fail<random>消息并销毁物品。
成功时发 reading.begin,服务端 TaskManager.SERVER_INSTANCE 排入 SnapshotDownloadTask(authorUuid, player);完成后客户端发 reading.end = “I finished the Prospector’s Log of %s”。
已知缺陷
-
失败消息键名带随机数,但语言文件只提供 fail0–fail4。
en_US.lang里creation.fail0–fail4与reading.fail0–fail4各 5 条(内容是 “Damn! I spilled coffee over it…” 之类的趣味文案),而代码把nextInt(1000)的返回值(0–999)直接拼进键名。所以 995/1000 的失败会显示原始键名字符串(形如item.visualprospecting.prospectorslog.creation.fail713)而不是可读文案。同一缺陷存在于写入与读取两条路径。 -
读取不存在的数据会销毁物品。当对方数据不在本地时
nextInt(5)恒小于 5,必然走进失败分支,而失败分支调player.destroyCurrentEquippedItem()。玩家在队伍数据未同步时右键队友的日志,日志直接消失且看不到任何有效原因(看到的是随机数键名)。 -
VP.randomGeneration命名误导(VP.java:13)。这个Random实例在本 mod 里只被当作「判失败」的随机源,与「随机生成」无关;且它是全局共享且非线程安全的单一Random,服务端多玩家同时右键会争用同一实例。 -
物品无任何获取途径。
grep -rn "addRecipe" src/main/java无输出,本 mod 不注册任何配方。唯一来源是创造模式物品栏——GT 地震勘探器产出的是数据棒(Data Stick),不是本物品。