Minecraft 1.19.2 Forge模组开发 11.Mixin

news2024/9/21 2:56:50

我们本次使用Mixin在1.19.2中制作一个属于自己的不死图腾。

在这里插入图片描述

演示效果 演示效果 演示效果

什么是Mixin?

简单来说是通过注入一些我们的代码,达到对MC原版内容的修改。

详细内容可以参考Minecraft 17.1 Mixin

1.首先我们需要在开发包中引入mixin的依赖,来到项目的build.gradle文件:

build.gradle

plugins {
    id 'eclipse'
    id 'maven-publish'
    id 'net.minecraftforge.gradle' version '5.+'
    //引入这个mixin依赖
    id 'org.spongepowered.mixin' version '0.7-SNAPSHOT'
}

version = "1.2.8-1.19"
group = "com.joy187.re8joymod"
archivesBaseName = "joy187"

java.toolchain.languageVersion = JavaLanguageVersion.of(17)

sourceSets.main.resources { srcDir 'src/generated/resources' }

//设置你的mixin源文件名称
mixin {
    add sourceSets.main, "re8.refmap.json"
}

minecraft {
    mappings channel: 'official', version: '1.19'

    accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') // Currently, this location cannot be changed from the default.

    runs {
        client {
            workingDirectory project.file('run')
            property 'mixin.env.disableRefMap', 'true'
            property 'mixin.env.refMapRemappingFile', "${projectDir}/build/createSrgToMcp/output.srg"
            property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'
            property 'forge.logging.console.level', 'debug'
            //客户端中指定你资源包中的mixin文件
            arg '-mixin.config=re8.mixins.json'
            
            mods {
                re8joymod {
                    source sourceSets.main
                }
            }
        }

        server {
            workingDirectory project.file('run')
            property 'mixin.env.disableRefMap', 'true'
            property 'mixin.env.refMapRemappingFile', "${projectDir}/build/createSrgToMcp/output.srg"
            property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'
            property 'forge.logging.console.level', 'debug'
            //服务端中指定你资源包中的mixin文件
            arg '-mixin.config=re8.mixins.json'
            mods {
                re8joymod {
                    source sourceSets.main
                }
            }
        }

        data {
            workingDirectory project.file('run')
            property 'mixin.env.disableRefMap', 'true'
            property 'mixin.env.refMapRemappingFile', "${projectDir}/build/createSrgToMcp/output.srg"
            property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'
            property 'forge.logging.console.level', 'debug'
            args '--mod', 're8joymod', '--all', '--output', file('src/generated/resources/')
            //数据包中指定你资源包中的mixin文件
            arg '-mixin.config=re8.mixins.json'
            mods {
                re8joymod {
                    source sourceSets.main
                }
            }
        }
    }
}

repositories {
    mavenLocal()
    maven {
        url "https://www.cursemaven.com"
    }
    maven {
        name "Progwml6 maven"
        url "https://dvs1.progwml6.com/files/maven/"
    }
    maven { url 'https://dl.cloudsmith.io/public/geckolib3/geckolib/maven/' }
//    maven {
//        name "ModMaven"
//        url "https://modmaven.k-4u.nl"
//    }
    maven {
        name = "Curios API"
        url = "https://maven.theillusivec4.top/"
    }
}

dependencies {
    minecraft 'net.minecraftforge:forge:1.19.2-43.1.1'

    implementation fg.deobf('curse.maven:framework-549225:3873800')
    implementation fg.deobf('curse.maven:mrcrayfishs-gun-mod-289479:3874034')
    implementation fg.deobf('software.bernie.geckolib:geckolib-forge-1.19:3.1.36')
    compileOnly fg.deobf("mezz.jei:jei-1.19-common-api:11.0.0.211")
    compileOnly fg.deobf("mezz.jei:jei-1.19-forge-api:11.0.0.211")

    runtimeOnly fg.deobf("top.theillusivec4.curios:curios-forge:1.19.2-5.1.1.0")
    compileOnly fg.deobf("top.theillusivec4.curios:curios-forge:1.19.2-5.1.1.0:api")

    runtimeOnly fg.deobf("mezz.jei:jei-1.19-forge:11.0.0.211")
    
    //这里引入mixin依赖
    annotationProcessor 'org.spongepowered:mixin:0.8.5:processor'
}

