User Tools

Site Tools


zh_cn:tutorial:enum_adding

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
zh_cn:tutorial:enum_adding [2021/10/10 01:33] – created solidblockzh_cn:tutorial:enum_adding [2022/08/18 02:37] (current) – removed solidblock
Line 1: Line 1:
-====== 添加到枚举 ====== 
  
-===== 介绍 ===== 
-要恰当地添加到枚举,我们需要编辑一些内部字段。不确保这应用于所有的 Java 版本。因为确保正确地添加到枚举是十分重要的,比如,如果你需要制作盔甲,你不应该添加到 ''ArmorMaterials'' 而应该制作自己的类([[armor]])。你还需要注意,如果你的目标枚举用在 switch 语句中,应该停止这样做以避免出问题(你应该总是确保所有的用例都包括进去了)。如果某些原因不起作用了,并不惊讶。可能是一些小东西或者整个概念都被改变了。这里,我们以添加美西螈变种为例子,不过,概念应该可以应用于你 mixin 的任何枚举。 
- 
-===== 创建容器类 ===== 
-这样做的目的是包含你的所有自定义枚举项。项会包含在静态的**非**常量字段中。 
-<code java> 
-public class CustomAxolotlVariant { 
-    static { 
-        AxolotlEntity.Variant.values(); // 确保类在访问变种之前就加载了 
-    } 
-     
-    public static AxolotlEntity.Variant PURPLE; // 你可以随便添加几个字段 
-} 
-</code> 
- 
-===== 往目标中 mixin ===== 
-如果你要往枚举中添加,建议你了解 mixin 的基本原理。 
- 
-==== 访问构造器 ==== 
-我们需要构造器的调用器。前两个参数永远是内部名称和id。然后,我们有可见构造器的参数。 
-<code java> 
-@SuppressWarnings("InvokerTarget") 
-@Invoker("<init>") 
-private static AxolotlEntity.Variant newVariant(String internalName, int internalId, int id, String name, boolean natural) { 
-    throw new AssertionError(); 
-} 
-</code> 
- 
-==== 访问值字段 ==== 
-如果我们处理一个 Minecraft 类,则字段名称会是中间映射。要查找其名称我们需要查看字节码。要查看字节码,可以将鼠标指针指向这个类,然后到视图 -> 查看字节码。向下滚动,直到看到像这样的一行: 
-<code java> 
-private final static synthetic [Lnet/minecraft/entity/passive/AxolotlEntity$Variant; field_28350 
-</code> 
-这意味着,在这个例子中,字段名称是 ''field_28350''。然后我们将其 shadow: 
-<code java> 
-@SuppressWarnings("ShadowTarget") 
-@Shadow 
-@Mutable 
-private static @FinalAxolotlEntity.Variant[] field_28350; 
-</code> 
- 
-==== 注入项 ==== 
-We are going inject after the values field is assigned. To do this we need the correct target for the for the ''INVOKE'' injection point. We can't use MCDev since we are dealing with internals so we need to type it ourselves as such: 
-''<classname><fieldname>:[<classname>'' 
-In our case it would be ''Lnet/minecraft/entity/passive/AxolotlEntity$Variant;field_28350:[Lnet/minecraft/entity/passive/AxolotlEntity$Variant;'' 
-Now we can create the inject: 
-<code java> 
-@SuppressWarnings("UnresolvedMixinReference") 
-@Inject(method = "<clinit>", at = @At(value = "FIELD",  
-        opcode = Opcodes.PUTSTATIC,  
-        target = "Lnet/minecraft/entity/passive/AxolotlEntity$Variant;field_28350:[Lnet/minecraft/entity/passive/AxolotlEntity$Variant;",  
-        shift = At.Shift.AFTER)) 
-private static void addCustomVariant(CallbackInfo ci) { 
- 
-} 
-</code> 
-Now finally we can add our entries: 
-<code java> 
-var variants = new ArrayList<>(Arrays.asList(field_28350)); 
-var last = variants.get(variants.size() - 1); 
- 
-// This means our code will still work if other mods or Mojang add more variants! 
-// Repeat this section if you need more than one entry. Just remember to have unique ordinals! 
-var purple = newVariant("PURPLE", last.ordinal() + 1, last.getId() + 1, "purple", true); 
-CustomAxolotlVariant.PURPLE = purple; 
-variants.add(purple); 
- 
-field_28350 = variants.toArray(new AxolotlEntity.Variant[0]); 
-</code> 
- 
-===== 访问项 ===== 
-要访问枚举项,只需要从容器类中获得字段,比如: 
-<code java> 
-System.out.println(CustomAxolotlVariant.PURPLE); 
-</code> 
- 
- 
-本教程基于lamalad的[[https://gist.github.com/LlamaLad7/0b553d5ae04e4eb44d3a1e8558be9151|此gist]]。翻译自[[tutorial:enum_adding]]。 
zh_cn/tutorial/enum_adding.1633829596.txt.gz · Last modified: 2021/10/10 01:33 by solidblock