diff --git a/patches/minecraft/net/minecraft/util/registry/WorldSettingsImport.java.patch b/patches/minecraft/net/minecraft/util/registry/WorldSettingsImport.java.patch new file mode 100644 index 0000000000..c8fae266f6 --- /dev/null +++ b/patches/minecraft/net/minecraft/util/registry/WorldSettingsImport.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/util/registry/WorldSettingsImport.java ++++ b/net/minecraft/util/registry/WorldSettingsImport.java +@@ -231,6 +231,7 @@ + + public DataResult> func_241879_a(DynamicOps p_241879_1_, RegistryKey> p_241879_2_, RegistryKey p_241879_3_, Decoder p_241879_4_) { + JsonElement jsonelement = this.field_244349_a.get(p_241879_3_); ++ if (jsonelement!= null) jsonelement.getAsJsonObject().addProperty("forge:registry_name", p_241879_3_.func_240901_a_().toString()); + return jsonelement == null ? DataResult.error("Unknown element: " + p_241879_3_) : p_241879_4_.parse(p_241879_1_, jsonelement).setLifecycle(this.field_244351_c.get(p_241879_3_)).map((p_244353_2_) -> { + return Pair.of(p_244353_2_, OptionalInt.of(this.field_244350_b.getInt(p_241879_3_))); + }); diff --git a/patches/minecraft/net/minecraft/world/biome/Biome.java.patch b/patches/minecraft/net/minecraft/world/biome/Biome.java.patch index 7499bfd4f9..8f020a5c7e 100644 --- a/patches/minecraft/net/minecraft/world/biome/Biome.java.patch +++ b/patches/minecraft/net/minecraft/world/biome/Biome.java.patch @@ -9,7 +9,18 @@ public static final Logger field_150586_aC = LogManager.getLogger(); public static final Codec field_242418_b = RecordCodecBuilder.create((p_235064_0_) -> { return p_235064_0_.group(Biome.Climate.field_242459_a.forGetter((p_242446_0_) -> { -@@ -200,7 +200,7 @@ +@@ -70,7 +70,9 @@ + return p_242443_0_.field_242424_k; + }), MobSpawnInfo.field_242552_c.forGetter((p_242442_0_) -> { + return p_242442_0_.field_242425_l; +- })).apply(p_235064_0_, Biome::new); ++ }), ResourceLocation.field_240908_a_.fieldOf("forge:registry_name").forGetter(Biome::getRegistryName)) ++ .apply(p_235064_0_, (climate, category, depth, scale, effects, gen, spawns, name) -> ++ net.minecraftforge.common.ForgeHooks.enhanceBiome(name, climate, category, depth, scale, effects, gen, spawns, p_235064_0_, Biome::new)); + }); + public static final Codec field_242419_c = RecordCodecBuilder.create((p_242432_0_) -> { + return p_242432_0_.group(Biome.Climate.field_242459_a.forGetter((p_242441_0_) -> { +@@ -200,7 +202,7 @@ } else { if (p_201850_2_.func_177956_o() >= 0 && p_201850_2_.func_177956_o() < 256 && p_201850_1_.func_226658_a_(LightType.BLOCK, p_201850_2_) < 10) { BlockState blockstate = p_201850_1_.func_180495_p(p_201850_2_); diff --git a/patches/minecraft/net/minecraft/world/biome/BiomeGenerationSettings.java.patch b/patches/minecraft/net/minecraft/world/biome/BiomeGenerationSettings.java.patch new file mode 100644 index 0000000000..180ff786b1 --- /dev/null +++ b/patches/minecraft/net/minecraft/world/biome/BiomeGenerationSettings.java.patch @@ -0,0 +1,28 @@ +--- a/net/minecraft/world/biome/BiomeGenerationSettings.java ++++ b/net/minecraft/world/biome/BiomeGenerationSettings.java +@@ -47,6 +47,7 @@ + }); + private final Supplier> field_242482_d; + private final Map>>> field_242483_e; ++ private final java.util.Set carversView; + private final List>>> field_242484_f; + private final List>> field_242485_g; + private final List> field_242486_h; +@@ -59,12 +60,17 @@ + this.field_242486_h = p_i241935_3_.stream().flatMap(Collection::stream).map(Supplier::get).flatMap(ConfiguredFeature::func_242768_d).filter((p_242490_0_) -> { + return p_242490_0_.field_222737_a == Feature.field_227247_y_; + }).collect(ImmutableList.toImmutableList()); ++ this.carversView = java.util.Collections.unmodifiableSet(field_242483_e.keySet()); + } + + public List>> func_242489_a(GenerationStage.Carving p_242489_1_) { + return this.field_242483_e.getOrDefault(p_242489_1_, ImmutableList.of()); + } + ++ public java.util.Set getCarvingStages() { ++ return this.carversView; ++ } ++ + public boolean func_242493_a(Structure p_242493_1_) { + return this.field_242485_g.stream().anyMatch((p_242494_1_) -> { + return (p_242494_1_.get()).field_236268_b_ == p_242493_1_; diff --git a/patches/minecraft/net/minecraft/world/biome/MobSpawnInfo.java.patch b/patches/minecraft/net/minecraft/world/biome/MobSpawnInfo.java.patch new file mode 100644 index 0000000000..2602bf22fb --- /dev/null +++ b/patches/minecraft/net/minecraft/world/biome/MobSpawnInfo.java.patch @@ -0,0 +1,38 @@ +--- a/net/minecraft/world/biome/MobSpawnInfo.java ++++ b/net/minecraft/world/biome/MobSpawnInfo.java +@@ -42,23 +42,35 @@ + private final Map> field_242554_e; + private final Map, MobSpawnInfo.SpawnCosts> field_242555_f; + private final boolean field_242556_g; ++ private final java.util.Set typesView; ++ private final java.util.Set> costView; + + private MobSpawnInfo(float p_i241946_1_, Map> p_i241946_2_, Map, MobSpawnInfo.SpawnCosts> p_i241946_3_, boolean p_i241946_4_) { + this.field_242553_d = p_i241946_1_; + this.field_242554_e = p_i241946_2_; + this.field_242555_f = p_i241946_3_; + this.field_242556_g = p_i241946_4_; ++ this.typesView = java.util.Collections.unmodifiableSet(this.field_242554_e.keySet()); ++ this.costView = java.util.Collections.unmodifiableSet(this.field_242555_f.keySet()); + } + + public List func_242559_a(EntityClassification p_242559_1_) { + return this.field_242554_e.getOrDefault(p_242559_1_, ImmutableList.of()); + } + ++ public java.util.Set getSpawnerTypes() { ++ return this.typesView; ++ } ++ + @Nullable + public MobSpawnInfo.SpawnCosts func_242558_a(EntityType p_242558_1_) { + return this.field_242555_f.get(p_242558_1_); + } + ++ public java.util.Set> getEntityTypes() { ++ return this.costView; ++ } ++ + public float func_242557_a() { + return this.field_242553_d; + } diff --git a/src/main/java/net/minecraftforge/common/ForgeHooks.java b/src/main/java/net/minecraftforge/common/ForgeHooks.java index 68279d0531..d5888b4039 100644 --- a/src/main/java/net/minecraftforge/common/ForgeHooks.java +++ b/src/main/java/net/minecraftforge/common/ForgeHooks.java @@ -39,6 +39,8 @@ import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParseException; +import com.mojang.serialization.codecs.RecordCodecBuilder; + import javax.annotation.Nonnull; import javax.annotation.Nullable; import net.minecraft.advancements.Advancement; @@ -104,9 +106,15 @@ import net.minecraft.world.IBlockReader; import net.minecraft.world.IWorld; import net.minecraft.world.IWorldReader; import net.minecraft.world.World; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.BiomeAmbience; +import net.minecraft.world.biome.BiomeGenerationSettings; +import net.minecraft.world.biome.MobSpawnInfo; import net.minecraftforge.common.loot.IGlobalLootModifier; import net.minecraftforge.common.loot.LootModifierManager; import net.minecraftforge.common.util.BlockSnapshot; +import net.minecraftforge.common.world.BiomeGenerationSettingsBuilder; +import net.minecraftforge.common.world.MobSpawnInfoBuilder; import net.minecraftforge.event.AnvilUpdateEvent; import net.minecraftforge.event.DifficultyChangeEvent; import net.minecraftforge.event.ForgeEventFactory; @@ -130,6 +138,7 @@ import net.minecraftforge.event.entity.player.AttackEntityEvent; import net.minecraftforge.event.entity.player.CriticalHitEvent; import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.event.entity.player.PlayerInteractEvent; +import net.minecraftforge.event.world.BiomeLoadingEvent; import net.minecraftforge.event.world.BlockEvent; import net.minecraftforge.event.world.NoteBlockEvent; import net.minecraftforge.eventbus.api.Event.Result; @@ -839,6 +848,21 @@ public class ForgeHooks throw new RuntimeException("Mod fluids must override createAttributes."); } + @FunctionalInterface + public interface BiomeCallbackFunction + { + Biome apply(final Biome.Climate climate, final Biome.Category category, final Float depth, final Float scale, final BiomeAmbience effects, final BiomeGenerationSettings gen, final MobSpawnInfo spawns); + } + + public static Biome enhanceBiome(final ResourceLocation name, final Biome.Climate climate, final Biome.Category category, final Float depth, final Float scale, final BiomeAmbience effects, final BiomeGenerationSettings gen, final MobSpawnInfo spawns, final RecordCodecBuilder.Instance codec, final BiomeCallbackFunction callback) + { + BiomeGenerationSettingsBuilder genBuilder = new BiomeGenerationSettingsBuilder(gen); + MobSpawnInfoBuilder spawnBuilder = new MobSpawnInfoBuilder(spawns); + BiomeLoadingEvent event = new BiomeLoadingEvent(name, climate, category, depth, scale, effects, genBuilder, spawnBuilder); + MinecraftForge.EVENT_BUS.post(event); + return callback.apply(event.getClimate(), event.getCategory(), event.getDepth(), event.getScale(), event.getEffects(), event.getGeneration().func_242508_a(), event.getSpawns().func_242577_b()); + } + private static class LootTableContext { public final ResourceLocation name; diff --git a/src/main/java/net/minecraftforge/common/world/BiomeGenerationSettingsBuilder.java b/src/main/java/net/minecraftforge/common/world/BiomeGenerationSettingsBuilder.java new file mode 100644 index 0000000000..2d3663b754 --- /dev/null +++ b/src/main/java/net/minecraftforge/common/world/BiomeGenerationSettingsBuilder.java @@ -0,0 +1,36 @@ +/* + * Minecraft Forge + * Copyright (c) 2016-2020. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package net.minecraftforge.common.world; + +import net.minecraft.world.biome.BiomeGenerationSettings; + +import java.util.ArrayList; +import java.util.Optional; + +public class BiomeGenerationSettingsBuilder extends BiomeGenerationSettings.Builder +{ + public BiomeGenerationSettingsBuilder(BiomeGenerationSettings orig) + { + field_242504_a = Optional.of(orig.func_242500_d()); + orig.getCarvingStages().forEach(k -> field_242505_b.put(k, orig.func_242489_a(k))); + orig.func_242498_c().forEach(l -> field_242506_c.add(new ArrayList<>(l))); + field_242507_d.addAll(orig.func_242487_a()); + } +} \ No newline at end of file diff --git a/src/main/java/net/minecraftforge/common/world/MobSpawnInfoBuilder.java b/src/main/java/net/minecraftforge/common/world/MobSpawnInfoBuilder.java new file mode 100644 index 0000000000..01df41c140 --- /dev/null +++ b/src/main/java/net/minecraftforge/common/world/MobSpawnInfoBuilder.java @@ -0,0 +1,79 @@ +/* + * Minecraft Forge + * Copyright (c) 2016-2020. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package net.minecraftforge.common.world; + +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import javax.annotation.Nullable; + +import net.minecraft.entity.EntityClassification; +import net.minecraft.entity.EntityType; +import net.minecraft.world.biome.MobSpawnInfo; + +public class MobSpawnInfoBuilder extends MobSpawnInfo.Builder +{ + private final Set typesView = Collections.unmodifiableSet(this.field_242567_a.keySet()); + private final Set> costView = Collections.unmodifiableSet(this.field_242568_b.keySet()); + + public MobSpawnInfoBuilder(MobSpawnInfo orig) + { + orig.getSpawnerTypes().forEach(k -> { + field_242567_a.get(k).clear(); + field_242567_a.get(k).addAll(new java.util.ArrayList<>(orig.func_242559_a(k))); + }); + orig.getEntityTypes().forEach(k -> field_242568_b.put(k, orig.func_242558_a(k))); + field_242569_c = orig.func_242557_a(); + field_242570_d = orig.func_242562_b(); + } + + public Set getSpawnerTypes() + { + return this.typesView; + } + + public List getSpawner(EntityClassification type) + { + return this.field_242567_a.get(type); + } + + public Set> getEntityTypes() + { + return this.costView; + } + + @Nullable + public MobSpawnInfo.SpawnCosts getCost(EntityType type) + { + return this.field_242568_b.get(type); + } + + public float getProbability() + { + return this.field_242569_c; + } + + public MobSpawnInfoBuilder disablePlayerSpawn() + { + this.field_242570_d = false; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/net/minecraftforge/event/world/BiomeLoadingEvent.java b/src/main/java/net/minecraftforge/event/world/BiomeLoadingEvent.java new file mode 100644 index 0000000000..a467f89604 --- /dev/null +++ b/src/main/java/net/minecraftforge/event/world/BiomeLoadingEvent.java @@ -0,0 +1,131 @@ +/* + * Minecraft Forge + * Copyright (c) 2016-2020. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package net.minecraftforge.event.world; + +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.BiomeAmbience; +import net.minecraftforge.common.world.BiomeGenerationSettingsBuilder; +import net.minecraftforge.common.world.MobSpawnInfoBuilder; +import net.minecraftforge.eventbus.api.Event; +import net.minecraftforge.eventbus.api.EventPriority; + +/** + * This event fires when a Biome is created from json or when a registered biome is re-created for worldgen. + * It allows mods to edit a biome (like add a mob spawn) before it gets used for worldgen. + * + * In order to maintain the most compatibility possible with other mods' modifications to a biome, + * the event should be assigned a {@link net.minecraftforge.eventbus.api.EventPriority} as follows: + * + * - Additions to any list/map contained in a biome : {@link EventPriority#HIGH} + * - Removals to any list/map contained in a biome : {@link EventPriority#NORMAL} + * - Any other modification : {@link EventPriority#LOW} + * + * Be aware that another mod could have done an operation beforehand, so an expected value out of a vanilla biome might not + * always be the same, depending on other mods. + */ +public class BiomeLoadingEvent extends Event +{ + private final ResourceLocation name; + private Biome.Climate climate; + private Biome.Category category; + private float depth; + private float scale; + private BiomeAmbience effects; + private final BiomeGenerationSettingsBuilder gen; + private final MobSpawnInfoBuilder spawns; + + public BiomeLoadingEvent(final ResourceLocation name, final Biome.Climate climate, final Biome.Category category, final float depth, final float scale, final BiomeAmbience effects, final BiomeGenerationSettingsBuilder gen, final MobSpawnInfoBuilder spawns) + { + this.name = name; + this.climate = climate; + this.category = category; + this.depth = depth; + this.scale = scale; + this.effects = effects; + this.gen = gen; + this.spawns = spawns; + } + + public ResourceLocation getName() + { + return name; + } + + public Biome.Climate getClimate() + { + return climate; + } + + public void setClimate(final Biome.Climate value) + { + this.climate = value; + } + + public Biome.Category getCategory() + { + return category; + } + + public void setCategory(final Biome.Category value) + { + this.category = value; + } + + public float getDepth() + { + return depth; + } + + public void setDepth(final float value) + { + this.depth = value; + } + + public float getScale() + { + return scale; + } + + public void setScale(final float value) + { + this.scale = value; + } + + public BiomeAmbience getEffects() + { + return effects; + } + + public void setEffects(final BiomeAmbience value) + { + this.effects = value; + } + + public BiomeGenerationSettingsBuilder getGeneration() + { + return gen; + } + + public MobSpawnInfoBuilder getSpawns() + { + return spawns; + } +} \ No newline at end of file diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index ce4b1aff19..c3d02a1243 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -298,6 +298,15 @@ public net.minecraft.world.World field_73003_n #prevRainingStrength public net.minecraft.world.World field_73004_o #rainingStrength public net.minecraft.world.World field_73017_q #thunderingStrength public net.minecraft.world.World field_73018_p #prevThunderingStrength +public net.minecraft.world.biome.Biome$Climate +protected net.minecraft.world.biome.BiomeGenerationSettings$Builder field_242504_a +protected net.minecraft.world.biome.BiomeGenerationSettings$Builder field_242505_b +protected net.minecraft.world.biome.BiomeGenerationSettings$Builder field_242506_c +protected net.minecraft.world.biome.BiomeGenerationSettings$Builder field_242507_d +protected net.minecraft.world.biome.MobSpawnInfo$Builder field_242567_a +protected net.minecraft.world.biome.MobSpawnInfo$Builder field_242568_b +protected net.minecraft.world.biome.MobSpawnInfo$Builder field_242569_c +protected net.minecraft.world.biome.MobSpawnInfo$Builder field_242570_d public net.minecraft.world.chunk.ChunkStatus (Ljava/lang/String;Lnet/minecraft/world/chunk/ChunkStatus;ILjava/util/EnumSet;Lnet/minecraft/world/chunk/ChunkStatus$Type;Lnet/minecraft/world/chunk/ChunkStatus$IGenerationWorker;Lnet/minecraft/world/chunk/ChunkStatus$ILoadingWorker;)V private-f net.minecraft.world.gen.DebugChunkGenerator field_177462_b #GRID_WIDTH private-f net.minecraft.world.gen.DebugChunkGenerator field_177464_a #ALL_VALID_STATES diff --git a/src/test/java/net/minecraftforge/debug/block/ScaffoldingTest.java b/src/test/java/net/minecraftforge/debug/block/ScaffoldingTest.java index 69e32a1dc9..148da57b01 100644 --- a/src/test/java/net/minecraftforge/debug/block/ScaffoldingTest.java +++ b/src/test/java/net/minecraftforge/debug/block/ScaffoldingTest.java @@ -1,3 +1,22 @@ +/* + * Minecraft Forge + * Copyright (c) 2016-2020. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + package net.minecraftforge.debug.block; import net.minecraft.block.AbstractBlock;