jar {
    manifest {
        attributes([
                "Specification-Title": "Resident Evil 8 mod",
                "Specification-Vendor": "Joy187",
                "Specification-Version": "1",
                "Implementation-Title": "Resident Evil 8 mod",
                "Implementation-Version": project.version,
                "Implementation-Vendor" : "Joy187",
                //"Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
                //你资源包中的mixin配置文件
                "MixinConfigs": "re8.mixins.json"
        ])
    }
}

jar.finalizedBy('reobfJar')

tasks.withType(JavaCompile).configureEach {
    options.encoding = 'UTF-8'
}

publishing {
    publications {
        mavenJava(MavenPublication) {
            artifact jar
        }
    }
    repositories {
        maven {
            url "file:///X:/localmaven/mcmods"
        }
    }
}

之后选择刷新gradle项目:

cr0.jpg

2.重新构建完成后我们在资源包中新建一个我们的mixin文件,文件名称与上面"MixinConfigs"字段填写的名称一样:

cr1.jpg

之后在文件中写一些内容:

re8.mixins.json

{
    "required": true,
    "package": "com.joy187.re8joymod.mixin",
    "compatibilityLevel": "JAVA_8",
    "minVersion": "0.8",
    "refmap": "re8.refmap.json",
    "plugin": "com.joy187.re8joymod.mixin.MixinPlugin", //注意这个地址
    "mixins": [

    ],
    "client": [

    ],
    "injectors": {
        "defaultRequire": 1
    }
}

3.来到Java包中,在上一步中我们声明了一个plugin地址,按照这个路径创建一个MixinPlugin文件,作为模组的mixin启动器:

cr2.jpg

MixinPlugin.java

package com.joy187.re8joymod.mixin;

import org.objectweb.asm.tree.ClassNode;
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;

import java.util.List;
import java.util.Set;

public class MixinPlugin implements IMixinConfigPlugin{
    private boolean isFrameworkInstalled;
    @Override
    public void onLoad(String mixinPackage) {
        try {   
            //这个字符串对应你的项目主类
            Class.forName("com.joy187.re8joymod.Main", false, this.getClass().getClassLoader());
            isFrameworkInstalled = true;
        } catch (Exception e) {
            isFrameworkInstalled = false;
        }
    }

    @Override
    public String getRefMapperConfig() {
        return null;
    }

    @Override
    public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
        return isFrameworkInstalled; // this makes sure that forge's helpful mods not found screen shows up
    }

    @Override
    public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) {

    }

    @Override
    public List<String> getMixins() {
        return null;
    }

    @Override
    public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {

    }

    @Override
    public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {

    }
}

之后我们在同样的包中新建一个LivingEntityMixin类,作为我们的注入类:

LivingEntityMixin.json

package com.joy187.re8joymod.mixin;

import com.joy187.re8joymod.init.ItemInit;
import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.stats.Stats;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

@Mixin(LivingEntity.class)
public abstract class LivingEntityMixin {

    //这里我们将代码注入到checkTotemDeathProtection中,注入位置是其HEAD头部
    @Inject(method = {"checkTotemDeathProtection"}, at = {@At("HEAD")}, cancellable = true)
    private void checkTotemDeathProtection(DamageSource source, CallbackInfoReturnable<Boolean> info) {
        LivingEntity livingEntity = ((LivingEntity)(Object)this);
        if (livingEntity instanceof ServerPlayer player) {
            ItemStack itemStack = null;
            Inventory inventory = player.getInventory();
            //在背包中找到我们的物品
            for (int i = 0; i < inventory.getContainerSize(); i++) {
                ItemStack stack = inventory.getItem(i);
                if (stack.getItem().equals(ItemInit.BODYGUARD.get())) {
                    itemStack = stack;
                    break;
                }
            }
            //如果找到了,当我们陷入濒死之时就会使用该物品并给予玩家一个15s的生命回复效果
            if (itemStack != null) {
                player.awardStat(Stats.ITEM_USED.get(ItemInit.BODYGUARD.get()));
                CriteriaTriggers.USED_TOTEM.trigger(player, itemStack);
                itemStack.shrink(1);
                player.setHealth(10.0F);
                player.removeAllEffects();
                player.addEffect(new MobEffectInstance(MobEffects.REGENERATION, 300, 1));
                player.level.broadcastEntityEvent(player, (byte) 35);
                info.setReturnValue(true);
            }
        }
    }
}

把这个类的名称放入我们之前资源包中的注入文件中:

re8.mixins.json

