跳转至内容
  • 论坛Tag征求

    壁画石窟 kubejs 渲染 数据包 世界生成 物品 实体 附魔
    4
    0 赞同
    4 帖子
    154 浏览
    Y
    tooltip 可以改成提示框或物品提示 https://zh.minecraft.wiki/w/提示框
  • [1.21.1 KubeJS7]如何更好的用指令去执行KubeJS代码

    魔改早教
    2
    2 赞同
    2 帖子
    202 浏览
    不是客服M
    o.O要长脑袋了
  • [1.21.1 KubeJS7]mcef与KubeJS交互(踩坑经验)

    魔改早教
    1
    0 赞同
    1 帖子
    160 浏览
    zhenshizZ
    本帖子用到的模组 kubejs-neoforge-2101.7.1-build.181 rhino-2101.2.7-build.74 mapperplugin-1.5.0 后文中称其为mp mcef-neoforge-2.1.6-1.21.1 本帖子用到的前端技术栈 Vue3+Vite+VueRouter 作用 可以做出更好看的gui界面来实现玩家的操作交互,而不用受限于Java写gui来折磨自己 通过gui和KubeJS的双向通信可以实现更多的操作和功能 问答 问:我该如何让mc打开vue项目中的页面 答:将vue项目打包(npm run build)出压缩文件后调用打包文件(dist)中的index.html文件。 问:我该如何用mp调用打包后的html里的路由页面 答:在router配置中设置hashHistory,使用项目文件名/dist/index.html#/路由名来打开对应的路由页面 [image: 1753107069789-a75529e7-2dd1-4dc1-ac6e-1fcf1a79fd71-image.png] 问:我浏览器预览的页面和mc里预览的gui效果并不一致,而且放大放小窗口字的大小也会变化的很大 答:不要使用px作为元素的宽高,字的大小,使用vh,vw这种百分比参数来适配,在mc设置中的尺寸大小使用自动而不是固定一个大小 问:我该如何让页面和kjs进行交互 答:浏览器中使用文档1中对于mp:gui中浏览器部分调用指令的功能,指令使用我之前教程中eval指令来调用kjs方法即可。kjs可以通过mp自带的指令和api去调用网页中写好的方法并传递方法里的参数 问:我打包后的方法名被混淆了,kjs调用不到咋办 答:在vue文件中将不想混淆的文件塞到window中即可。你可以在那个方法里添加一个id,让kjs中传递这个id去网页中实现不一样的效果,目的是为了大量减少塞到window里的屎 [image: 1753107661018-30473f23-be3e-41cc-8f08-026d2e5f1605-image.png] 参考文献 文档1:https://doc.mafuyu.moe MapperPlugin教程
  • 论坛似了,对吗

    壁画石窟
    4
    0 赞同
    4 帖子
    151 浏览
    忆然
    会赢的
  • 呜,苦路西

    壁画石窟
    3
    0 赞同
    3 帖子
    97 浏览
    初见
    呜呜呜
  • 想被谜题羊狠狠厚乳喵🥵

    壁画石窟
    1
    0 赞同
    1 帖子
    66 浏览
    半梦
    🥵🥵🥵
  • 我下辈子不碰Network!!!!!

    壁画石窟
    4
    0 赞同
    4 帖子
    88 浏览
    不是客服M
  • [原创]在MC中如何使用简单的着色器

    魔改早教 渲染
    3
    1 赞同
    3 帖子
    201 浏览
    真冬M
    @mihono 例子里的效果就是屏幕色彩亮度提高50%
  • 在这测试一下各种功能

    壁画石窟
    11
    0 赞同
    11 帖子
    219 浏览
    不是客服M
  • [原创][KubeJS]利用事件监听制作弹幕武器

    灵感大王 kubejs
    7
    3 赞同
    7 帖子
    318 浏览
    不是客服M
    flowchart TD A((玩家空挥)) --> B{是否为特定武器} B -->|是| C["计算发射数据 发包服务端<br/>(坐标,弹幕实体id)"] B -->|不是| D["服务端生成相应弹幕"] C --> D D --> E((结束))
  • [原创][KubeJS 6] 物品投射实现飞剑

    灵感大王 kubejs entityjs
    2
    3 赞同
    2 帖子
    110 浏览
    不是客服M
    cool
  • [原创][数据包][持续更新]NuQuest模组中的对话框使用示例

    妙妙工具
    1
    0 赞同
    1 帖子
    133 浏览
    昨天没做东西,今天也没K
    很多人在催这玩意,但是也有人不知道这玩意怎么用,那我今天来教教大家吧。 数据包路径 关于数据包的路径存放 目前的路径是在nu_quest/dialog下的 完整路径就是data/nu_quest/dialog 代码会自动检测这个路径下的全部文件,包括子文件夹,所以大可放心整理问题。 编写数据包 那现在我们就来介绍如何写对话了 { "dialogueId": "intro", "dialogTexts": [ { "title": "dialog.nuquest.intro.title", "text": "dialog.nuquest.intro.text", "imageGroup": { "image": "foo:textures/gui/npc.png", "x": "0", "y": "(screenheight / 3 * 2) - 64", "width": 64, "height": 64, "uOffset": 0, "vOffset": 0, "uWidth": 64, "vHeight": 64, "textureWidth": 64, "textureHeight": 64 }, "soundGroup": { "sound": "minecraft:entity.villager.yes", "volume": 1.0, "pitch": 1.0 }, "textEffect": { "name": "typewriter" }, "params": { "speed": 2 } } ], "dialogActionDatas": [ { "message": "dialog.nuquest.intro.continue", "action": { "name": "dialog", "params": { "dialogId": "foo:intro_2" } } }, { "message": "dialog.nuquest.intro.exit", "action": { "name": "close" } } ] } 这是目前对话中可用的全部功能 在最外级的json元素中主要有三个,分别是dialogueId,dialogTexts,dialogActionDatas dialogueId定义了这个动画的id名,调用时也是通过id名来查找,而dialogTexts是一个列表,里面存放了对话的文本内容,dialogActionDatas是选项按钮,在对话文字全部播放完后则会出现。
  • 0 赞同
    11 帖子
    475 浏览
    不是客服M
    Override被爆掉确实很奇怪…
  • [模组推荐]在进入游戏的时候从网上获取信息展示

    壁画石窟
    1
    3 赞同
    1 帖子
    148 浏览
    忆然
    本文使用:CC-BY-NC-SA 4.0协议 使用的mod为[YiRanVersionCheck] 实际上就是在推荐我自己的mod 这个mod会在进入游戏的时候访问指定的链接并在聊天栏提示你其中的文本 使用实例: [image: 1748268457072-6f4a9e31-ca60-4fb0-870a-55584bdd07d0-image.png] 如何使用? 首先你需要开通一个gitee仓库 github也行,但不一定好访问 在里面创建一个纯文本文件 建议使用log后缀 本文使用的例子为 https://gitee.com/bakayiran/mmrryyhh/blob/master/test.txt 本整合包免费发布,私自贩卖不得好死 目前最新版本:§61.0.0-hotfix 当前版本:§6${version} 链接:[[§b§n获取最新信息§r]](https://gitee.com/bakayiran/mmrryyhh/edit/master/test.txt) 若在游玩整合包遇到问题请先在[§b§n百科](https://www.mcmod.cn/)寻求答案 可以灌注下[§b§n作者(B站)](https://www.bilibili.com/)吗OVO 文本中的${version}会被替换成config里面的版本 string则会解析为一个可点击,点击打开指定的链接 一行目前只能存在一个可点击文本 配置文件: #在这里填入URL checkUrl = "https://gitee.com/bakayiran/mmrryyhh/blob/master/test.txt" #在这里填入次要URL secondaryCheckUrl = "null" #当前版本 version = "0.1.0" 本mod会先尝试从主要链接获取文本,失败则会尝试次要链接 你也可以使用kjs修改配置文件 //在Startup,当然你也可以放client ClientEvents.init(event => { let $Config = Java.loadClass("com.yiran.versioncheck.Config") $Config.VERSION.set("0.1.0") $Config.CHECK_URL.set("https://gitee.com/bakayiran/mmrryyhh/blob/master/test.txt") //$Config.CHECK_URL2.set("null") }) 为什么使用这个mod? 用于告诉整合包玩家目前的整合包版本和现在版本 提供bug反馈链接 用作进入世界的消息提醒 声明整合包免费(倒勾不得好死)
  • 一种基于AND/OR的单个方块状态使用多个模型

    灵感大王
    1
    1 赞同
    1 帖子
    70 浏览
    yizhi9jiyan
    "apply"{"model":"texture_path"} 中model对应的value只能为字符串,且候选模型也只能选择一个模型,这个时候我们就可以使用{ "when":{"AND":[{}]},"apply":{} }来实现(或者把AND换成OR也行)单个方块状态添加第二个模型 示例 Github
  • [原创][KubeJS]简单的以tick实现的嘲讽

    灵感大王 kubejs
    3
    2 赞同
    3 帖子
    86 浏览
    稽塔Gui_tarJ
    我必须先攻击拥有嘲讽的随从
  • [原创][1.21.X][Neoforge][modding]CodecCodec你的!

    已移动 魔改早教 模组开发
    2
    3 赞同
    2 帖子
    217 浏览
    AnNingUIA
    受益颇多
  • 已经,没有modding的理由了

    壁画石窟
    7
    0 赞同
    7 帖子
    93 浏览
    AnNingUIA
  • [原创][KubeJS]kubejs获取玩家所处坐标的结构

    妙妙工具 kubejs
    1
    1 赞同
    1 帖子
    110 浏览
    忆然
    本文使用:CC-BY-NC-SA 4.0协议 直接上代码 在此推荐下来自ZZZank的ProbeJS Legacy (已经支持1.20.1了(喜)) /** * 获取实体坐标的所有结构 * @param {Internal.Entity} entity * @returns {$StructureStart_[]} */ function getAllStructuresAt(entity) { let structureList = [] /**@type {$ServerLevel_} */ let serverLevel = entity.level let entityPos = entity.block.pos /** @type {Internal.Structure[]} */ let structureArray = serverLevel.structureManager().getAllStructuresAt(entityPos).keySet().toArray() for (let structure of structureArray) { let structureStart = serverLevel.structureManager().getStructureAt(entityPos, structure) if (structureStart.isValid()) { structureList.push(structureStart) } } return structureList }
  • [原创][Mod]通过特定格式文字进行查找结构

    妙妙工具 forge mixin
    1
    0 赞同
    1 帖子
    76 浏览
    昨天没做东西,今天也没K
    故事的起因是有帮twf写模组时,需要用到查找结构指令显示坐标给玩家,但是玩家不一定有权限或者ftbq发送并不会sendmessage给玩家,所以有了此代码。 我也将结构查找的功能写成了一个类,可以直接拿去用。 public class StructureLocator { private static final ResourceKey<Registry<ConfiguredStructureFeature<?, ?>>> STRUCTURE_REGISTRY_KEY = Registry.CONFIGURED_STRUCTURE_FEATURE_REGISTRY; /** * 根据单个结构 ResourceLocation(如 "minecraft:village" 或者自定义 mod:id)查找最近的那个点。 * * @param level 当前维度 * @param center 中心搜索点 * @param id 结构的 ResourceLocation * @param radius 搜索半径(方块数) * @param skipKnown 是否跳过已探索过的结构 * @return 如果找到,返回 Pair(结构坐标, Holder<该结构>); 找不到则 empty() */ public static Optional<Pair<BlockPos, Holder<ConfiguredStructureFeature<?, ?>>>> findNearest( ServerLevel level, BlockPos center, ResourceLocation id, int radius, boolean skipKnown ) { Registry<ConfiguredStructureFeature<?, ?>> registry = level.registryAccess().registryOrThrow(STRUCTURE_REGISTRY_KEY); ResourceKey<ConfiguredStructureFeature<?, ?>> key = ResourceKey.create(STRUCTURE_REGISTRY_KEY, id); Holder<ConfiguredStructureFeature<?, ?>> holder = registry.getHolder(key).orElse(null); if (holder == null) return Optional.empty(); HolderSet<ConfiguredStructureFeature<?, ?>> holderSet = HolderSet.direct(holder); Pair<BlockPos, Holder<ConfiguredStructureFeature<?, ?>>> result = level.getChunkSource() .getGenerator() .findNearestMapFeature(level, holderSet, center, radius, skipKnown); return Optional.ofNullable(result); } /** * 根据 TagKey(像 "#minecraft:village")来查找最近的结构。 * * @param level 当前维度 * @param center 中心搜索点 * @param tagKey 结构 TagKey(Registry.CONFIGURED_STRUCTURE_FEATURE_REGISTRY 下的 Tag) * @param radius 搜索半径 * @param skipKnown 是否跳过已探索结构 * @return 如果找到,返回 Pair(结构坐标, Holder<该结构>); 找不到则 empty() */ public static Optional<Pair<BlockPos, Holder<ConfiguredStructureFeature<?, ?>>>> findNearestByTag( ServerLevel level, BlockPos center, TagKey<ConfiguredStructureFeature<?, ?>> tagKey, int radius, boolean skipKnown ) { Registry<ConfiguredStructureFeature<?, ?>> registry = level.registryAccess().registryOrThrow(STRUCTURE_REGISTRY_KEY); HolderSet<ConfiguredStructureFeature<?, ?>> holderSet = registry.getOrCreateTag(tagKey); Pair<BlockPos, Holder<ConfiguredStructureFeature<?, ?>>> result = level.getChunkSource() .getGenerator() .findNearestMapFeature(level, holderSet, center, radius, skipKnown); return Optional.ofNullable(result); } /** * 把查到的结果格式化成一个聊天用的组件(绿色坐标 + 距离)。 * * @param structureName 你想显示的结构名称(如 "minecraft:village" 或 "#minecraft:village") * @param origin 搜索中心 * @param pair findNearest 返回的 Pair * @param translateKey 翻译 key,通常用 "commands.locate.success" */ public static Component formatLocateResult( String structureName, BlockPos origin, Pair<BlockPos, Holder<ConfiguredStructureFeature<?, ?>>> pair, String translateKey ) { BlockPos found = pair.getFirst(); int distance = Mth.floor( dist(origin.getX(), origin.getZ(), found.getX(), found.getZ()) ); MutableComponent coords = ComponentUtils.wrapInSquareBrackets( new TranslatableComponent("chat.coordinates", found.getX(), "~", found.getZ()) ); return new TranslatableComponent( translateKey, structureName, coords, distance ); } private static float dist(int x1, int z1, int x2, int z2) { int dx = x2 - x1, dz = z2 - z1; return Mth.sqrt((float) (dx * dx + dz * dz)); } } 这部分代码就是查找结构有关的类了,通过获取ConfiguredStructureFeature的注册表,然后再获取结构的Holder类,再给ChunkGenerator的findNearestMapFeature方法去获取到BlockPos。 @Mixin(ServerPlayer.class) public class ServerPlayerMixin { @ModifyArg(method = "sendMessage(Lnet/minecraft/network/chat/Component;Lnet/minecraft/network/chat/ChatType;Ljava/util/UUID;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/protocol/game/ClientboundChatPacket;<init>(Lnet/minecraft/network/chat/Component;Lnet/minecraft/network/chat/ChatType;Ljava/util/UUID;)V"), index = 0) public Component modifyMessage(Component component){ MutableComponent mutableComponent = component.copy(); String message = mutableComponent.getString(); ServerPlayer serverPlayer = (ServerPlayer) (Object) this; if (message.contains("<structure>") && message.contains("</structure>")) { String structure = message.replaceAll(".*<structure>(.*?)</structure>.*", "$1"); BlockPos center = serverPlayer.blockPosition(); Optional<Pair<BlockPos, Holder<ConfiguredStructureFeature<?, ?>>>> holderPair = StructureLocator.findNearest( serverPlayer.getLevel(), center, new ResourceLocation(structure), 100, false ); AtomicReference<String> replace = new AtomicReference<>(); holderPair.ifPresentOrElse(pair -> { Component component1 = StructureLocator.formatLocateResult(structure, center, pair, "commands.locate.success"); replace.set(component1.getString()); }, () -> { replace.set(new TranslatableComponent("commands.locate.failed", structure).getString()); }); Style style = component.getStyle(); mutableComponent = new TextComponent(message.replaceAll("<structure>(.*?)</structure>", "§a%s§r".formatted(replace.get()))).withStyle(style); } return mutableComponent; } } 这段mixin则是注入ServerPlayer的sendMessage方法,修改new ClientboundChatPacket(message, type, sender)的message参数,||因为我偷懒,所以没用MixinExtra||,用正则表达式进行匹配到对应的结构格式文字,然后修改原文字中的内容。 这差不多都就是本次代码的全部内容了。