public record CrystallineFlowerEnchantmentPacket(int containerId, List<EnchantmentSkeleton> enchantmentSkeletons) {
public static Gson gson = new GsonBuilder().create();
public static void sendToClient(ServerPlayer entity, int containerId, List<EnchantmentSkeleton> enchantmentSkeletons) {
MessageHandler.DEFAULT_CHANNEL.send(PacketDistributor.PLAYER.with(() -> entity),
public static List<BlockPos> matchingBlocksOfKindInRange(Level level, BlockPos centerPos, int radius, Predicate<BlockState> predicate) { | |
List<BlockPos> validPos = new ObjectArrayList<>(); | |
// Figure out how many chunk radius we need to search outward to encompass the radius properly | |
ChunkPos maxChunkPos = new ChunkPos( | |
SectionPos.blockToSectionCoord(centerPos.getX() + radius), | |
SectionPos.blockToSectionCoord(centerPos.getZ() + radius) | |
); | |
ChunkPos minChunkPos = new ChunkPos( |
// FORGE | |
@Mod(Test.MODID) | |
public class Test { | |
public static final String MODID = "test"; | |
// A Feature + Config to say how the feature should generate. | |
public static ConfiguredFeature<?, ?> CUSTOM_ORE_CF; | |
// A ConfiguredFeature + 0 or more Placement Modifiers that tells the | |
// ConfiguredFeature where and how often it should generate in chunks. | |
public static PlacedFeature CUSTOM_ORE_PF; |
// This gist code is public domain. Take it! Steal it! AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!!!!!!!!!!!! | |
// 1.18.2 code at top. 1.16.5 version farther down | |
private static final ResourceKey<StructureProcessorList> EMPTY_PROCESSOR_LIST_KEY = ResourceKey.create( | |
Registry.PROCESSOR_LIST_REGISTRY, new ResourceLocation("minecraft", "empty")); | |
public ExampleMod() { | |
MinecraftForge.EVENT_BUS.addListener(this::addNewVillageBuilding); | |
} |
Forge PRs can be quite tricky to understand and get working but if you can get your new event or hook or fix into Forge, you benefit a ton of modders! Don't let the idea of a Forge PR scare you or seem too daunting! Just follow this gist and hopefully you'll get the hang of it!
The first step is check out gigaherz's gist for creating a PR:
https://gist.github.com/gigaherz/ca256fea517cb925dfc31d7cd48c487e
Forge's doc on making PRs with extra into and styling rules:
https://github.com/MinecraftForge/MinecraftForge/wiki/If-you-want-to-contribute-to-Forge
When you mixin into a non-static inner class, the inner class has a hidden field that stores the instance of the outer class. It is a bit tricky to get it but it can be done.
Step one, go to the Forge jar and find the class in question. Open it in Intellij
// This gist code is public domain. Take it! Steal it! AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!!!!!!!!!!!! | |
// 1.18.2+ | |
public ExampleMod() { | |
MinecraftForge.EVENT_BUS.addListener(this::addNewVillageCrop); | |
} | |
public void addNewVillageCrop(final ServerAboutToStartEvent event) { | |
// Dynamic registry of processor lists. We will edit the processor lists from here as this is what the world will actually use. | |
Registry<StructureProcessorList> processorListRegistry = event.getServer().registryAccess().registry(Registry.PROCESSOR_LIST_REGISTRY).orElseThrow(); |
Mixins are a way to inject code or change the minecraft source code directly and should be use with caution. If you can do a PR to Forge or use an event, try those first. If all else fails, then mixins may be a good option to look into. Here are some resources for mixins:
- Mixin Official Docs: https://github.com/SpongePowered/Mixin/wiki
- Mixin Javadocs: https://jenkins.liteloader.com/view/Other/job/Mixin/javadoc/index.html
- Mixin Cheatsheet: https://github.com/2xsaiko/mixin-cheatsheet
- MixinExtras (Adds some powerful compatiable mixin options!): https://github.com/LlamaLad7/MixinExtras
Now, I'll be honest, the official mixin doc is kind of terrible to learn from for most people. It's extremely dense and and really only helps people who already knows in-depth bytecode and stuff. But most modders aren't like that and just wants to do small stuff lol. But I'll give you the run-down here. There's a few kinds of mixins that you will encounter quite often.
Gson gson = new GsonBuilder().setPrettyPrinting().create(); | |
// Will print the stuff into the runs/config folder | |
try { | |
for(Map.Entry<RegistryKey<StructureProcessorList>, StructureProcessorList> processorListEntry : BuiltinRegistries.STRUCTURE_PROCESSOR_LIST.getEntries()){ | |
if(!processorListEntry.getKey().getValue().getNamespace().equals(RepurposedStructures.MODID)) continue; | |
for(StructureProcessor processorEntry : processorListEntry.getValue().getList()) { | |
String filePath = FabricLoader.getInstance().getConfigDir()+"\\processor_list\\"+processorListEntry.getKey().getValue().getPath()+".json"; |