New BiomeLoadingEvent that allows modders to edit biomes as they are being deserialized.

This commit is contained in:
LexManos 2020-09-14 17:43:01 -07:00
parent ce6c664acd
commit 11e3281b3f
10 changed files with 386 additions and 1 deletions

View file

@ -0,0 +1,10 @@
--- a/net/minecraft/util/registry/WorldSettingsImport.java
+++ b/net/minecraft/util/registry/WorldSettingsImport.java
@@ -231,6 +231,7 @@
public <E> DataResult<Pair<E, OptionalInt>> func_241879_a(DynamicOps<JsonElement> p_241879_1_, RegistryKey<? extends Registry<E>> p_241879_2_, RegistryKey<E> p_241879_3_, Decoder<E> 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_)));
});

View file

@ -9,7 +9,18 @@
public static final Logger field_150586_aC = LogManager.getLogger();
public static final Codec<Biome> 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<Biome> 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_);

View file

@ -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<ConfiguredSurfaceBuilder<?>> field_242482_d;
private final Map<GenerationStage.Carving, List<Supplier<ConfiguredCarver<?>>>> field_242483_e;
+ private final java.util.Set<GenerationStage.Carving> carversView;
private final List<List<Supplier<ConfiguredFeature<?, ?>>>> field_242484_f;
private final List<Supplier<StructureFeature<?, ?>>> field_242485_g;
private final List<ConfiguredFeature<?, ?>> 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<Supplier<ConfiguredCarver<?>>> func_242489_a(GenerationStage.Carving p_242489_1_) {
return this.field_242483_e.getOrDefault(p_242489_1_, ImmutableList.of());
}
+ public java.util.Set<GenerationStage.Carving> 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_;

View file

@ -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<EntityClassification, List<MobSpawnInfo.Spawners>> field_242554_e;
private final Map<EntityType<?>, MobSpawnInfo.SpawnCosts> field_242555_f;
private final boolean field_242556_g;
+ private final java.util.Set<EntityClassification> typesView;
+ private final java.util.Set<EntityType<?>> costView;
private MobSpawnInfo(float p_i241946_1_, Map<EntityClassification, List<MobSpawnInfo.Spawners>> p_i241946_2_, Map<EntityType<?>, 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<MobSpawnInfo.Spawners> func_242559_a(EntityClassification p_242559_1_) {
return this.field_242554_e.getOrDefault(p_242559_1_, ImmutableList.of());
}
+ public java.util.Set<EntityClassification> 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<EntityType<?>> getEntityTypes() {
+ return this.costView;
+ }
+
public float func_242557_a() {
return this.field_242553_d;
}

View file

@ -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<Biome> 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;

View file

@ -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());
}
}

View file

@ -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<EntityClassification> typesView = Collections.unmodifiableSet(this.field_242567_a.keySet());
private final Set<EntityType<?>> 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<EntityClassification> getSpawnerTypes()
{
return this.typesView;
}
public List<MobSpawnInfo.Spawners> getSpawner(EntityClassification type)
{
return this.field_242567_a.get(type);
}
public Set<EntityType<?>> 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;
}
}

View file

@ -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;
}
}

View file

@ -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 <init>(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

View file

@ -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;