{
    "required": true,
    "package": "com.joy187.re8joymod.mixin",
    "compatibilityLevel": "JAVA_8",
    "minVersion": "0.8",
    "refmap": "re8.refmap.json",
    "plugin": "com.joy187.re8joymod.mixin.MixinPlugin",
    "mixins": [
        "LivingEntityMixin" //放在这里
    ],
    "client": [

    ],
    "injectors": {
        "defaultRequire": 1
    }
}

4.在ItemInit中注册我们的物品,作为图腾使用:

ItemInit.java

    public static final RegistryObject<Item> BODYGUARD = register("bodyguard",
            () -> new Item(new Item.Properties().tab(Main.TUTORIAL_TAB)));

在资源包中物品的名称、模型、贴图文件。

en_us.json

	"item.re8joymod.bodyguard":"Crystal",

模型文件

bodyguard.json

{
  "parent": "item/generated",
  "textures": {
    "layer0": "re8joymod:item/bodyguard"
  }
}

贴图文件

在这里插入图片描述

5.启动游戏调试

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/172107.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度学习——双向循环神经网络(笔记)

双向循环神经网络&#xff1a; ①对于序列来讲&#xff0c;假设的目标是&#xff1a;给定观测的情况下&#xff08;在时间序列的上下文或语言模型的上下文&#xff09;&#xff0c;对于下一个输出进行建模 ②对于序列模型来讲&#xff0c;可以从前往后看&#xff0c;也可以从…

Servlet基础

Servlet1. Servlet概述2. 快速入门3. 执行原理4. 生命周期方法5. Servlet3.06. 体系结构7. 相关配置8. HTTP8.1 概念8.2 Request8.3 Response8.4 ServletContext综合案例:文件下载&#xff1a;1. Servlet概述 Servlet是JavaEE规范(接口)之一Servlet是JavaWeb三大组件之一&…

使用sdk-npi-enablement-tool生成SVD文件和芯片头文件

使用sdk-npi-enablement-tool生成SVD文件和芯片头文件 文章目录使用sdk-npi-enablement-tool生成SVD文件和芯片头文件IntroductionOverviewOperation Steps创建芯片配置文件yaml填充外设模块的寄存器映射描述文件xlsx验证生成芯片头文件ConclusionIntroduction 芯片验证与测试…

【Linux杂篇】Linux系统终端常用配置文件更改

目录列表&#xff1a; 1.alias别名永久保存 2.解决vim文件没有颜色的问题 3.vim插件supertap插件安装&#xff08;可支持自动补全&#xff0c;非函数代码补全&#xff0c;仅支持在当前编辑文档内补全&#xff09; 4.vim插件管理 5.YCM下载 6.解决vim中使用backspace无法删…

windows安装npm和cnpm

npm: 代码的包管理器&#xff0c;但是服服器在国外&#xff0c;每一次启动项目都要下载一些依赖&#xff0c;耗时之久&#xff0c;官网下载链接戳 npm。 cnpm&#xff1a;这是淘宝团队出的npm的镜像&#xff0c;可用此代替官方的只读版本&#xff0c;官网链接 cnpm。 先安装np…

Redis6学习笔记【part3】配置文件与订阅/发布

一.Redis配置文件 1.Units单位 配置大小单位,开头定义了一些基本的度量单位&#xff0c;只支持bytes&#xff0c;不支持bit。其中 GB、Gb 大小写不敏感。 2.Include包含 类似 jsp 中的 include 引入公共页面 &#xff0c;redis 在多实例的情况也可以把公用的配置文件提取出来…

9 大指标分析 Solana 的熊市危机

Daniel, 2023 年 1 月Solana 是一个去中心化的区块链网络&#xff0c;由 Solana 实验室设计并在2020年推出&#xff0c;具有快速、可扩展和安全的特点。由于其快速的交易速度和低交易费用&#xff0c;Solana 在 2020 年和 2021 年获得了极大的关注&#xff0c;这使得它对去中心…

远程仓库操作

添加远程仓库 新建一个文件夹&#xff1a; 文件夹右键打开git bash: 初始化为git仓库&#xff1a; 在码云上新建一个git仓库&#xff1a; 复制链接&#xff1a; 在文件夹里使用git bash&#xff1a; git remote add<shortname><url> 添加一个新的远程仓库&…

制作tomcat的docker镜像

环境信息&#xff1a;MacBook Pro&#xff08;M1&#xff09;VMware-fusion(Player 版本 13.0.0 (20802013))Ubuntu 22.10tomcat镜像&#xff1a;centos-7.9.2009jdk1.8.0_341 apache-tomcat-8.5.84制作步骤&#xff1a;&#xff08;1&#xff09;下载好tomcat/jdk(我是在macbo…

