Implement feature for mods to define new world types (#7448)
* Mods can now register world types via a new forge registry, and optionally register a settings screen to tweak them. * The default world type for dedicated servers and singleplayer world creation is configurable via forge's common config.
This commit is contained in:
parent
cd393bbfdc
commit
93c00b67d9
17 changed files with 519 additions and 4 deletions
|
@ -0,0 +1,21 @@
|
|||
--- a/net/minecraft/client/gui/screen/BiomeGeneratorTypeScreens.java
|
||||
+++ b/net/minecraft/client/gui/screen/BiomeGeneratorTypeScreens.java
|
||||
@@ -113,6 +113,9 @@
|
||||
private BiomeGeneratorTypeScreens(String p_i232324_1_) {
|
||||
this.field_239076_k_ = new TranslationTextComponent("generator." + p_i232324_1_);
|
||||
}
|
||||
+ public BiomeGeneratorTypeScreens(ITextComponent displayName) {
|
||||
+ this.field_239076_k_ = displayName;
|
||||
+ }
|
||||
|
||||
private static DimensionGeneratorSettings func_243452_a(DynamicRegistries p_243452_0_, DimensionGeneratorSettings p_243452_1_, BiomeGeneratorTypeScreens p_243452_2_, Biome p_243452_3_) {
|
||||
BiomeProvider biomeprovider = new SingleBiomeProvider(p_243452_3_);
|
||||
@@ -166,4 +169,8 @@
|
||||
public interface IFactory {
|
||||
Screen createEditScreen(CreateWorldScreen p_createEditScreen_1_, DimensionGeneratorSettings p_createEditScreen_2_);
|
||||
}
|
||||
+
|
||||
+ // Forge start
|
||||
+ // For internal use only, automatically called for all ForgeWorldTypes. Register your ForgeWorldType in the forge registry!
|
||||
+ public static void registerGenerator(BiomeGeneratorTypeScreens gen) { field_239068_c_.add(gen); }
|
||||
}
|
|
@ -1,5 +1,14 @@
|
|||
--- a/net/minecraft/client/gui/screen/CreateWorldScreen.java
|
||||
+++ b/net/minecraft/client/gui/screen/CreateWorldScreen.java
|
||||
@@ -110,7 +110,7 @@
|
||||
|
||||
public static CreateWorldScreen func_243425_a(@Nullable Screen p_243425_0_) {
|
||||
DynamicRegistries.Impl dynamicregistries$impl = DynamicRegistries.func_239770_b_();
|
||||
- return new CreateWorldScreen(p_243425_0_, DatapackCodec.field_234880_a_, new WorldOptionsScreen(dynamicregistries$impl, DimensionGeneratorSettings.func_242751_a(dynamicregistries$impl.func_243612_b(Registry.field_239698_ad_), dynamicregistries$impl.func_243612_b(Registry.field_239720_u_), dynamicregistries$impl.func_243612_b(Registry.field_243549_ar)), Optional.of(BiomeGeneratorTypeScreens.field_239066_a_), OptionalLong.empty()));
|
||||
+ return new CreateWorldScreen(p_243425_0_, DatapackCodec.field_234880_a_, new WorldOptionsScreen(dynamicregistries$impl, DimensionGeneratorSettings.func_242751_a(dynamicregistries$impl.func_243612_b(Registry.field_239698_ad_), dynamicregistries$impl.func_243612_b(Registry.field_239720_u_), dynamicregistries$impl.func_243612_b(Registry.field_243549_ar)), net.minecraftforge.client.ForgeHooksClient.getDefaultWorldType(), OptionalLong.empty()));
|
||||
}
|
||||
|
||||
private CreateWorldScreen(@Nullable Screen p_i242063_1_, DatapackCodec p_i242063_2_, WorldOptionsScreen p_i242063_3_) {
|
||||
@@ -542,6 +542,7 @@
|
||||
File file1 = path.toFile();
|
||||
if (this.field_243416_G == null) {
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
--- a/net/minecraft/client/gui/screen/WorldOptionsScreen.java
|
||||
+++ b/net/minecraft/client/gui/screen/WorldOptionsScreen.java
|
||||
@@ -134,6 +134,7 @@
|
||||
this.field_239035_i_.field_230693_o_ = this.field_239040_n_.isPresent();
|
||||
this.field_239036_j_ = p_239048_1_.func_230480_a_(new Button(j, 120, 150, 20, new TranslationTextComponent("selectWorld.customizeType"), (p_239044_3_) -> {
|
||||
BiomeGeneratorTypeScreens.IFactory biomegeneratortypescreens$ifactory = BiomeGeneratorTypeScreens.field_239069_d_.get(this.field_239040_n_);
|
||||
+ biomegeneratortypescreens$ifactory = net.minecraftforge.client.ForgeHooksClient.getBiomeGeneratorTypeScreenFactory(this.field_239040_n_, biomegeneratortypescreens$ifactory);
|
||||
if (biomegeneratortypescreens$ifactory != null) {
|
||||
p_239048_2_.func_147108_a(biomegeneratortypescreens$ifactory.createEditScreen(p_239048_1_, this.field_239039_m_));
|
||||
}
|
||||
@@ -292,7 +293,7 @@
|
||||
} else {
|
||||
this.field_239034_h_.field_230694_p_ = p_239059_1_;
|
||||
this.field_239027_a_.field_230694_p_ = p_239059_1_;
|
||||
- this.field_239036_j_.field_230694_p_ = p_239059_1_ && BiomeGeneratorTypeScreens.field_239069_d_.containsKey(this.field_239040_n_);
|
||||
+ this.field_239036_j_.field_230694_p_ = p_239059_1_ && (BiomeGeneratorTypeScreens.field_239069_d_.containsKey(this.field_239040_n_) || net.minecraftforge.client.ForgeHooksClient.hasBiomeGeneratorSettingsOptionsScreen(this.field_239040_n_));
|
||||
this.field_239037_k_.field_230694_p_ = p_239059_1_;
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
--- a/net/minecraft/world/gen/settings/DimensionGeneratorSettings.java
|
||||
+++ b/net/minecraft/world/gen/settings/DimensionGeneratorSettings.java
|
||||
@@ -192,7 +192,7 @@
|
||||
String s3 = (String)p_242753_1_.get("level-type");
|
||||
String s4 = Optional.ofNullable(s3).map((p_236217_0_) -> {
|
||||
return p_236217_0_.toLowerCase(Locale.ROOT);
|
||||
- }).orElse("default");
|
||||
+ }).orElseGet(net.minecraftforge.common.ForgeHooks::getDefaultWorldType);
|
||||
p_242753_1_.put("level-type", s4);
|
||||
long i = (new Random()).nextLong();
|
||||
if (!s1.isEmpty()) {
|
||||
@@ -210,6 +210,8 @@
|
||||
Registry<Biome> registry = p_242753_0_.func_243612_b(Registry.field_239720_u_);
|
||||
Registry<DimensionSettings> registry1 = p_242753_0_.func_243612_b(Registry.field_243549_ar);
|
||||
SimpleRegistry<Dimension> simpleregistry = DimensionType.func_242718_a(registry2, registry, registry1, i);
|
||||
+ net.minecraftforge.common.world.ForgeWorldType type = net.minecraftforge.registries.ForgeRegistries.WORLD_TYPES.getValue(new net.minecraft.util.ResourceLocation(s4));
|
||||
+ if (type != null) return type.createSettings(p_242753_0_, i, flag, false, s);
|
||||
switch(s4) {
|
||||
case "flat":
|
||||
JsonObject jsonobject = !s.isEmpty() ? JSONUtils.func_212745_a(s) : new JsonObject();
|
|
@ -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.fml.loading;
|
||||
|
||||
import net.minecraftforge.forgespi.language.MavenVersionAdapter;
|
||||
|
|
|
@ -31,6 +31,7 @@ import net.minecraft.client.audio.SoundEngine;
|
|||
import net.minecraft.client.gui.AbstractGui;
|
||||
import net.minecraft.client.gui.ClientBossInfo;
|
||||
import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.client.gui.screen.BiomeGeneratorTypeScreens;
|
||||
import net.minecraft.client.gui.screen.MainMenuScreen;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.network.play.NetworkPlayerInfo;
|
||||
|
@ -78,6 +79,7 @@ import net.minecraft.util.text.TranslationTextComponent;
|
|||
import net.minecraft.world.GameType;
|
||||
import net.minecraft.world.IBlockDisplayReader;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.gen.settings.DimensionGeneratorSettings;
|
||||
import net.minecraftforge.client.event.*;
|
||||
import net.minecraftforge.client.event.sound.PlaySoundEvent;
|
||||
import net.minecraftforge.client.model.ModelLoader;
|
||||
|
@ -102,12 +104,14 @@ import org.apache.logging.log4j.core.impl.ReusableLogEventFactory;
|
|||
import org.lwjgl.opengl.GL13;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.Buffer;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
@ -785,4 +789,29 @@ public class ForgeHooksClient
|
|||
});
|
||||
setRenderLayer(null);
|
||||
}
|
||||
|
||||
public static void registerForgeWorldTypeScreens()
|
||||
{
|
||||
ForgeWorldTypeScreens.registerTypes();
|
||||
}
|
||||
|
||||
public static BiomeGeneratorTypeScreens.IFactory getBiomeGeneratorTypeScreenFactory(Optional<BiomeGeneratorTypeScreens> generator, @Nullable BiomeGeneratorTypeScreens.IFactory biomegeneratortypescreens$ifactory)
|
||||
{
|
||||
return ForgeWorldTypeScreens.getGeneratorScreenFactory(generator, biomegeneratortypescreens$ifactory);
|
||||
}
|
||||
|
||||
public static boolean hasBiomeGeneratorSettingsOptionsScreen(Optional<BiomeGeneratorTypeScreens> generator)
|
||||
{
|
||||
return getBiomeGeneratorTypeScreenFactory(generator, null) != null;
|
||||
}
|
||||
|
||||
public static Optional<BiomeGeneratorTypeScreens> getWorldTypeFromGenerator(DimensionGeneratorSettings dimensionGeneratorSettings)
|
||||
{
|
||||
return BiomeGeneratorTypeScreens.func_239079_a_(dimensionGeneratorSettings);
|
||||
}
|
||||
|
||||
public static Optional<BiomeGeneratorTypeScreens> getDefaultWorldType()
|
||||
{
|
||||
return Optional.of(ForgeWorldTypeScreens.getDefaultGenerator());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* 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.client;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import net.minecraft.client.gui.screen.BiomeGeneratorTypeScreens;
|
||||
import net.minecraft.util.registry.DynamicRegistries;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.gen.ChunkGenerator;
|
||||
import net.minecraft.world.gen.DimensionSettings;
|
||||
import net.minecraft.world.gen.settings.DimensionGeneratorSettings;
|
||||
import net.minecraftforge.common.world.ForgeWorldType;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class ForgeWorldTypeScreens
|
||||
{
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
private static final Map<ForgeWorldType, BiomeGeneratorTypeScreens> GENERATORS = Maps.newHashMap();
|
||||
private static final Map<ForgeWorldType, BiomeGeneratorTypeScreens.IFactory> GENERATOR_SCREEN_FACTORIES = Maps.newHashMap();
|
||||
|
||||
public static synchronized void registerFactory(ForgeWorldType type, BiomeGeneratorTypeScreens.IFactory factory)
|
||||
{
|
||||
if (GENERATOR_SCREEN_FACTORIES.containsKey(type))
|
||||
throw new IllegalStateException("Factory has already been registered for: " + type);
|
||||
|
||||
GENERATOR_SCREEN_FACTORIES.put(type, factory);
|
||||
}
|
||||
|
||||
static BiomeGeneratorTypeScreens getDefaultGenerator()
|
||||
{
|
||||
ForgeWorldType def = ForgeWorldType.getDefaultWorldType();
|
||||
if (def == null)
|
||||
{
|
||||
return BiomeGeneratorTypeScreens.field_239066_a_;
|
||||
}
|
||||
|
||||
BiomeGeneratorTypeScreens gen = GENERATORS.get(def);
|
||||
if (gen == null)
|
||||
{
|
||||
LOGGER.error("The default world type '{}' has not been added to the GUI. Was it registered too late?", def.getRegistryName());
|
||||
return BiomeGeneratorTypeScreens.field_239066_a_;
|
||||
}
|
||||
|
||||
return gen;
|
||||
}
|
||||
|
||||
static BiomeGeneratorTypeScreens.IFactory getGeneratorScreenFactory(Optional<BiomeGeneratorTypeScreens> generator, @Nullable BiomeGeneratorTypeScreens.IFactory biomegeneratortypescreens$ifactory)
|
||||
{
|
||||
return generator.filter(gen -> gen instanceof GeneratorType)
|
||||
.map(type -> GENERATOR_SCREEN_FACTORIES.get(((GeneratorType)type).getWorldType()))
|
||||
.orElse(biomegeneratortypescreens$ifactory);
|
||||
}
|
||||
|
||||
static void registerTypes()
|
||||
{
|
||||
ForgeRegistries.WORLD_TYPES.forEach(wt -> {
|
||||
GeneratorType gen = new GeneratorType(wt);
|
||||
GENERATORS.put(wt, gen);
|
||||
BiomeGeneratorTypeScreens.registerGenerator(gen);
|
||||
});
|
||||
}
|
||||
|
||||
private static class GeneratorType extends BiomeGeneratorTypeScreens
|
||||
{
|
||||
private final ForgeWorldType worldType;
|
||||
|
||||
public GeneratorType(ForgeWorldType wt)
|
||||
{
|
||||
super(wt.getDisplayName());
|
||||
worldType = wt;
|
||||
}
|
||||
|
||||
public ForgeWorldType getWorldType()
|
||||
{
|
||||
return worldType;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public DimensionGeneratorSettings func_241220_a_(@Nonnull DynamicRegistries.Impl dynamicRegistries, long seed, boolean generateStructures, boolean bonusChest)
|
||||
{
|
||||
return worldType.createSettings(dynamicRegistries, seed, generateStructures, bonusChest, "");
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
protected ChunkGenerator func_241869_a(@Nonnull Registry<Biome> p_241869_1_, @Nonnull Registry<DimensionSettings> p_241869_2_, long p_241869_3_)
|
||||
{
|
||||
return worldType.createChunkGenerator(p_241869_1_, p_241869_2_, p_241869_3_, "");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -108,10 +108,33 @@ public class ForgeConfig
|
|||
.comment("Fix advancement loading to use a proper topological sort. This may have visibility side-effects and can thus be turned off if needed for data-pack compatibility.")
|
||||
.translation("forge.configgui.fixAdvancementLoading")
|
||||
.define("fixAdvancementLoading", true);
|
||||
|
||||
builder.pop();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* General configuration that doesn't need to be synchronized but needs to be available before server startup
|
||||
*/
|
||||
public static class Common {
|
||||
public final ForgeConfigSpec.ConfigValue<? extends String> defaultWorldType;
|
||||
|
||||
Common(ForgeConfigSpec.Builder builder)
|
||||
{
|
||||
builder.comment("General configuration settings")
|
||||
.push("general");
|
||||
|
||||
defaultWorldType = builder
|
||||
.comment("Defines a default world type to use. The vanilla default world type is represented by 'default'.",
|
||||
"The modded world types are registry names which should include the registry namespace, such as 'examplemod:example_world_type'.")
|
||||
.translation("forge.configgui.defaultWorldType")
|
||||
.define("defaultWorldType", "default");
|
||||
|
||||
builder.pop();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Client specific configuration - only loaded clientside from forge-client.toml
|
||||
*/
|
||||
|
@ -196,6 +219,15 @@ public class ForgeConfig
|
|||
}
|
||||
|
||||
|
||||
static final ForgeConfigSpec commonSpec;
|
||||
public static final Common COMMON;
|
||||
static {
|
||||
final Pair<Common, ForgeConfigSpec> specPair = new ForgeConfigSpec.Builder().configure(Common::new);
|
||||
commonSpec = specPair.getRight();
|
||||
COMMON = specPair.getLeft();
|
||||
}
|
||||
|
||||
|
||||
static final ForgeConfigSpec serverSpec;
|
||||
public static final Server SERVER;
|
||||
static {
|
||||
|
|
|
@ -120,6 +120,7 @@ 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.ForgeWorldType;
|
||||
import net.minecraftforge.common.world.MobSpawnInfoBuilder;
|
||||
import net.minecraftforge.event.AnvilUpdateEvent;
|
||||
import net.minecraftforge.event.DifficultyChangeEvent;
|
||||
|
@ -879,6 +880,14 @@ public class ForgeHooks
|
|||
throw new RuntimeException("Mod fluids must override createAttributes.");
|
||||
}
|
||||
|
||||
public static String getDefaultWorldType()
|
||||
{
|
||||
ForgeWorldType def = ForgeWorldType.getDefaultWorldType();
|
||||
if (def != null)
|
||||
return def.getRegistryName().toString();
|
||||
return "default";
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface BiomeCallbackFunction
|
||||
{
|
||||
|
|
|
@ -27,14 +27,16 @@ import net.minecraft.entity.ai.attributes.RangedAttribute;
|
|||
import net.minecraft.util.SoundEvent;
|
||||
import net.minecraft.world.storage.IServerConfiguration;
|
||||
import net.minecraft.world.storage.SaveFormat;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.client.ForgeHooksClient;
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.*;
|
||||
import net.minecraftforge.fml.config.ModConfig;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLModIdMappingEvent;
|
||||
import net.minecraftforge.fml.event.lifecycle.*;
|
||||
import net.minecraftforge.fml.event.server.FMLServerStoppingEvent;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
import net.minecraftforge.fml.loading.FMLEnvironment;
|
||||
import net.minecraftforge.fml.loading.progress.StartupMessageManager;
|
||||
import net.minecraftforge.registries.DeferredRegister;
|
||||
import net.minecraftforge.server.command.EnumArgument;
|
||||
|
@ -71,7 +73,6 @@ import net.minecraftforge.common.data.ForgeRecipeProvider;
|
|||
import net.minecraftforge.common.model.animation.CapabilityAnimation;
|
||||
import net.minecraftforge.energy.CapabilityEnergy;
|
||||
import net.minecraftforge.event.RegistryEvent;
|
||||
import net.minecraftforge.fml.event.lifecycle.GatherDataEvent;
|
||||
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
|
@ -118,12 +119,14 @@ public class ForgeMod implements WorldPersistenceHooks.WorldPersistenceHook
|
|||
final IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
|
||||
modEventBus.addListener(this::preInit);
|
||||
modEventBus.addListener(this::gatherData);
|
||||
modEventBus.addListener(this::loadComplete);
|
||||
modEventBus.register(this);
|
||||
ATTRIBUTES.register(modEventBus);
|
||||
MinecraftForge.EVENT_BUS.addListener(this::serverStopping);
|
||||
MinecraftForge.EVENT_BUS.addGenericListener(SoundEvent.class, this::missingSoundMapping);
|
||||
ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, ForgeConfig.clientSpec);
|
||||
ModLoadingContext.get().registerConfig(ModConfig.Type.SERVER, ForgeConfig.serverSpec);
|
||||
ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, ForgeConfig.commonSpec);
|
||||
modEventBus.register(ForgeConfig.class);
|
||||
// Forge does not display problems when the remote is not matching.
|
||||
ModLoadingContext.get().registerExtensionPoint(ExtensionPoint.DISPLAYTEST, ()-> Pair.of(()->"ANY", (remote, isServer)-> true));
|
||||
|
@ -154,6 +157,12 @@ public class ForgeMod implements WorldPersistenceHooks.WorldPersistenceHook
|
|||
ArgumentTypes.register("forge:modid", ModIdArgument.class, new ArgumentSerializer<>(ModIdArgument::modIdArgument));
|
||||
}
|
||||
|
||||
public void loadComplete(FMLLoadCompleteEvent event)
|
||||
{
|
||||
if (FMLEnvironment.dist == Dist.CLIENT)
|
||||
ForgeHooksClient.registerForgeWorldTypeScreens();
|
||||
}
|
||||
|
||||
public void serverStopping(FMLServerStoppingEvent evt)
|
||||
{
|
||||
WorldWorkerManager.clear();
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* 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.util.ResourceLocation;
|
||||
import net.minecraft.util.StringUtils;
|
||||
import net.minecraft.util.Util;
|
||||
import net.minecraft.util.registry.DynamicRegistries;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.TranslationTextComponent;
|
||||
import net.minecraft.world.DimensionType;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.gen.ChunkGenerator;
|
||||
import net.minecraft.world.gen.DimensionSettings;
|
||||
import net.minecraft.world.gen.settings.DimensionGeneratorSettings;
|
||||
import net.minecraftforge.common.ForgeConfig;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import net.minecraftforge.registries.ForgeRegistryEntry;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
public class ForgeWorldType extends ForgeRegistryEntry<ForgeWorldType>
|
||||
{
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
public static ForgeWorldType getDefaultWorldType()
|
||||
{
|
||||
String defaultWorldType = ForgeConfig.COMMON.defaultWorldType.get();
|
||||
|
||||
if (StringUtils.isNullOrEmpty(defaultWorldType) || "default".equals(defaultWorldType))
|
||||
return null; // use vanilla
|
||||
|
||||
ForgeWorldType def = ForgeRegistries.WORLD_TYPES.getValue(new ResourceLocation(defaultWorldType));
|
||||
if (def == null)
|
||||
{
|
||||
LOGGER.error("The defaultWorldType '{}' specified in the forge config has not been registered. The vanilla default generator will be used.", defaultWorldType);
|
||||
}
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
private final IChunkGeneratorFactory factory;
|
||||
|
||||
public ForgeWorldType(IChunkGeneratorFactory factory)
|
||||
{
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
public ForgeWorldType(IBasicChunkGeneratorFactory factory)
|
||||
{
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
public String getTranslationKey()
|
||||
{
|
||||
return Util.makeTranslationKey("generator", getRegistryName());
|
||||
}
|
||||
|
||||
public ITextComponent getDisplayName()
|
||||
{
|
||||
return new TranslationTextComponent(getTranslationKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from both the dedicated server and the world creation screen in the client.
|
||||
* to construct the DimensionGEneratorSettings:
|
||||
* @return The constructed chunk generator.
|
||||
*/
|
||||
public ChunkGenerator createChunkGenerator(Registry<Biome> biomeRegistry, Registry<DimensionSettings> dimensionSettingsRegistry, long seed, String generatorSettings)
|
||||
{
|
||||
return this.factory.createChunkGenerator(biomeRegistry, dimensionSettingsRegistry, seed, generatorSettings);
|
||||
}
|
||||
|
||||
public DimensionGeneratorSettings createSettings(DynamicRegistries dynamicRegistries, long seed, boolean generateStructures, boolean generateLoot, String generatorSettings)
|
||||
{
|
||||
return this.factory.createSettings(dynamicRegistries, seed, generateStructures, generateLoot, generatorSettings);
|
||||
}
|
||||
|
||||
public interface IChunkGeneratorFactory
|
||||
{
|
||||
ChunkGenerator createChunkGenerator(Registry<Biome> biomeRegistry, Registry<DimensionSettings> dimensionSettingsRegistry, long seed, String generatorSettings);
|
||||
|
||||
default DimensionGeneratorSettings createSettings(DynamicRegistries dynamicRegistries, long seed, boolean generateStructures, boolean bonusChest, String generatorSettings) {
|
||||
Registry<Biome> biomeRegistry = dynamicRegistries.getRegistry(Registry.BIOME_KEY);
|
||||
Registry<DimensionType> dimensionTypeRegistry = dynamicRegistries.getRegistry(Registry.DIMENSION_TYPE_KEY);
|
||||
Registry<DimensionSettings> dimensionSettingsRegistry = dynamicRegistries.getRegistry(Registry.NOISE_SETTINGS_KEY);
|
||||
return new DimensionGeneratorSettings(seed, generateStructures, bonusChest,
|
||||
DimensionGeneratorSettings.func_242749_a(dimensionTypeRegistry,
|
||||
DimensionType.getDefaultSimpleRegistry(dimensionTypeRegistry, biomeRegistry, dimensionSettingsRegistry, seed),
|
||||
createChunkGenerator(biomeRegistry, dimensionSettingsRegistry, seed, generatorSettings)));
|
||||
}
|
||||
}
|
||||
|
||||
public interface IBasicChunkGeneratorFactory extends IChunkGeneratorFactory
|
||||
{
|
||||
ChunkGenerator createChunkGenerator(Registry<Biome> biomeRegistry, Registry<DimensionSettings> dimensionSettingsRegistry, long seed);
|
||||
|
||||
default ChunkGenerator createChunkGenerator(Registry<Biome> biomeRegistry, Registry<DimensionSettings> dimensionSettingsRegistry, long seed, String generatorSettings)
|
||||
{
|
||||
return createChunkGenerator(biomeRegistry, dimensionSettingsRegistry, seed);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -57,6 +57,7 @@ import net.minecraft.world.gen.surfacebuilders.SurfaceBuilder;
|
|||
import net.minecraft.world.gen.treedecorator.TreeDecoratorType;
|
||||
import net.minecraftforge.common.Tags;
|
||||
import net.minecraftforge.common.loot.GlobalLootModifierSerializer;
|
||||
import net.minecraftforge.common.world.ForgeWorldType;
|
||||
import net.minecraftforge.fml.common.registry.GameRegistry;
|
||||
|
||||
/**
|
||||
|
@ -111,6 +112,7 @@ public class ForgeRegistries
|
|||
// Custom forge registries
|
||||
public static final IForgeRegistry<DataSerializerEntry> DATA_SERIALIZERS = RegistryManager.ACTIVE.getRegistry(DataSerializerEntry.class);
|
||||
public static final IForgeRegistry<GlobalLootModifierSerializer<?>> LOOT_MODIFIER_SERIALIZERS = RegistryManager.ACTIVE.getRegistry(GlobalLootModifierSerializer.class);
|
||||
public static final IForgeRegistry<ForgeWorldType> WORLD_TYPES = RegistryManager.ACTIVE.getRegistry(ForgeWorldType.class);
|
||||
|
||||
public static final class Keys {
|
||||
//Vanilla
|
||||
|
@ -152,6 +154,7 @@ public class ForgeRegistries
|
|||
//Forge
|
||||
public static final RegistryKey<Registry<DataSerializerEntry>> DATA_SERIALIZERS = key("data_serializers");
|
||||
public static final RegistryKey<Registry<GlobalLootModifierSerializer<?>>> LOOT_MODIFIER_SERIALIZERS = key("forge:loot_modifier_serializers");
|
||||
public static final RegistryKey<Registry<ForgeWorldType>> WORLD_TYPES = key("forge:world_types");
|
||||
|
||||
private static <T> RegistryKey<Registry<T>> key(String name)
|
||||
{
|
||||
|
|
|
@ -74,6 +74,7 @@ import net.minecraft.world.gen.treedecorator.TreeDecoratorType;
|
|||
import net.minecraftforge.common.ForgeTagHandler;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.common.loot.GlobalLootModifierSerializer;
|
||||
import net.minecraftforge.common.world.ForgeWorldType;
|
||||
import net.minecraftforge.event.RegistryEvent;
|
||||
import net.minecraftforge.event.RegistryEvent.MissingMappings;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
|
@ -180,6 +181,7 @@ public class GameData
|
|||
// Custom forge registries
|
||||
makeRegistry(DATA_SERIALIZERS, DataSerializerEntry.class, 256 /*vanilla space*/, MAX_VARINT).disableSaving().disableOverrides().addCallback(SerializerCallbacks.INSTANCE).create();
|
||||
makeRegistry(LOOT_MODIFIER_SERIALIZERS, c(GlobalLootModifierSerializer.class)).disableSaving().disableSync().create();
|
||||
makeRegistry(WORLD_TYPES, ForgeWorldType.class).disableSaving().disableSync().create();
|
||||
}
|
||||
@SuppressWarnings("unchecked") //Ugly hack to let us pass in a typed Class object. Remove when we remove type specific references.
|
||||
private static <T> Class<T> c(Class<?> cls) { return (Class<T>)cls; }
|
||||
|
|
|
@ -144,6 +144,7 @@ public net.minecraft.client.gui.ScreenManager func_216911_a(Lnet/minecraft/inven
|
|||
public net.minecraft.client.gui.ScreenManager$IScreenFactory
|
||||
protected net.minecraft.client.gui.overlay.DebugOverlayGui field_211537_g # rayTraceBlock
|
||||
protected net.minecraft.client.gui.overlay.DebugOverlayGui field_211538_h # rayTraceFluid
|
||||
public net.minecraft.client.gui.screen.WorldOptionsScreen func_239043_a_(Lnet/minecraft/world/gen/settings/DimensionGeneratorSettings;)V # func_239043_a_
|
||||
protected net.minecraft.client.gui.widget.list.AbstractList$AbstractListEntry field_230666_a_ # list
|
||||
public net.minecraft.client.particle.ParticleManager func_199283_a(Lnet/minecraft/particles/ParticleType;Lnet/minecraft/client/particle/IParticleFactory;)V # registerFactory
|
||||
public net.minecraft.client.particle.ParticleManager func_215234_a(Lnet/minecraft/particles/ParticleType;Lnet/minecraft/client/particle/ParticleManager$IParticleMetaFactory;)V # registerFactory
|
||||
|
|
|
@ -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.client.rendering;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* 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.world;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.widget.button.Button;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.gen.ChunkGenerator;
|
||||
import net.minecraft.world.gen.DimensionSettings;
|
||||
import net.minecraft.world.gen.settings.DimensionGeneratorSettings;
|
||||
import net.minecraftforge.client.ForgeWorldTypeScreens;
|
||||
import net.minecraftforge.common.world.ForgeWorldType;
|
||||
import net.minecraftforge.event.RegistryEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
import net.minecraftforge.registries.ObjectHolder;
|
||||
|
||||
@Mod("forge_world_type_test")
|
||||
public class ForgeWorldTypeTest
|
||||
{
|
||||
@ObjectHolder("forge_world_type_test:test_world_type")
|
||||
public static ForgeWorldType testWorldType;
|
||||
|
||||
public ForgeWorldTypeTest()
|
||||
{
|
||||
FMLJavaModLoadingContext.get().getModEventBus().addGenericListener(ForgeWorldType.class, this::registerWorldTypes);
|
||||
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::registerWorldTypeScreenFactories);
|
||||
}
|
||||
|
||||
private void registerWorldTypes(RegistryEvent.Register<ForgeWorldType> event)
|
||||
{
|
||||
event.getRegistry().registerAll(
|
||||
new ForgeWorldType(DimensionGeneratorSettings::func_242750_a).setRegistryName("test_world_type")
|
||||
);
|
||||
event.getRegistry().registerAll(
|
||||
new ForgeWorldType(this::createChunkGenerator).setRegistryName("test_world_type2")
|
||||
);
|
||||
}
|
||||
|
||||
private ChunkGenerator createChunkGenerator(Registry<Biome> biomes, Registry<DimensionSettings> dimensionSettings, long seed, String settings)
|
||||
{
|
||||
return DimensionGeneratorSettings.func_242750_a(biomes, dimensionSettings, seed);
|
||||
}
|
||||
|
||||
private void registerWorldTypeScreenFactories(FMLClientSetupEvent event)
|
||||
{
|
||||
ForgeWorldTypeScreens.registerFactory(testWorldType, (returnTo, dimensionGeneratorSettings) -> new Screen(testWorldType.getDisplayName())
|
||||
{
|
||||
@Override
|
||||
protected void init()
|
||||
{
|
||||
super.init();
|
||||
|
||||
addButton(new Button(0, 0, 120, 20, new StringTextComponent("close"), btn -> {
|
||||
Minecraft.getInstance().displayGuiScreen(returnTo);
|
||||
}));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -95,4 +95,6 @@ license="LGPL v2.1"
|
|||
[[mods]]
|
||||
modId="forge_codecs_test"
|
||||
[[mods]]
|
||||
modId="render_local_player_test"
|
||||
modId="render_local_player_test"
|
||||
[[mods]]
|
||||
modId="forge_world_type_test"
|
Loading…
Reference in a new issue