MCphone NeoForge 1.21.1 v1.10.1
Curse Maven Snippet
What's new
MCphone v1.10.1
接着 1.10.0:手机物品换成了 3D 模型、快捷键少走一步、卡槽里的终端不会再没电。
运行环境: Minecraft 1.21.1 · NeoForge 21.1.200 或更高 · 客户端与服务端都需安装
从 1.10.0 升级: 直接替换 jar。存储格式没动,存档、好友、聊天记录、笔记、买过的 App、手机里的唱片与终端全部原样保留。
📱 手机物品换成 3D 模型,开着的时候屏幕是亮的
背包里那张 32×32 的平面小图退休了,换成一部真正的手机:铝框、圆角、磨砂玻璃背面,四十九个方块拼出来的,共用一张 128×128 贴图(一条色板加一块屏幕)。
屏幕会亮:手机界面开着的时候(全屏那副面孔,或者挂在副手 HUD 上的那部),那部手机的屏幕是白的;界面一关就回到黑屏。第三人称下最看得出来。
服务器上所有人都看得见。 手机界面本来是纯客户端的,服务端根本不知道谁开着手机,所以这一版补了一条链:客户端在开机、关机、手机在身上换了地方这三下各报一次(不轮询——手机的"生"和"死"各只有一个收口);服务端把状态写进物品堆上的组件;组件随手持物品同步给所有看得见这只手的人。于是别人手里那部亮着,你也看得见。
只对拿在手上的那部生效。 手机在背包里、饰品栏里的时候,那件物品在别人眼里根本不渲染,点亮它谁也看不见——所以那种情况客户端连包都不发,服务端也不认。
那个组件只同步、不落盘:开着手机时崩溃或退出,不会留下一部永远亮着的手机——重进世界它自己就灭了。
只有正开着的那一部会亮。地上掉着的、箱子里的、身上带的另一部,都还是黑屏。
资源包作者:模型在 assets/mcphone/models/item/phone_black.json 与 phone_white.json,贴图 textures/item/device_black.png / device_white.png,切换的那条 override 写在 models/item/phone.json 上,判断键是 mcphone:screen_on(1 = 亮)。另外还随包附了两个平板模型(tablet_black / tablet_white),目前没有物品用它们,先放着。
⚡ 快捷键:中间那一步没了
给 App 绑了快捷键之后,按下去是先开机、再进那个 App。画在手机屏幕里的 App(记事本、聊天、天气……)没问题,那一页本来就在手机里。但界面根本不在手机里的那几个——终端、末影箱、传送石、任务书、浏览器、相机——玩家会先看见手机弹出来,然后才被真正的界面顶掉:自己开界面的那几个是闪一帧,发包的那几个更久(界面得等服务端把容器开回来才换,联机再加一个来回)。
这一版这几个 App 不再先开机,按一下直接就是那个界面。手机仍然要带在身上——手机是那台设备,锁在箱子里按一下键不该开出终端来。
一个附带的小变化:快捷键开的浏览器关掉后回到游戏,而不是回到手机(它下面本来就没有手机了)。从手机里点开的那条路不变,照样回得去。
附属 App 也能享受:覆盖一句 opensInsidePhone() 返回 false 即可,方法自己的文档里写清了什么时候该覆盖。不覆盖的话行为和以前一模一样,默认是 true。
🔌 装进卡槽的终端由手机供电,一直是满的
不然这个卡槽是负资产:世界里的充电器够不着卡槽,没电了只能取出来、充完再装回去,而没电的终端连开都开不了——装进手机反倒比揣在背包里麻烦。所以电这件事手机管了:打开终端的那一刻补满,之后只要还有界面开着就每秒补一次。界面全关着的时候不补,那时候电量本来就不会变(AE2 只在菜单开着时扣,RS 是按操作扣)。
只有电这一件事是我们管的。 范围、维度、绑的是哪个网络、增幅卡加了多远,一条都没动,仍旧是 AE2 / RS 自己查、自己拒绝、自己给你发消息。充电走的也是它们自己给终端注册的那份能量能力,和把终端放进充电器里充是同一条路,我们没有碰它们的菜单。
它不是无限发电机:充进去的电取不回来——AE2 与 RS 的那两份实现都不允许外部抽电(canExtract() 恒为 false,AE2 的 extractEnergy 方法体就是一句 return 0),拿终端当电池这条路不通。
Tom's 无事发生,它的终端本来就不用电。
不想要就关:serverconfig/mcphone-server.toml 里的 terminalKeepPowered = false,关掉之后卡槽里的终端和拿在手上完全一样,该耗多少耗多少。
🩹 顺手修的
笔记里写的字,界面放大之后看不见了。 和 1.9.3 那个"界面放大后文字被裁掉"是同一个根因,只是这回踩坑的不是我们的页面、是原版控件自己:多行输入框的正文是它在自己内部 enableScissor 起来画的,而原版那句不看手机这层缩放。界面大小 150% 时正文顶上三行没了、每行左右还各少一截,三行以内的笔记于是"打完字什么都没出现";200% 吃掉前四行,300% 吃掉前六行。反过来倍数小于 100% 时框比控件大,滚动的正文会溢到框外。
笔记内容一直都在,只是没被画出来——存在服务端的正文一个字都没少,这一版打开就看得见,不用重写。
顺带:修好的那个替身 PhoneMultiLineEditBox 放进了 API(api.client.ui),附属直接 new 出来就能用——原版 MultiLineEditBox、以及任何 AbstractScrollWidget 的子类,摆进手机都会踩同一个坑,而那两句夹在父类方法正中间,附属自己改不到。
顺带修了个一直没生效的判断:MCphoneApi.VERSION 是编译期常量,Java 会把它内联进附属自己的字节码——VERSION >= n 判断到的是附属编译时看到的 MCphone,不是运行时真正装着的那个,两个方向都会错(拿新版编装到旧版上照样进 if,拿旧版编装到新版上永远进不去)。现在这个值改在静态块里赋,它不再是常量,读它的地方编出来的是 getstatic、运行时才解析。字段名和用法都没变,只有【重新编译过的】附属享受得到;在那之前编出去的那些,值已经烧死在它们自己的字节码里,救不回来。这条坑从 1.2.12 就在,只是一直没人真的跨版本试过。
给开发者
API 代号升到 2:api.client.ui 里多了一个 PhoneMultiLineEditBox——放得进手机的多行输入框,构造函数与原版 MultiLineEditBox 逐字相同,只把它自己那句裁剪换成了认 pose 的那一句(就是上面"顺手修的"那一条)。附属直接 new 出来、每帧 box.render(canvas.graphics(), ...) 画一次即可,不用把 PhoneCanvas 交给它,缩放是它自己从变换矩阵里读的。要判断这个类在不在,用 MCphoneApi.VERSION >= 2——注意那个判断是这一版才真的生效的(见上一条),拿旧版编出去的附属读到的仍是烧死在自己字节码里的旧值。同属代号 2 的还有 IPhoneApp.opensInsidePhone()(快捷键那一条),它是 default 方法,不判断也安全。
「终端」那三家的接入写在 docs/terminal-integration.md:查实过的 API 入口表(全是 javap 出来的,不是抄文档)、每一家那条"错了不报错"的坑、许可表、测试清单,以及想再加一家要做什么。加一家的代价是 feature/terminal/integration/ 下一个包加一行 isLoaded。
这一格原来是个独立附属(november521/mcphone-terminal,只发过 v0.3.0),这一版并了进来。理由:本体自己早就在做同一件事——传送石靠 Waystones、任务书靠 FTB Quests、阅读靠 Patchouli、浏览器靠 MCEF,"装了 X 就多一格"在这个仓库里的既定形态就是内建 App 加可选依赖。那个仓库已归档,v0.3.0 的 Release 留着不删。
This mod has no additional files