学习react

这里写自定义目录标题学习React学习React 安装react的脚手架 npm i create-react-app -g通过脚手架创建demo D:\dev_project>create-react-app react-demo You are running Node 11.1.0. Create React App requires Node 14 or higher. Please update your version of No…

找不到合适好用的redis客户端工具?试试官方的客户端工具RedisInsight

这里是weihubeats,觉得文章不错可以关注公众号小奏技术&#xff0c;文章首发。拒绝营销号&#xff0c;拒绝标题党 背景 之前使用的redis客户端工具是AnotherRedisDesktopManager AnotherRedisDesktopManager github地址: https://github.com/qishibo/AnotherRedisDesktopManag…

千锋JavaScript学习笔记

千锋JavaScript学习笔记 文章目录千锋JavaScript学习笔记写在前面1. JS基础1.1 变量1.2 数据类型1.3 数据类型转换1.4 运算符1.5 条件1.6 循环1.7 函数1.8 对象数据类型1.9 数组和排序1.10 数组常用方法&#xff1a;1.11 字符串常用方法1.12 数字常用方法1.13 时间常用方法1.14…

九龙证券|三元锂离子电池和磷酸铁锂离子电池的特点和优劣势详解

动力蓄电池包括锂离子动力蓄电池、金属氢化物/镍动力蓄电池等。锂离子动力蓄电池一般简称为锂离子电池&#xff0c;锂离子电池是新能源轿车动力锂电池的重要品类&#xff0c;商场占有量也是最大的。新能源轿车商场上&#xff0c;锂离子电池常见的是磷酸铁锂离子电池和三元锂离子…

《图解HTTP》读书笔记

第一章、了解Web及网络基础 HTTP&#xff1a;HyperText Transfer Protocol&#xff0c;超文本传输协议。 HTML&#xff1a;HyperText Markup Language&#xff0c;超文本标记语言。 URL&#xff1a;Uniform Resource Locator&#xff0c;统一资源定位符。 把与互联网相关联的…

SQL题面试题

有3个表S(学生表)&#xff0c;C&#xff08;课程表&#xff09;&#xff0c;SC&#xff08;学生选课表&#xff09; S&#xff08;SNO&#xff0c;SNAME&#xff09;代表&#xff08;学号&#xff0c;姓名&#xff09; C&#xff08;CNO&#xff0c;CNAME&#xff0c;CTEACHER&…

SQL同时在线问题的解法

前言 同时在线相关的问题&#xff0c;在很多行业中也经常出现&#xff0c;比如&#xff1a; 统计同时最大主播数量统计同时最大在线人数统计同时最大打车人数… 很多人看到这类题&#xff0c;一脸懵逼&#xff0c;甚至连题意都看不懂&#xff0c;但是这道题是面试题中的常客&a…

SAP FICO CO-PA(获利分析会计)简介

一、概念信息 1、目标 CO-PA的目标&#xff1a;确定市场段的获利能力。 其中市场段就是一些指标的组合&#xff0c;比如客户A&#xff0c;加上产品&#xff11;就可以是一个获利分析段。 分析各个获利分析段的贡献边际&#xff0c;为后续销售决策提供支持&#xff08;主要与…

4、PyCharm中配置PyQt5-tools

1、 配置Qt Designer Workint directory&#xff1a;$FileDir$ 2、配置PyUIC Arguments&#xff1a;$FileName$ -o $FileNameWithoutExtension$.py Workint directory&#xff1a;$FileDir$ 3、配置PyRcc Arguments&#xff1a;$FileName$ -o $FileNameWithoutExtension$_rc.…

Linux常用命令——time命令

在线Linux命令查询工具(http://www.lzltool.com/LinuxCommand) time 统计给定命令所花费的总时间 补充说明 time命令用于统计给定命令所花费的总时间。 语法 time(参数)参数 指令&#xff1a;指定需要运行的额指令及其参数。 实例 当测试一个程序或比较不同算法时&…

【进阶】Spring Boot配置文件(.properties提示有问题版)

努力经营当下&#xff0c;直至未来明朗&#xff01; 文章目录一、配置文件作用二、配置文件的格式三、properties配置文件说明1. properties 基本语法2. 读取配置文件3. properties缺点分析四、 yml配置文件说明1. yml基本语法2. yml使用进阶3. 注意&#xff1a;value值加单双引…