tutorial:mixin_accessors
                Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| tutorial:mixin_accessors [2020/08/29 15:18] – Add how to add ores to the end biomes siglong | tutorial:mixin_accessors [2025/10/17 13:47] (current) – Add warnings for outdated examples, use yarncode plugin for most refs to vanilla code. gauntrecluse | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ====== | + | ====== | 
| - | A lot of mods add their own ores, and you'll need a way to place them in existing biomes for players to find. In this tutorial, we'll look at adding ores to existing biomes. There are 2 steps that are required to add ores to biomes. | + | FIXME //This page is under revison. This page may change suddenly and should be taken with a grain of salt.// | 
| - | * Make a ConfiguredFeatures. | + | |
| - | * Register your feature by using [[tutorial: | + | |
| - | We'll assume you've already created your own ore block at this point. Quartz Ore will serve as our replacement throughout this tutorial. Replace references to Quartz Ore with your ore when appropriate. | + | **Accessor Mixins** are special mixins defined as interfaces which must **only** contain | 
| - | ==== Adding | + | The '' | 
| - | In this section, our goal will be spawning the ore in the overworld. | + | |
| - | === Making a ConfiguredFeatures === | + | Unlike typical injectors, accessors do not prefix the merged methods with the modid of the mod that contains them. Additionally as the **Accessor Mixins** are used in user code, the names of the handlers are not mangled, these differences are important | 
| - | First we need to create a ConfiguredFeatures. Make sure to register your ConfiguredFeature at '' | + | |
| - | <code java [enable_line_numbers=" | + | '' | 
| - | public class ExampleMod implements ModInitializer { | + | |
| - | public static ConfiguredFeature<? | + | |
| - | .configure(new OreFeatureConfig( | + | |
| - | OreFeatureConfig.Rules.BASE_STONE_OVERWORLD, | + | |
| - | Blocks.NETHER_QUARTZ_ORE.getDefaultState(), | + | |
| - | 9)) // vein size | + | |
| - |  | + | |
| - | 0, // bottom offset | + | |
| - | 0, // min y level | + | |
| - | 64))) // max y level | + | |
| - |  | + | |
| - | .repeat(20); | + | |
| - |  | + | ===== Accessor ===== | 
| - | public | + | '' | 
| - |  | + | |
| + | ==== Getting a value from the field ==== | ||
| + | < | ||
| + | @Mixin(class_310.class) | ||
| + | public | ||
| + | @Accessor(" | ||
| + | int modid$getItemUseCooldown(); | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Usage: | ||
| + | |||
| + | < | ||
| + | int field_1752 = ((class_310Accessor) class_310.method_1551()).modid$getItemUseCooldown(); | ||
| + | </ | ||
| + | |||
| + | ==== Setting a value to the field ==== | ||
| + | < | ||
| + | @Mixin(class_310.class) | ||
| + | public interface class_310Accessor | ||
| + |  | ||
| + | void modid$setItemUseCooldown(int field_1752); | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Usage: | ||
| + | |||
| + | < | ||
| + | ((class_310Accessor) class_310.method_1551()).modid$setItemUseCooldown(100); | ||
| + | </ | ||
| + | |||
| + | When the field is final and you need to set it, use '' | ||
| + | |||
| + | ===== Accessor for static fields ===== | ||
| + | FIXME // | ||
| + | Suppose we want to access the '' | ||
| + | |||
| + | ==== Getting a value from the field ==== | ||
| + | <code java> | ||
| + | @Mixin(VanillaLayeredBiomeSource.class) | ||
| + | public interface VanillaLayeredBiomeSourceAccessor { | ||
| + | @Accessor("BIOMES") | ||
| + | static List< | ||
| + | throw new AssertionError(); | ||
| } | } | ||
| } | } | ||
| </ | </ | ||
| - | === Registering the feature === | + | Usage: | 
| - | Vanilla ore features that spawn in the overworld biomes are listed in '' | + | |
| - | <code java [enable_line_numbers=" | + | <code java> | 
| - | @Mixin(DefaultBiomeFeatures.class) | + | List< | 
| - | public | + | </ | 
| - | @Inject(method = "addDefaultOres(Lnet/ | + | |
| - |  | + | ==== Setting a value to the field ==== | 
| - |  | + | <code java> | 
| + | @Mixin(VanillaLayeredBiomeSource.class) | ||
| + | public | ||
| + | @Accessor("BIOMES") | ||
| + | static void modid$setBiomes(List< | ||
| + |  | ||
| } | } | ||
| } | } | ||
| </ | </ | ||
| - | === Result === | + | Usage: | 
| - | You should see quartz ore spawning in the overworld. You can use fill command to remove stone blocks surrounding you like this: ''/ | + | |
| - | {{tutorial: | + | <code java> | 
| + | VanillaLayeredBiomeSourceAccessor.modid$setBiomes(biomes); | ||
| + | </ | ||
| - | ==== Adding | + | When the field is final and you need to set it, use '' | 
| - | In this section, based on the code in the previous section, we will add the ore to the end biomes. | + | |
| - | === Making a ConfiguredFeatures | + | ===== Invoker ===== | 
| - | We replace | + | '' | 
| - | <code java [enable_line_numbers=" | + | <yarncode | 
| - | public class ExampleMod implements ModInitializer { | + | @Mixin(class_1560.class) | 
| - | public static ConfiguredFeature<?, | + | public interface class_1560Invoker { | 
| - | .configure(new OreFeatureConfig( | + | @Invoker(" | 
| - | new BlockMatchRuleTest(Blocks.END_STONE), /* We use endstone! */ | + |  | 
| - | Blocks.NETHER_QUARTZ_ORE.getDefaultState(), | + | |
| - | 9)) | + | |
| - | .decorate(Decorator.RANGE.configure(new RangeDecoratorConfig( | + | |
| - | 0, | + | |
| - | 0, | + | |
| - | 64))) | + | |
| - | .spreadHorizontally() | + | |
| - | .repeat(20); | + | |
| - | + | ||
| - | @Override | + | |
| - | public void onInitialize() { | + | |
| - |  | + | |
| - | } | + | |
| } | } | ||
| - | </code> | + | </yarncode> | 
| - | === Registering the feature === | + | Usage: | 
| - | Considering that no ore is generated in the end biomes on vanilla minecraft, '' | + | |
| - | <code java [enable_line_numbers=" | + | <yarncode | 
| - | @Mixin(DefaultBiomeCreator.class) | + | class_1560 enderman | 
| - | public | + | ((class_1560Invoker) enderman).modid$invokeTeleportTo(0.0D, | 
| - | @Inject(method = "method_31065(Lnet/ | + | </ | 
| - |  | + | |
| - |  | + | ===== Invoker for static methods ===== | 
| + | FIXME //This example is not fully accurate to latest versions, '' | ||
| + | Suppose we want to invoke '' | ||
| + | |||
| + | <code java> | ||
| + | @Mixin(BrewingRecipeRegistry.class) | ||
| + | public | ||
| + | @Invoker("registerPotionType") | ||
| + | static void modid$invokeRegisterPotionType(Item item) { | ||
| + |  | ||
| } | } | ||
| } | } | ||
| </ | </ | ||
| + | Usage: | ||
| + | |||
| + | <code java> | ||
| + | BrewingRecipeRegistryInvoker.modid$invokeRegisterPotionType(item); | ||
| + | </ | ||
tutorial/mixin_accessors.1598714307.txt.gz · Last modified: 2020/08/29 15:18 by siglong
                
                