Jump to content
View in the app

A better way to browse. Learn more.

Forge Forums

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Featured Replies

Posted

I'm trying to slightly modify the world generation of a structure created within villages. Specifically, I want to add a chest with loot (and maybe a few more blocks down the road) to the church.

 

What is the best way to go about this? I've poked around rather extensively in the code and there doesn't seem to be a way to be notified that that specific building was generated and where so I can simply plug my block(s) in. There is an event that informs about a village being generated but I didn't see anything more specific than that.

 

Would I need to replace the church with my own church building? If so, what's the best way to go about that? Wouldn't that mess with cleric villager spawning and possibly other things?

  • Author

Edit: Ignore the following post. I'm still looking for help with the OP, but I figured out what went wrong with the below. (The issue was that Forge doesn't handle villages on superflat worlds the way it does for regular worlds, meaning there is no InitMapGenEvent for them. I think that Forge probably should do so since testing this stuff out is much more difficult as is, but that isn't what this thread is about.)

Spoiler

 

Now I'm really lost. I decided to experiment with InitMapGenEvent, but I couldn't get my event method to trigger when villages were spawned at all (let alone something specific to the church building). Here's my event handler:

 

Spoiler


public class TestEventHandler {

	@SubscribeEvent
	public void onInitMapGen(InitMapGenEvent event) {
		logDebug("" + event.getType());
		if (event.getType() == EventType.VILLAGE) {
			logDebug("gen VILLAGE");
			//logDebug("class: " + event.getOriginalGen());
			if (event.getOriginalGen() != event.getNewGen()) {
				logDebug("Another mod has altered village generation?");
			}
		}
	}

}

 

 

I created a new superflat world for testing and the method IS called, but the only output I get is this:

 


[09:33:05] [Server thread/INFO] [pact]: [Pact DEBUG] NETHER_BRIDGE
[09:33:05] [Server thread/INFO] [pact]: [Pact DEBUG] NETHER_CAVE

 

... which I thought was odd. Nether stuff? I'm not in the Nether, but I guess maybe a small area of the Nether is generated around the origin point when a new world is created, or something. In any case, there's nothing about any village being generated.

 

 

Edited by Tuhljin

  • Author

So, I've done a lot of research on this and I haven't found a practical solution. I could replace the village generation with my own (extending the vanilla one), but that would make my mod incompatible with many other mods that change villages.

 

Does no one know of a good way to do this? The vanilla code relies on so many static methods in key places, there isn't a nice way to do what I want by reflection. Perhaps we need a new Event in Forge. I don't know where the best place for that would be, though I can offer some suggestions.

 

At net.minecraft.world.gen.structure.StructureVillagePieces.getStructureVillageWeightedPieceList(Random random, int size), there's already a call to Forge's "addExtraVillageComponents". Maybe there could be something there to remove components, as well. Then, I could remove the vanilla structure and add my own. But while removing structures could be nice for some mods, and it'd work fine on its own for me, it isn't the ideal when it comes to intermod compatibility since all I want to do is make some minor adjustments -- adjustments that could, presumably, happen in conjunction with other mods' adjustments to the same structure.

 

Perhaps the ideal for me is an Event that fires within net.minecraft.world.gen.structure.StructureStart.generateStructure(World, Random, StructureBoundingBox) just after structurecomponent.addComponentParts is called (if that call was a success), something that is passed all the arguments addComponentParts is to be passed and also structurecomponent itself (so the event tells us which component this was). So, the event would act as a pseudo-post-hook for the addComponentParts call.

 

 

Edited by Tuhljin
typo / clarity

8 hours ago, Tuhljin said:

So, I've done a lot of research on this and I haven't found a practical solution. I could replace the village generation with my own (extending the vanilla one), but that would make my mod incompatible with many other mods that change villages.

 

Does no one know of a good way to do this? The vanilla code relies on so many static methods in key places, there isn't a nice way to do what I want by reflection. Perhaps we need a new Event in Forge. I don't know where the best place for that would be, though I can offer some suggestions.

 

At net.minecraft.world.gen.structure.StructureVillagePieces.getStructureVillageWeightedPieceList(Random random, int size), there's already a call to Forge's "addExtraVillageComponents". Maybe there could be something there to remove components, as well. Then, I could remove the vanilla structure and add my own. But while removing structures could be nice for some mods, and it'd work fine on its own for me, it isn't the ideal when it comes to intermod compatibility since all I want to do is make some minor adjustments -- adjustments that could, presumably, happen in conjunction with other mods' adjustments to the same structure.

 

Perhaps the ideal for me is an Event that fires within net.minecraft.world.gen.structure.StructureStart.generateStructure(World, Random, StructureBoundingBox) just after structurecomponent.addComponentParts is called (if that call was a success), something that is passed all the arguments addComponentParts is to be passed and also structurecomponent itself (so the event tells us which component this was). So, the event would act as a pseudo-post-hook for the addComponentParts call.

 

 

I tried to do the same thing but the only way I could find to do it is to replace the MapGenVillage with my own. Would be great if someone had another solution.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

Important Information

By using this site, you agree to our Terms of Use.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.