mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-10-26 05:50:08 +00:00
Merge pull request #191 from PolyhedralDev/dev/fabric-compat
Options for mod compatibility on Fabric
This commit is contained in:
20 files changed
+579
-165
No files matched your search
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import com.dfsek.terra.getGitHash
|
import com.dfsek.terra.getGitHash
|
||||||
|
|
||||||
val versionObj = Version("5", "3", "2", true)
|
val versionObj = Version("5", "3", "3", true)
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
version = versionObj
|
version = versionObj
|
||||||
|
|||||||
+18
-1
@@ -1,5 +1,7 @@
|
|||||||
package com.dfsek.terra.api.event.events.config;
|
package com.dfsek.terra.api.event.events.config;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.config.ConfigTemplate;
|
||||||
|
import com.dfsek.tectonic.exception.ConfigException;
|
||||||
import com.dfsek.terra.api.event.events.PackEvent;
|
import com.dfsek.terra.api.event.events.PackEvent;
|
||||||
import com.dfsek.terra.config.pack.ConfigPack;
|
import com.dfsek.terra.config.pack.ConfigPack;
|
||||||
|
|
||||||
@@ -8,13 +10,28 @@ import com.dfsek.terra.config.pack.ConfigPack;
|
|||||||
*/
|
*/
|
||||||
public abstract class ConfigPackLoadEvent implements PackEvent {
|
public abstract class ConfigPackLoadEvent implements PackEvent {
|
||||||
private final ConfigPack pack;
|
private final ConfigPack pack;
|
||||||
|
private final ExceptionalConsumer<ConfigTemplate> configLoader;
|
||||||
|
|
||||||
public ConfigPackLoadEvent(ConfigPack pack) {
|
public ConfigPackLoadEvent(ConfigPack pack, ExceptionalConsumer<ConfigTemplate> configLoader) {
|
||||||
this.pack = pack;
|
this.pack = pack;
|
||||||
|
this.configLoader = configLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConfigPack getPack() {
|
public ConfigPack getPack() {
|
||||||
return pack;
|
return pack;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load a custom {@link ConfigTemplate} using the pack manifest.
|
||||||
|
*
|
||||||
|
* @param template Template to register.
|
||||||
|
*/
|
||||||
|
public void loadTemplate(ConfigTemplate template) throws ConfigException {
|
||||||
|
configLoader.accept(template);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ExceptionalConsumer<T extends ConfigTemplate> {
|
||||||
|
void accept(T value) throws ConfigException;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+3
-2
@@ -1,12 +1,13 @@
|
|||||||
package com.dfsek.terra.api.event.events.config;
|
package com.dfsek.terra.api.event.events.config;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.config.ConfigTemplate;
|
||||||
import com.dfsek.terra.config.pack.ConfigPack;
|
import com.dfsek.terra.config.pack.ConfigPack;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when a config pack has finished loading.
|
* Called when a config pack has finished loading.
|
||||||
*/
|
*/
|
||||||
public class ConfigPackPostLoadEvent extends ConfigPackLoadEvent {
|
public class ConfigPackPostLoadEvent extends ConfigPackLoadEvent {
|
||||||
public ConfigPackPostLoadEvent(ConfigPack pack) {
|
public ConfigPackPostLoadEvent(ConfigPack pack, ExceptionalConsumer<ConfigTemplate> loader) {
|
||||||
super(pack);
|
super(pack, loader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+4
-2
@@ -1,12 +1,14 @@
|
|||||||
package com.dfsek.terra.api.event.events.config;
|
package com.dfsek.terra.api.event.events.config;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.config.ConfigTemplate;
|
||||||
|
import com.dfsek.tectonic.exception.ConfigException;
|
||||||
import com.dfsek.terra.config.pack.ConfigPack;
|
import com.dfsek.terra.config.pack.ConfigPack;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called before a config pack's registries are filled. At this point, the pack manifest has been loaded, and all registries are empty.
|
* Called before a config pack's registries are filled. At this point, the pack manifest has been loaded, and all registries are empty.
|
||||||
*/
|
*/
|
||||||
public class ConfigPackPreLoadEvent extends ConfigPackLoadEvent {
|
public class ConfigPackPreLoadEvent extends ConfigPackLoadEvent {
|
||||||
public ConfigPackPreLoadEvent(ConfigPack pack) {
|
public ConfigPackPreLoadEvent(ConfigPack pack, ExceptionalConsumer<ConfigTemplate> configLoader) {
|
||||||
super(pack);
|
super(pack, configLoader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
package com.dfsek.terra.api.transform;
|
|
||||||
|
|
||||||
public class NotNullValidator<T> implements Validator<T> {
|
|
||||||
@Override
|
|
||||||
public boolean validate(T value) {
|
|
||||||
return !(value == null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,12 @@
|
|||||||
package com.dfsek.terra.api.transform;
|
package com.dfsek.terra.api.transform;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public interface Validator<T> {
|
public interface Validator<T> {
|
||||||
boolean validate(T value) throws TransformException;
|
boolean validate(T value) throws TransformException;
|
||||||
|
|
||||||
|
static <T> Validator<T> notNull() {
|
||||||
|
return Objects::nonNull;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@ package com.dfsek.terra.config.pack;
|
|||||||
|
|
||||||
import com.dfsek.paralithic.eval.parser.Scope;
|
import com.dfsek.paralithic.eval.parser.Scope;
|
||||||
import com.dfsek.tectonic.abstraction.AbstractConfigLoader;
|
import com.dfsek.tectonic.abstraction.AbstractConfigLoader;
|
||||||
|
import com.dfsek.tectonic.config.Configuration;
|
||||||
import com.dfsek.tectonic.exception.ConfigException;
|
import com.dfsek.tectonic.exception.ConfigException;
|
||||||
import com.dfsek.tectonic.exception.LoadException;
|
import com.dfsek.tectonic.exception.LoadException;
|
||||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||||
@@ -110,6 +111,8 @@ public class ConfigPack implements LoaderRegistrar {
|
|||||||
private final TerraPlugin main;
|
private final TerraPlugin main;
|
||||||
private final Loader loader;
|
private final Loader loader;
|
||||||
|
|
||||||
|
private final Configuration configuration;
|
||||||
|
|
||||||
private final BiomeProvider.BiomeProviderBuilder biomeProviderBuilder;
|
private final BiomeProvider.BiomeProviderBuilder biomeProviderBuilder;
|
||||||
|
|
||||||
|
|
||||||
@@ -130,11 +133,15 @@ public class ConfigPack implements LoaderRegistrar {
|
|||||||
File pack = new File(folder, "pack.yml");
|
File pack = new File(folder, "pack.yml");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
selfLoader.load(template, new FileInputStream(pack));
|
configuration = new Configuration(new FileInputStream(pack));
|
||||||
|
selfLoader.load(template, configuration);
|
||||||
|
|
||||||
main.logger().info("Loading config pack \"" + template.getID() + "\"");
|
main.logger().info("Loading config pack \"" + template.getID() + "\"");
|
||||||
|
|
||||||
|
main.getEventManager().callEvent(new ConfigPackPreLoadEvent(this, template -> selfLoader.load(template, configuration)));
|
||||||
|
|
||||||
load(l, main);
|
load(l, main);
|
||||||
|
|
||||||
ConfigPackPostTemplate packPostTemplate = new ConfigPackPostTemplate();
|
ConfigPackPostTemplate packPostTemplate = new ConfigPackPostTemplate();
|
||||||
selfLoader.load(packPostTemplate, new FileInputStream(pack));
|
selfLoader.load(packPostTemplate, new FileInputStream(pack));
|
||||||
biomeProviderBuilder = packPostTemplate.getProviderBuilder();
|
biomeProviderBuilder = packPostTemplate.getProviderBuilder();
|
||||||
@@ -174,9 +181,12 @@ public class ConfigPack implements LoaderRegistrar {
|
|||||||
|
|
||||||
if(pack == null) throw new LoadException("No pack.yml file found in " + file.getName());
|
if(pack == null) throw new LoadException("No pack.yml file found in " + file.getName());
|
||||||
|
|
||||||
selfLoader.load(template, file.getInputStream(pack));
|
configuration = new Configuration(file.getInputStream(pack));
|
||||||
|
selfLoader.load(template, configuration);
|
||||||
main.logger().info("Loading config pack \"" + template.getID() + "\"");
|
main.logger().info("Loading config pack \"" + template.getID() + "\"");
|
||||||
|
|
||||||
|
main.getEventManager().callEvent(new ConfigPackPreLoadEvent(this, template -> selfLoader.load(template, configuration)));
|
||||||
|
|
||||||
load(l, main);
|
load(l, main);
|
||||||
|
|
||||||
ConfigPackPostTemplate packPostTemplate = new ConfigPackPostTemplate();
|
ConfigPackPostTemplate packPostTemplate = new ConfigPackPostTemplate();
|
||||||
@@ -211,8 +221,6 @@ public class ConfigPack implements LoaderRegistrar {
|
|||||||
|
|
||||||
|
|
||||||
private void load(long start, TerraPlugin main) throws ConfigException {
|
private void load(long start, TerraPlugin main) throws ConfigException {
|
||||||
main.getEventManager().callEvent(new ConfigPackPreLoadEvent(this));
|
|
||||||
|
|
||||||
for(Map.Entry<String, Double> var : template.getVariables().entrySet()) {
|
for(Map.Entry<String, Double> var : template.getVariables().entrySet()) {
|
||||||
varScope.create(var.getKey(), var.getValue());
|
varScope.create(var.getKey(), var.getValue());
|
||||||
}
|
}
|
||||||
@@ -245,7 +253,7 @@ public class ConfigPack implements LoaderRegistrar {
|
|||||||
.open("flora", ".yml").then(configs -> buildAll(new FloraFactory(), floraRegistry, abstractConfigLoader.loadConfigs(configs, FloraTemplate::new), main)).close()
|
.open("flora", ".yml").then(configs -> buildAll(new FloraFactory(), floraRegistry, abstractConfigLoader.loadConfigs(configs, FloraTemplate::new), main)).close()
|
||||||
.open("biomes", ".yml").then(configs -> buildAll(new BiomeFactory(this), biomeRegistry, abstractConfigLoader.loadConfigs(configs, () -> new BiomeTemplate(this, main)), main)).close();
|
.open("biomes", ".yml").then(configs -> buildAll(new BiomeFactory(this), biomeRegistry, abstractConfigLoader.loadConfigs(configs, () -> new BiomeTemplate(this, main)), main)).close();
|
||||||
|
|
||||||
main.getEventManager().callEvent(new ConfigPackPostLoadEvent(this));
|
main.getEventManager().callEvent(new ConfigPackPostLoadEvent(this, template -> selfLoader.load(template, configuration)));
|
||||||
main.logger().info("Loaded config pack \"" + template.getID() + "\" v" + template.getVersion() + " by " + template.getAuthor() + " in " + (System.nanoTime() - start) / 1000000D + "ms.");
|
main.logger().info("Loaded config pack \"" + template.getID() + "\" v" + template.getVersion() + " by " + template.getAuthor() + " in " + (System.nanoTime() - start) / 1000000D + "ms.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,122 @@
|
|||||||
|
enable:
|
||||||
|
- "Pokud se vám líbí Terra, můžete nás podpořit na Patreon!"
|
||||||
|
- "Získáte přístup k experimentálním funkcím, než budou vydány!"
|
||||||
|
- "Podpořit projekt můžete zde: https://www.patreon.com/dfsek"
|
||||||
|
disable:
|
||||||
|
- "Děkujeme, že používáte Terra!"
|
||||||
|
command:
|
||||||
|
debug-only: "Tento příkaz musí být použit se zapnutým debug modem!"
|
||||||
|
player-only: "Tento příkaz je pouze pro hráče!"
|
||||||
|
invalid: "Neznámý příkaz. (Očekáváno %1$s argumentů, nalezeno %2$s)."
|
||||||
|
players-only: "Příkaz je pouze pro použití hráčem."
|
||||||
|
world: "Tento příkaz musí být použit v Terra světě!"
|
||||||
|
reload: "Obnoven Terra konfig."
|
||||||
|
reload-error: "Nastaly chyby při obnově Terra konfigurace. Podívejte se do logů pro více informací."
|
||||||
|
version: "Na tomto serveru běží Terra verze \"%1$s\", na platformě \"%2$s\""
|
||||||
|
main-menu:
|
||||||
|
- "--------------------Terra--------------------"
|
||||||
|
- "reload - Obnoví konfigurační data"
|
||||||
|
- "biome - Ukáže aktuální biom"
|
||||||
|
- "ore - Generuje žílu rud v lokaci, ve směru kam se koukáte (Pro debugging)"
|
||||||
|
- "save-data - Uložit populační data"
|
||||||
|
- "structure - Nahrát a exportovat struktury"
|
||||||
|
- "profile - Profiler možnosti"
|
||||||
|
- "image - Obrázek/GUI možnosti"
|
||||||
|
biome:
|
||||||
|
biome-found: "Lokalizován biom na (%1$s, %2$s)"
|
||||||
|
unable-to-locate: "Nelze lokalizovat biom."
|
||||||
|
invalid-radius: "Nesprávný radius: \"%s\""
|
||||||
|
invalid: "Nesprávné ID bomu: \"%s\""
|
||||||
|
in: "Jste v \"%s\""
|
||||||
|
packs:
|
||||||
|
main: "Aktuální instalované konfigurační balíčky:"
|
||||||
|
pack: " - %1$s v%3$s od %2$s"
|
||||||
|
none: "Žádné konfigurační balíčky nejsou nainstalovány."
|
||||||
|
ore:
|
||||||
|
main-menu:
|
||||||
|
- "---------------Terra/ore---------------"
|
||||||
|
- "Generuje žílu rud na bloku, na který koukáte."
|
||||||
|
out-of-range: "Blok mimo dosah"
|
||||||
|
invalid-ore: "Nelze nalézt Rudu \"%s\""
|
||||||
|
geometry:
|
||||||
|
main-menu:
|
||||||
|
- "---------------Terra/geometry----------------"
|
||||||
|
- "Různé voxel geometrické debugging příkazy"
|
||||||
|
- "sphere - Generuje kouli"
|
||||||
|
- "deformsphere - Generuje deformovanou kouli"
|
||||||
|
- "tube - Generuje válec"
|
||||||
|
deform:
|
||||||
|
invalid-radius: "Nesprávný radius: \"%s\""
|
||||||
|
invalid-deform: "Nesprávná deformace: \"%s\""
|
||||||
|
invalid-frequency: "Nesprávná frekvence: \"%s\""
|
||||||
|
sphere:
|
||||||
|
invalid-radius: "Nesprávný radius: \"%s\""
|
||||||
|
tube:
|
||||||
|
invalid-radius: "Nesprávný radius: \"%s\""
|
||||||
|
image:
|
||||||
|
main-menu:
|
||||||
|
- "---------------Terra/image---------------"
|
||||||
|
- "render - Vykreslí obrázek s danou šířkou a výškou, který může být později importován jako svět."
|
||||||
|
- "gui - Otevřít debug GUI (Musí být zapnuto v konfigu)"
|
||||||
|
gui:
|
||||||
|
main-menu:
|
||||||
|
- "-------------Terra/image/gui-------------"
|
||||||
|
- "raw - Otevře GUI s raw Biom daty"
|
||||||
|
- "step - Znovu vykreslí data k lepšímu zobrazení borderu"
|
||||||
|
debug: "Debug mod musí být zapnutý pro použití této možnosti! Debug GUI NENÍ PRODUKČNĚ BEZPEČNÉ!"
|
||||||
|
render:
|
||||||
|
save: "Uložen obrázek jako \"%s\""
|
||||||
|
error: "Nastala chyba při generování obrázku!"
|
||||||
|
profile:
|
||||||
|
main-menu:
|
||||||
|
- "---------------Terra/profile---------------"
|
||||||
|
- "start - Zapne profiler"
|
||||||
|
- "stop - Vypne profiler"
|
||||||
|
- "query - Ukáže profiler data"
|
||||||
|
- "reset - Resetuje profiler data"
|
||||||
|
reset: "Profiler byl resetován."
|
||||||
|
start: "Profiler byl zapnut."
|
||||||
|
stop: "Profiler byl vypnut."
|
||||||
|
structure:
|
||||||
|
main-menu:
|
||||||
|
- "---------------Terra/structure---------------"
|
||||||
|
- "export - Export vašeho výběru WorldEdit jako Terra struktura."
|
||||||
|
- "load - Načíst Terra strukturu"
|
||||||
|
invalid-radius: "Nesprávný radius: \"%s\""
|
||||||
|
invalid-rotation: "Nesprávná rotace: \"%s\""
|
||||||
|
invalid: "Nesprávné ID struktury: \"%s\""
|
||||||
|
export: "Uložena struktura do \"%s\""
|
||||||
|
world-config:
|
||||||
|
load: "Načteny konfigurační hodnoty světa pro svět \"%s\"..."
|
||||||
|
not-found: "Konfigurace pro svět \"%s\" nenalezena. Kopíruji defaultní konfig."
|
||||||
|
using-image: "Načítám svět z obrázku."
|
||||||
|
error: "Nelze načíst konfigurace pro svět %s"
|
||||||
|
done: "Načítání světa \"%1$s\" dokončeno. Uplynulý čas: %2$sms"
|
||||||
|
config-pack:
|
||||||
|
loaded: "Konfigurační balíček %1$s v%4$s od %3$s byl načten za %2$sms."
|
||||||
|
config:
|
||||||
|
loaded: "Načten %1$s ze souboru %2$s"
|
||||||
|
loaded-all: "Načteno %1$s %2$s(s) za %3$sms."
|
||||||
|
error:
|
||||||
|
invalid-failover: "Nesprávný typ failover: \"%s\""
|
||||||
|
duplicate: "Duplikační ID nalezeno v souboru: %s"
|
||||||
|
file:
|
||||||
|
- "Konfigurační chyba pro Terra objekt. Soubor: %1$s"
|
||||||
|
- "%2$s"
|
||||||
|
- "Opravte jej před pokračováním!"
|
||||||
|
generic:
|
||||||
|
- "Nastala chyba při načítání konfigurace."
|
||||||
|
- "Prosíme nahlašte to na Terra."
|
||||||
|
warning:
|
||||||
|
no-population: "Žádné populační chunky nebyly načteny. Pokud je to poprvé, co zapínáte server s Terra, či vytváříte nový svět, je tohle normální."
|
||||||
|
error:
|
||||||
|
severe-config: "Vážná konfigurační chyba zabránila Terra ze správné generace terénu na koordinátech: %1$s, %2$s. Prosíme zkontrolujte konfiguraci pro chyby. Jakékoli konfigurační chyby jsou vypsány výše."
|
||||||
|
debug:
|
||||||
|
data-save : "Uložena populační data."
|
||||||
|
use-paper:
|
||||||
|
- "Vypadá to, že používáte Spigot/CraftBukkit."
|
||||||
|
- "Ačkoli Terra &ofunguje&r na Spigot, některé funkce budou ztraceny. (Terra je netestována na CraftBukkit; žádná podpora nebude dána pro CraftBukkit)."
|
||||||
|
- "Pro nejvíce funkcí s Terra, použijte Paper."
|
||||||
|
- "Navíc, Paper přináší obrovské výkonnostní zlepešení než Spigot, a všechny Spigot pluginy by měli fungovat s Paper!"
|
||||||
|
- "Pro nejlepší zážitek s Terra a všemi pluginy, použijte prosím Paper."
|
||||||
|
- "Více info najdete na stránce Paperu: https://papermc.io/"
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
package com.dfsek.terra.fabric;
|
package com.dfsek.terra.fabric;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.exception.ConfigException;
|
||||||
|
import com.dfsek.tectonic.exception.LoadException;
|
||||||
import com.dfsek.tectonic.loading.TypeRegistry;
|
import com.dfsek.tectonic.loading.TypeRegistry;
|
||||||
import com.dfsek.terra.api.TerraPlugin;
|
import com.dfsek.terra.api.TerraPlugin;
|
||||||
import com.dfsek.terra.api.addons.TerraAddon;
|
import com.dfsek.terra.api.addons.TerraAddon;
|
||||||
@@ -14,6 +16,7 @@ import com.dfsek.terra.api.event.EventManager;
|
|||||||
import com.dfsek.terra.api.event.TerraEventManager;
|
import com.dfsek.terra.api.event.TerraEventManager;
|
||||||
import com.dfsek.terra.api.event.annotations.Global;
|
import com.dfsek.terra.api.event.annotations.Global;
|
||||||
import com.dfsek.terra.api.event.annotations.Priority;
|
import com.dfsek.terra.api.event.annotations.Priority;
|
||||||
|
import com.dfsek.terra.api.event.events.config.ConfigPackPostLoadEvent;
|
||||||
import com.dfsek.terra.api.event.events.config.ConfigPackPreLoadEvent;
|
import com.dfsek.terra.api.event.events.config.ConfigPackPreLoadEvent;
|
||||||
import com.dfsek.terra.api.platform.block.BlockData;
|
import com.dfsek.terra.api.platform.block.BlockData;
|
||||||
import com.dfsek.terra.api.platform.handle.ItemHandle;
|
import com.dfsek.terra.api.platform.handle.ItemHandle;
|
||||||
@@ -22,94 +25,87 @@ import com.dfsek.terra.api.platform.world.Tree;
|
|||||||
import com.dfsek.terra.api.platform.world.World;
|
import com.dfsek.terra.api.platform.world.World;
|
||||||
import com.dfsek.terra.api.registry.CheckedRegistry;
|
import com.dfsek.terra.api.registry.CheckedRegistry;
|
||||||
import com.dfsek.terra.api.registry.LockedRegistry;
|
import com.dfsek.terra.api.registry.LockedRegistry;
|
||||||
import com.dfsek.terra.api.transform.NotNullValidator;
|
|
||||||
import com.dfsek.terra.api.transform.Transformer;
|
import com.dfsek.terra.api.transform.Transformer;
|
||||||
|
import com.dfsek.terra.api.transform.Validator;
|
||||||
|
import com.dfsek.terra.api.util.generic.pair.Pair;
|
||||||
import com.dfsek.terra.api.util.logging.DebugLogger;
|
import com.dfsek.terra.api.util.logging.DebugLogger;
|
||||||
import com.dfsek.terra.api.util.logging.Logger;
|
import com.dfsek.terra.api.util.logging.Logger;
|
||||||
import com.dfsek.terra.commands.CommandUtil;
|
import com.dfsek.terra.commands.CommandUtil;
|
||||||
import com.dfsek.terra.config.GenericLoaders;
|
import com.dfsek.terra.config.GenericLoaders;
|
||||||
import com.dfsek.terra.config.PluginConfig;
|
import com.dfsek.terra.config.PluginConfig;
|
||||||
import com.dfsek.terra.config.builder.BiomeBuilder;
|
|
||||||
import com.dfsek.terra.config.lang.LangUtil;
|
import com.dfsek.terra.config.lang.LangUtil;
|
||||||
import com.dfsek.terra.config.lang.Language;
|
import com.dfsek.terra.config.lang.Language;
|
||||||
import com.dfsek.terra.config.pack.ConfigPack;
|
import com.dfsek.terra.config.pack.ConfigPack;
|
||||||
import com.dfsek.terra.config.templates.BiomeTemplate;
|
import com.dfsek.terra.fabric.config.PostLoadCompatibilityOptions;
|
||||||
|
import com.dfsek.terra.fabric.config.PreLoadCompatibilityOptions;
|
||||||
import com.dfsek.terra.fabric.generation.FabricChunkGeneratorWrapper;
|
import com.dfsek.terra.fabric.generation.FabricChunkGeneratorWrapper;
|
||||||
import com.dfsek.terra.fabric.generation.PopulatorFeature;
|
import com.dfsek.terra.fabric.generation.PopulatorFeature;
|
||||||
import com.dfsek.terra.fabric.generation.TerraBiomeSource;
|
import com.dfsek.terra.fabric.generation.TerraBiomeSource;
|
||||||
import com.dfsek.terra.fabric.handle.FabricItemHandle;
|
import com.dfsek.terra.fabric.handle.FabricItemHandle;
|
||||||
import com.dfsek.terra.fabric.handle.FabricWorldHandle;
|
import com.dfsek.terra.fabric.handle.FabricWorldHandle;
|
||||||
import com.dfsek.terra.fabric.mixin.access.BiomeEffectsAccessor;
|
import com.dfsek.terra.fabric.util.FabricUtil;
|
||||||
import com.dfsek.terra.fabric.mixin.access.GeneratorTypeAccessor;
|
|
||||||
import com.dfsek.terra.profiler.Profiler;
|
import com.dfsek.terra.profiler.Profiler;
|
||||||
import com.dfsek.terra.profiler.ProfilerImpl;
|
import com.dfsek.terra.profiler.ProfilerImpl;
|
||||||
import com.dfsek.terra.registry.exception.DuplicateEntryException;
|
import com.dfsek.terra.registry.exception.DuplicateEntryException;
|
||||||
import com.dfsek.terra.registry.master.AddonRegistry;
|
import com.dfsek.terra.registry.master.AddonRegistry;
|
||||||
import com.dfsek.terra.registry.master.ConfigRegistry;
|
import com.dfsek.terra.registry.master.ConfigRegistry;
|
||||||
import com.dfsek.terra.world.TerraWorld;
|
import com.dfsek.terra.world.TerraWorld;
|
||||||
import net.fabricmc.api.EnvType;
|
|
||||||
import net.fabricmc.api.ModInitializer;
|
import net.fabricmc.api.ModInitializer;
|
||||||
import net.fabricmc.loader.api.FabricLoader;
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.server.world.ServerWorld;
|
||||||
import net.minecraft.client.world.GeneratorType;
|
|
||||||
import net.minecraft.text.LiteralText;
|
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.registry.BuiltinRegistries;
|
import net.minecraft.util.registry.BuiltinRegistries;
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.util.registry.Registry;
|
||||||
import net.minecraft.util.registry.RegistryKey;
|
import net.minecraft.util.registry.RegistryKey;
|
||||||
|
import net.minecraft.world.WorldAccess;
|
||||||
import net.minecraft.world.biome.Biome;
|
import net.minecraft.world.biome.Biome;
|
||||||
import net.minecraft.world.biome.BiomeEffects;
|
import net.minecraft.world.dimension.DimensionType;
|
||||||
import net.minecraft.world.biome.GenerationSettings;
|
|
||||||
import net.minecraft.world.gen.GenerationStep;
|
|
||||||
import net.minecraft.world.gen.chunk.ChunkGenerator;
|
|
||||||
import net.minecraft.world.gen.chunk.ChunkGeneratorSettings;
|
|
||||||
import net.minecraft.world.gen.decorator.Decorator;
|
import net.minecraft.world.gen.decorator.Decorator;
|
||||||
import net.minecraft.world.gen.decorator.NopeDecoratorConfig;
|
import net.minecraft.world.gen.decorator.NopeDecoratorConfig;
|
||||||
import net.minecraft.world.gen.feature.ConfiguredFeature;
|
import net.minecraft.world.gen.feature.ConfiguredFeature;
|
||||||
import net.minecraft.world.gen.feature.ConfiguredFeatures;
|
import net.minecraft.world.gen.feature.ConfiguredFeatures;
|
||||||
import net.minecraft.world.gen.feature.DefaultFeatureConfig;
|
import net.minecraft.world.gen.feature.DefaultFeatureConfig;
|
||||||
import net.minecraft.world.gen.feature.FeatureConfig;
|
import net.minecraft.world.gen.feature.FeatureConfig;
|
||||||
import net.minecraft.world.gen.surfacebuilder.SurfaceBuilder;
|
|
||||||
import net.minecraft.world.gen.surfacebuilder.TernarySurfaceConfig;
|
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
|
public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
|
||||||
|
private final org.apache.logging.log4j.Logger log4jLogger = LogManager.getLogger();
|
||||||
public static final PopulatorFeature POPULATOR_FEATURE = new PopulatorFeature(DefaultFeatureConfig.CODEC);
|
public static final PopulatorFeature POPULATOR_FEATURE = new PopulatorFeature(DefaultFeatureConfig.CODEC);
|
||||||
public static final ConfiguredFeature<?, ?> POPULATOR_CONFIGURED_FEATURE = POPULATOR_FEATURE.configure(FeatureConfig.DEFAULT).decorate(Decorator.NOPE.configure(NopeDecoratorConfig.INSTANCE));
|
public static final ConfiguredFeature<?, ?> POPULATOR_CONFIGURED_FEATURE = POPULATOR_FEATURE.configure(FeatureConfig.DEFAULT).decorate(Decorator.NOPE.configure(NopeDecoratorConfig.INSTANCE));
|
||||||
private static TerraFabricPlugin instance;
|
private static TerraFabricPlugin instance;
|
||||||
private final Map<Long, TerraWorld> worldMap = new HashMap<>();
|
private final Map<DimensionType, Pair<ServerWorld, TerraWorld>> worldMap = new HashMap<>();
|
||||||
|
|
||||||
|
public Map<DimensionType, Pair<ServerWorld, TerraWorld>> getWorldMap() {
|
||||||
|
return worldMap;
|
||||||
|
}
|
||||||
|
|
||||||
private final EventManager eventManager = new TerraEventManager(this);
|
private final EventManager eventManager = new TerraEventManager(this);
|
||||||
private final GenericLoaders genericLoaders = new GenericLoaders(this);
|
private final GenericLoaders genericLoaders = new GenericLoaders(this);
|
||||||
|
|
||||||
private final Profiler profiler = new ProfilerImpl();
|
private final Profiler profiler = new ProfilerImpl();
|
||||||
|
|
||||||
private final Logger logger = new Logger() {
|
private final Logger logger = new Logger() {
|
||||||
private final org.apache.logging.log4j.Logger logger = LogManager.getLogger();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void info(String message) {
|
public void info(String message) {
|
||||||
logger.info(message);
|
log4jLogger.info(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void warning(String message) {
|
public void warning(String message) {
|
||||||
logger.warn(message);
|
log4jLogger.warn(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void severe(String message) {
|
public void severe(String message) {
|
||||||
logger.error(message);
|
log4jLogger.error(message);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -118,12 +114,16 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
|
|||||||
private final WorldHandle worldHandle = new FabricWorldHandle();
|
private final WorldHandle worldHandle = new FabricWorldHandle();
|
||||||
private final ConfigRegistry registry = new ConfigRegistry();
|
private final ConfigRegistry registry = new ConfigRegistry();
|
||||||
private final CheckedRegistry<ConfigPack> checkedRegistry = new CheckedRegistry<>(registry);
|
private final CheckedRegistry<ConfigPack> checkedRegistry = new CheckedRegistry<>(registry);
|
||||||
private final AddonRegistry addonRegistry = new AddonRegistry(new FabricAddon(this), this);
|
|
||||||
|
private final FabricAddon fabricAddon = new FabricAddon(this);
|
||||||
|
private final AddonRegistry addonRegistry = new AddonRegistry(fabricAddon, this);
|
||||||
private final LockedRegistry<TerraAddon> addonLockedRegistry = new LockedRegistry<>(addonRegistry);
|
private final LockedRegistry<TerraAddon> addonLockedRegistry = new LockedRegistry<>(addonRegistry);
|
||||||
|
|
||||||
private final PluginConfig config = new PluginConfig();
|
private final PluginConfig config = new PluginConfig();
|
||||||
|
|
||||||
private final Transformer<String, Biome> biomeFixer = new Transformer.Builder<String, Biome>()
|
private final Transformer<String, Biome> biomeFixer = new Transformer.Builder<String, Biome>()
|
||||||
.addTransform(id -> BuiltinRegistries.BIOME.get(Identifier.tryParse(id)), new NotNullValidator<>())
|
.addTransform(id -> BuiltinRegistries.BIOME.get(Identifier.tryParse(id)), Validator.notNull())
|
||||||
.addTransform(id -> BuiltinRegistries.BIOME.get(Identifier.tryParse("minecraft:" + id.toLowerCase())), new NotNullValidator<>()).build();
|
.addTransform(id -> BuiltinRegistries.BIOME.get(Identifier.tryParse("minecraft:" + id.toLowerCase())), Validator.notNull()).build();
|
||||||
private File dataFolder;
|
private File dataFolder;
|
||||||
private final CommandManager manager = new TerraCommandManager(this);
|
private final CommandManager manager = new TerraCommandManager(this);
|
||||||
|
|
||||||
@@ -135,10 +135,6 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String createBiomeID(ConfigPack pack, String biomeID) {
|
|
||||||
return pack.getTemplate().getID().toLowerCase() + "/" + biomeID.toLowerCase(Locale.ROOT);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WorldHandle getWorldHandle() {
|
public WorldHandle getWorldHandle() {
|
||||||
return worldHandle;
|
return worldHandle;
|
||||||
@@ -146,15 +142,12 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TerraWorld getWorld(World world) {
|
public TerraWorld getWorld(World world) {
|
||||||
return worldMap.computeIfAbsent(world.getSeed(), w -> {
|
return getWorld(((WorldAccess) world).getDimension());
|
||||||
logger.info("Loading world " + w);
|
|
||||||
return new TerraWorld(world, ((FabricChunkGeneratorWrapper) world.getGenerator()).getPack(), this);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TerraWorld getWorld(long seed) {
|
public TerraWorld getWorld(DimensionType type) {
|
||||||
TerraWorld world = worldMap.get(seed);
|
TerraWorld world = worldMap.get(type).getRight();
|
||||||
if(world == null) throw new IllegalArgumentException("No world exists with seed " + seed);
|
if(world == null) throw new IllegalArgumentException("No world exists with dimension type " + type);
|
||||||
return world;
|
return world;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,7 +168,7 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isDebug() {
|
public boolean isDebug() {
|
||||||
return true;
|
return config.isDebug();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -198,14 +191,11 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
|
|||||||
config.load(this);
|
config.load(this);
|
||||||
LangUtil.load(config.getLanguage(), this); // Load language.
|
LangUtil.load(config.getLanguage(), this); // Load language.
|
||||||
boolean succeed = registry.loadAll(this);
|
boolean succeed = registry.loadAll(this);
|
||||||
Map<Long, TerraWorld> newMap = new HashMap<>();
|
worldMap.forEach((seed, pair) -> {
|
||||||
worldMap.forEach((seed, tw) -> {
|
pair.getRight().getConfig().getSamplerCache().clear();
|
||||||
tw.getConfig().getSamplerCache().clear();
|
String packID = pair.getRight().getConfig().getTemplate().getID();
|
||||||
String packID = tw.getConfig().getTemplate().getID();
|
pair.setRight(new TerraWorld(pair.getRight().getWorld(), registry.get(packID), this));
|
||||||
newMap.put(seed, new TerraWorld(tw.getWorld(), registry.get(packID), this));
|
|
||||||
});
|
});
|
||||||
worldMap.clear();
|
|
||||||
worldMap.putAll(newMap);
|
|
||||||
return succeed;
|
return succeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,71 +229,19 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
|
|||||||
genericLoaders.register(registry);
|
genericLoaders.register(registry);
|
||||||
registry
|
registry
|
||||||
.registerLoader(BlockData.class, (t, o, l) -> worldHandle.createBlockData((String) o))
|
.registerLoader(BlockData.class, (t, o, l) -> worldHandle.createBlockData((String) o))
|
||||||
.registerLoader(com.dfsek.terra.api.platform.world.Biome.class, (t, o, l) -> biomeFixer.translate((String) o));
|
.registerLoader(com.dfsek.terra.api.platform.world.Biome.class, (t, o, l) -> biomeFixer.translate((String) o))
|
||||||
}
|
.registerLoader(Identifier.class, (t, o, l) -> {
|
||||||
|
Identifier identifier = Identifier.tryParse((String) o);
|
||||||
private Biome createBiome(BiomeBuilder biome) {
|
if(identifier == null) throw new LoadException("Invalid identifier: " + o);
|
||||||
BiomeTemplate template = biome.getTemplate();
|
return identifier;
|
||||||
Map<String, Integer> colors = template.getColors();
|
});
|
||||||
|
|
||||||
Biome vanilla = (Biome) (new ArrayList<>(biome.getVanillaBiomes().getContents()).get(0)).getHandle();
|
|
||||||
|
|
||||||
GenerationSettings.Builder generationSettings = new GenerationSettings.Builder();
|
|
||||||
generationSettings.surfaceBuilder(SurfaceBuilder.DEFAULT.withConfig(new TernarySurfaceConfig(Blocks.GRASS_BLOCK.getDefaultState(), Blocks.DIRT.getDefaultState(), Blocks.GRAVEL.getDefaultState()))); // It needs a surfacebuilder, even though we dont use it.
|
|
||||||
generationSettings.feature(GenerationStep.Feature.VEGETAL_DECORATION, POPULATOR_CONFIGURED_FEATURE);
|
|
||||||
|
|
||||||
|
|
||||||
BiomeEffectsAccessor accessor = (BiomeEffectsAccessor) vanilla.getEffects();
|
|
||||||
BiomeEffects.Builder effects = new BiomeEffects.Builder()
|
|
||||||
.waterColor(colors.getOrDefault("water", accessor.getWaterColor()))
|
|
||||||
.waterFogColor(colors.getOrDefault("water-fog", accessor.getWaterFogColor()))
|
|
||||||
.fogColor(colors.getOrDefault("fog", accessor.getFogColor()))
|
|
||||||
.skyColor(colors.getOrDefault("sky", accessor.getSkyColor()))
|
|
||||||
.grassColorModifier(accessor.getGrassColorModifier());
|
|
||||||
|
|
||||||
if(colors.containsKey("grass")) {
|
|
||||||
effects.grassColor(colors.get("grass"));
|
|
||||||
} else {
|
|
||||||
accessor.getGrassColor().ifPresent(effects::grassColor);
|
|
||||||
}
|
|
||||||
if(colors.containsKey("foliage")) {
|
|
||||||
effects.foliageColor(colors.get("foliage"));
|
|
||||||
} else {
|
|
||||||
accessor.getFoliageColor().ifPresent(effects::foliageColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Biome.Builder()
|
|
||||||
.precipitation(vanilla.getPrecipitation())
|
|
||||||
.category(vanilla.getCategory())
|
|
||||||
.depth(vanilla.getDepth())
|
|
||||||
.scale(vanilla.getScale())
|
|
||||||
.temperature(vanilla.getTemperature())
|
|
||||||
.downfall(vanilla.getDownfall())
|
|
||||||
.effects(effects.build())
|
|
||||||
.spawnSettings(vanilla.getSpawnSettings())
|
|
||||||
.generationSettings(generationSettings.build())
|
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void packInit() {
|
public void packInit() {
|
||||||
logger.info("Loading config packs...");
|
logger.info("Loading config packs...");
|
||||||
registry.loadAll(this);
|
registry.loadAll(this);
|
||||||
|
|
||||||
registry.forEach(pack -> pack.getBiomeRegistry().forEach((id, biome) -> Registry.register(BuiltinRegistries.BIOME, new Identifier("terra", createBiomeID(pack, id)), createBiome(biome)))); // Register all Terra biomes.
|
registry.forEach(pack -> pack.getBiomeRegistry().forEach((id, biome) -> Registry.register(BuiltinRegistries.BIOME, new Identifier("terra", FabricUtil.createBiomeID(pack, id)), FabricUtil.createBiome(fabricAddon, biome, pack)))); // Register all Terra biomes.
|
||||||
|
|
||||||
if(FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) {
|
|
||||||
registry.forEach(pack -> {
|
|
||||||
final GeneratorType generatorType = new GeneratorType("terra." + pack.getTemplate().getID()) {
|
|
||||||
@Override
|
|
||||||
protected ChunkGenerator getChunkGenerator(Registry<Biome> biomeRegistry, Registry<ChunkGeneratorSettings> chunkGeneratorSettingsRegistry, long seed) {
|
|
||||||
return new FabricChunkGeneratorWrapper(new TerraBiomeSource(biomeRegistry, seed, pack), seed, pack);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
//noinspection ConstantConditions
|
|
||||||
((GeneratorTypeAccessor) generatorType).setTranslationKey(new LiteralText("Terra:" + pack.getTemplate().getID()));
|
|
||||||
GeneratorTypeAccessor.getValues().add(generatorType);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.info("Loaded packs.");
|
logger.info("Loaded packs.");
|
||||||
}
|
}
|
||||||
@@ -315,6 +253,7 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
|
|||||||
this.dataFolder = new File(FabricLoader.getInstance().getConfigDir().toFile(), "Terra");
|
this.dataFolder = new File(FabricLoader.getInstance().getConfigDir().toFile(), "Terra");
|
||||||
saveDefaultConfig();
|
saveDefaultConfig();
|
||||||
config.load(this);
|
config.load(this);
|
||||||
|
debugLogger.setDebug(config.isDebug());
|
||||||
LangUtil.load(config.getLanguage(), this);
|
LangUtil.load(config.getLanguage(), this);
|
||||||
logger.info("Initializing Terra...");
|
logger.info("Initializing Terra...");
|
||||||
|
|
||||||
@@ -324,9 +263,8 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
|
|||||||
logger.info("Loaded addons.");
|
logger.info("Loaded addons.");
|
||||||
|
|
||||||
|
|
||||||
|
Registry.register(Registry.FEATURE, new Identifier("terra", "populator"), POPULATOR_FEATURE);
|
||||||
Registry.register(Registry.FEATURE, new Identifier("terra", "flora_populator"), POPULATOR_FEATURE);
|
RegistryKey<ConfiguredFeature<?, ?>> floraKey = RegistryKey.of(Registry.CONFIGURED_FEATURE_WORLDGEN, new Identifier("terra", "populator"));
|
||||||
RegistryKey<ConfiguredFeature<?, ?>> floraKey = RegistryKey.of(Registry.CONFIGURED_FEATURE_WORLDGEN, new Identifier("terra", "flora_populator"));
|
|
||||||
Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, floraKey.getValue(), POPULATOR_CONFIGURED_FEATURE);
|
Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, floraKey.getValue(), POPULATOR_CONFIGURED_FEATURE);
|
||||||
|
|
||||||
Registry.register(Registry.CHUNK_GENERATOR, new Identifier("terra:terra"), FabricChunkGeneratorWrapper.CODEC);
|
Registry.register(Registry.CHUNK_GENERATOR, new Identifier("terra:terra"), FabricChunkGeneratorWrapper.CODEC);
|
||||||
@@ -355,10 +293,12 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
|
|||||||
@Addon("Terra-Fabric")
|
@Addon("Terra-Fabric")
|
||||||
@Author("Terra")
|
@Author("Terra")
|
||||||
@Version("1.0.0")
|
@Version("1.0.0")
|
||||||
private static final class FabricAddon extends TerraAddon implements EventListener {
|
public static final class FabricAddon extends TerraAddon implements EventListener {
|
||||||
|
|
||||||
private final TerraPlugin main;
|
private final TerraPlugin main;
|
||||||
|
|
||||||
|
private final Map<ConfigPack, Pair<PreLoadCompatibilityOptions, PostLoadCompatibilityOptions>> templates = new HashMap<>();
|
||||||
|
|
||||||
private FabricAddon(TerraPlugin main) {
|
private FabricAddon(TerraPlugin main) {
|
||||||
this.main = main;
|
this.main = main;
|
||||||
}
|
}
|
||||||
@@ -391,6 +331,40 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
|
|||||||
injectTree(treeRegistry, "MEGA_SPRUCE", ConfiguredFeatures.MEGA_SPRUCE);
|
injectTree(treeRegistry, "MEGA_SPRUCE", ConfiguredFeatures.MEGA_SPRUCE);
|
||||||
injectTree(treeRegistry, "CRIMSON_FUNGUS", ConfiguredFeatures.CRIMSON_FUNGI);
|
injectTree(treeRegistry, "CRIMSON_FUNGUS", ConfiguredFeatures.CRIMSON_FUNGI);
|
||||||
injectTree(treeRegistry, "WARPED_FUNGUS", ConfiguredFeatures.WARPED_FUNGI);
|
injectTree(treeRegistry, "WARPED_FUNGUS", ConfiguredFeatures.WARPED_FUNGI);
|
||||||
|
|
||||||
|
PreLoadCompatibilityOptions template = new PreLoadCompatibilityOptions();
|
||||||
|
try {
|
||||||
|
event.loadTemplate(template);
|
||||||
|
} catch(ConfigException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(template.doRegistryInjection()) {
|
||||||
|
BuiltinRegistries.CONFIGURED_FEATURE.getEntries().forEach(entry -> {
|
||||||
|
if(!template.getExcludedRegistryFeatures().contains(entry.getKey().getValue())) {
|
||||||
|
try {
|
||||||
|
event.getPack().getTreeRegistry().add(entry.getKey().getValue().toString(), (Tree) entry.getValue());
|
||||||
|
main.getDebugLogger().info("Injected ConfiguredFeature " + entry.getKey().getValue() + " as Tree.");
|
||||||
|
} catch(DuplicateEntryException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
templates.put(event.getPack(), Pair.of(template, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Priority(Priority.HIGHEST)
|
||||||
|
@Global
|
||||||
|
public void createInjectionOptions(ConfigPackPostLoadEvent event) {
|
||||||
|
PostLoadCompatibilityOptions template = new PostLoadCompatibilityOptions();
|
||||||
|
|
||||||
|
try {
|
||||||
|
event.loadTemplate(template);
|
||||||
|
} catch(ConfigException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
templates.get(event.getPack()).setRight(template);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -400,5 +374,9 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
|
|||||||
} catch(DuplicateEntryException ignore) {
|
} catch(DuplicateEntryException ignore) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<ConfigPack, Pair<PreLoadCompatibilityOptions, PostLoadCompatibilityOptions>> getTemplates() {
|
||||||
|
return templates;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
package com.dfsek.terra.fabric.config;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.annotations.Default;
|
||||||
|
import com.dfsek.tectonic.annotations.Value;
|
||||||
|
import com.dfsek.tectonic.config.ConfigTemplate;
|
||||||
|
import com.dfsek.terra.config.builder.BiomeBuilder;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@SuppressWarnings("FieldMayBeFinal")
|
||||||
|
public class PostLoadCompatibilityOptions implements ConfigTemplate {
|
||||||
|
@Value("structures.inject-biome.exclude-biomes")
|
||||||
|
@Default
|
||||||
|
private Map<BiomeBuilder, Set<Identifier>> excludedPerBiomeStructures = new HashMap<>();
|
||||||
|
|
||||||
|
@Value("features.inject-biome.exclude-biomes")
|
||||||
|
@Default
|
||||||
|
private Map<BiomeBuilder, Set<Identifier>> excludedPerBiomeFeatures = new HashMap<>();
|
||||||
|
|
||||||
|
public Map<BiomeBuilder, Set<Identifier>> getExcludedPerBiomeFeatures() {
|
||||||
|
return excludedPerBiomeFeatures;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<BiomeBuilder, Set<Identifier>> getExcludedPerBiomeStructures() {
|
||||||
|
return excludedPerBiomeStructures;
|
||||||
|
}
|
||||||
|
}
|
||||||
+55
@@ -0,0 +1,55 @@
|
|||||||
|
package com.dfsek.terra.fabric.config;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.annotations.Default;
|
||||||
|
import com.dfsek.tectonic.annotations.Value;
|
||||||
|
import com.dfsek.tectonic.config.ConfigTemplate;
|
||||||
|
import com.dfsek.terra.config.builder.BiomeBuilder;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@SuppressWarnings("FieldMayBeFinal")
|
||||||
|
public class PreLoadCompatibilityOptions implements ConfigTemplate {
|
||||||
|
@Value("features.inject-registry.enable")
|
||||||
|
@Default
|
||||||
|
private boolean doRegistryInjection = false;
|
||||||
|
|
||||||
|
@Value("features.inject-biome.enable")
|
||||||
|
@Default
|
||||||
|
private boolean doBiomeInjection = false;
|
||||||
|
|
||||||
|
@Value("features.inject-registry.excluded-features")
|
||||||
|
@Default
|
||||||
|
private Set<Identifier> excludedRegistryFeatures = new HashSet<>();
|
||||||
|
|
||||||
|
@Value("features.inject-biome.excluded-features")
|
||||||
|
@Default
|
||||||
|
private Set<Identifier> excludedBiomeFeatures = new HashSet<>();
|
||||||
|
|
||||||
|
@Value("structures.inject-biome.excluded-features")
|
||||||
|
@Default
|
||||||
|
private Set<Identifier> excludedBiomeStructures = new HashSet<>();
|
||||||
|
|
||||||
|
public boolean doBiomeInjection() {
|
||||||
|
return doBiomeInjection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean doRegistryInjection() {
|
||||||
|
return doRegistryInjection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Identifier> getExcludedBiomeFeatures() {
|
||||||
|
return excludedBiomeFeatures;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Identifier> getExcludedRegistryFeatures() {
|
||||||
|
return excludedRegistryFeatures;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Identifier> getExcludedBiomeStructures() {
|
||||||
|
return excludedBiomeStructures;
|
||||||
|
}
|
||||||
|
}
|
||||||
+44
-21
@@ -4,6 +4,7 @@ import com.dfsek.terra.api.platform.world.World;
|
|||||||
import com.dfsek.terra.api.platform.world.generator.ChunkData;
|
import com.dfsek.terra.api.platform.world.generator.ChunkData;
|
||||||
import com.dfsek.terra.api.platform.world.generator.GeneratorWrapper;
|
import com.dfsek.terra.api.platform.world.generator.GeneratorWrapper;
|
||||||
import com.dfsek.terra.api.util.FastRandom;
|
import com.dfsek.terra.api.util.FastRandom;
|
||||||
|
import com.dfsek.terra.api.world.biome.UserDefinedBiome;
|
||||||
import com.dfsek.terra.api.world.generation.TerraChunkGenerator;
|
import com.dfsek.terra.api.world.generation.TerraChunkGenerator;
|
||||||
import com.dfsek.terra.api.world.locate.AsyncStructureFinder;
|
import com.dfsek.terra.api.world.locate.AsyncStructureFinder;
|
||||||
import com.dfsek.terra.config.pack.ConfigPack;
|
import com.dfsek.terra.config.pack.ConfigPack;
|
||||||
@@ -27,9 +28,13 @@ import net.minecraft.util.registry.Registry;
|
|||||||
import net.minecraft.world.BlockView;
|
import net.minecraft.world.BlockView;
|
||||||
import net.minecraft.world.ChunkRegion;
|
import net.minecraft.world.ChunkRegion;
|
||||||
import net.minecraft.world.Heightmap;
|
import net.minecraft.world.Heightmap;
|
||||||
|
import net.minecraft.world.SpawnHelper;
|
||||||
import net.minecraft.world.WorldAccess;
|
import net.minecraft.world.WorldAccess;
|
||||||
|
import net.minecraft.world.biome.Biome;
|
||||||
import net.minecraft.world.biome.source.BiomeAccess;
|
import net.minecraft.world.biome.source.BiomeAccess;
|
||||||
import net.minecraft.world.chunk.Chunk;
|
import net.minecraft.world.chunk.Chunk;
|
||||||
|
import net.minecraft.world.dimension.DimensionType;
|
||||||
|
import net.minecraft.world.gen.ChunkRandom;
|
||||||
import net.minecraft.world.gen.GenerationStep;
|
import net.minecraft.world.gen.GenerationStep;
|
||||||
import net.minecraft.world.gen.StructureAccessor;
|
import net.minecraft.world.gen.StructureAccessor;
|
||||||
import net.minecraft.world.gen.chunk.ChunkGenerator;
|
import net.minecraft.world.gen.chunk.ChunkGenerator;
|
||||||
@@ -55,6 +60,7 @@ public class FabricChunkGeneratorWrapper extends ChunkGenerator implements Gener
|
|||||||
PACK_CODEC.fieldOf("pack").stable().forGetter(generator -> generator.pack))
|
PACK_CODEC.fieldOf("pack").stable().forGetter(generator -> generator.pack))
|
||||||
.apply(instance, instance.stable(FabricChunkGeneratorWrapper::new)));
|
.apply(instance, instance.stable(FabricChunkGeneratorWrapper::new)));
|
||||||
private final ConfigPack pack;
|
private final ConfigPack pack;
|
||||||
|
private DimensionType dimensionType;
|
||||||
|
|
||||||
public ConfigPack getPack() {
|
public ConfigPack getPack() {
|
||||||
return pack;
|
return pack;
|
||||||
@@ -87,26 +93,31 @@ public class FabricChunkGeneratorWrapper extends ChunkGenerator implements Gener
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setDimensionType(DimensionType dimensionType) {
|
||||||
|
this.dimensionType = dimensionType;
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public BlockPos locateStructure(ServerWorld world, StructureFeature<?> feature, BlockPos center, int radius, boolean skipExistingChunks) {
|
public BlockPos locateStructure(ServerWorld world, StructureFeature<?> feature, BlockPos center, int radius, boolean skipExistingChunks) {
|
||||||
String name = Objects.requireNonNull(Registry.STRUCTURE_FEATURE.getId(feature)).toString();
|
if(!pack.getTemplate().disableStructures()) {
|
||||||
TerraWorld terraWorld = TerraFabricPlugin.getInstance().getWorld((World) world);
|
String name = Objects.requireNonNull(Registry.STRUCTURE_FEATURE.getId(feature)).toString();
|
||||||
TerraStructure located = pack.getStructure(pack.getTemplate().getLocatable().get(name));
|
TerraWorld terraWorld = TerraFabricPlugin.getInstance().getWorld((World) world);
|
||||||
if(located != null) {
|
TerraStructure located = pack.getStructure(pack.getTemplate().getLocatable().get(name));
|
||||||
CompletableFuture<BlockPos> result = new CompletableFuture<>();
|
if(located != null) {
|
||||||
AsyncStructureFinder finder = new AsyncStructureFinder(terraWorld.getBiomeProvider(), located, FabricAdapter.adapt(center).toLocation((World) world), 0, 500, location -> {
|
CompletableFuture<BlockPos> result = new CompletableFuture<>();
|
||||||
result.complete(FabricAdapter.adapt(location));
|
AsyncStructureFinder finder = new AsyncStructureFinder(terraWorld.getBiomeProvider(), located, FabricAdapter.adapt(center).toLocation((World) world), 0, 500, location -> {
|
||||||
}, TerraFabricPlugin.getInstance());
|
result.complete(FabricAdapter.adapt(location));
|
||||||
finder.run(); // Do this synchronously.
|
}, TerraFabricPlugin.getInstance());
|
||||||
try {
|
finder.run(); // Do this synchronously.
|
||||||
return result.get();
|
try {
|
||||||
} catch(InterruptedException | ExecutionException e) {
|
return result.get();
|
||||||
throw new RuntimeException(e);
|
} catch(InterruptedException | ExecutionException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TerraFabricPlugin.getInstance().logger().warning("No overrides are defined for \"" + name + "\"");
|
return super.locateStructure(world, feature, center, radius, skipExistingChunks);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -127,32 +138,32 @@ public class FabricChunkGeneratorWrapper extends ChunkGenerator implements Gener
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isStrongholdStartingChunk(ChunkPos chunkPos) {
|
public boolean isStrongholdStartingChunk(ChunkPos chunkPos) {
|
||||||
|
if(pack.getTemplate().vanillaStructures()) return super.isStrongholdStartingChunk(chunkPos);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getHeight(int x, int z, Heightmap.Type heightmapType) {
|
public int getHeight(int x, int z, Heightmap.Type heightmapType) {
|
||||||
TerraWorld world = TerraFabricPlugin.getInstance().getWorld(seed);
|
TerraWorld world = TerraFabricPlugin.getInstance().getWorld(dimensionType);
|
||||||
Sampler sampler = world.getConfig().getSamplerCache().getChunk(FastMath.floorDiv(x, 16), FastMath.floorDiv(z, 16));
|
Sampler sampler = world.getConfig().getSamplerCache().getChunk(FastMath.floorDiv(x, 16), FastMath.floorDiv(z, 16));
|
||||||
int cx = FastMath.floorMod(x, 16);
|
int cx = FastMath.floorMod(x, 16);
|
||||||
int cz = FastMath.floorMod(z, 16);
|
int cz = FastMath.floorMod(z, 16);
|
||||||
|
|
||||||
int height = world.getWorld().getMaxHeight();
|
int height = world.getWorld().getMaxHeight();
|
||||||
|
|
||||||
while (height >= 0 && sampler.sample(cx, height - 1, cz) < 0) {
|
while(height >= 0 && sampler.sample(cx, height-1, cz) < 0) height--;
|
||||||
height--;
|
|
||||||
}
|
|
||||||
|
|
||||||
return height;
|
return height;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockView getColumnSample(int x, int z) {
|
public BlockView getColumnSample(int x, int z) {
|
||||||
int height = 64; // TODO: implementation
|
TerraWorld world = TerraFabricPlugin.getInstance().getWorld(dimensionType);
|
||||||
|
int height = getHeight(x, z, Heightmap.Type.WORLD_SURFACE);
|
||||||
BlockState[] array = new BlockState[256];
|
BlockState[] array = new BlockState[256];
|
||||||
for(int y = 255; y >= 0; y--) {
|
for(int y = 255; y >= 0; y--) {
|
||||||
if(y > height) {
|
if(y > height) {
|
||||||
if(y > getSeaLevel()) {
|
if(y > ((UserDefinedBiome) world.getBiomeProvider().getBiome(x, z)).getConfig().getSeaLevel()) {
|
||||||
array[y] = Blocks.AIR.getDefaultState();
|
array[y] = Blocks.AIR.getDefaultState();
|
||||||
} else {
|
} else {
|
||||||
array[y] = Blocks.WATER.getDefaultState();
|
array[y] = Blocks.WATER.getDefaultState();
|
||||||
@@ -165,6 +176,18 @@ public class FabricChunkGeneratorWrapper extends ChunkGenerator implements Gener
|
|||||||
return new VerticalBlockSample(array);
|
return new VerticalBlockSample(array);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void populateEntities(ChunkRegion region) {
|
||||||
|
if(pack.getTemplate().vanillaMobs()) {
|
||||||
|
int cx = region.getCenterChunkX();
|
||||||
|
int cy = region.getCenterChunkZ();
|
||||||
|
Biome biome = region.getBiome((new ChunkPos(cx, cy)).getStartPos());
|
||||||
|
ChunkRandom chunkRandom = new ChunkRandom();
|
||||||
|
chunkRandom.setPopulationSeed(region.getSeed(), cx << 4, cy << 4);
|
||||||
|
SpawnHelper.populateEntities(region, biome, cx, cy, chunkRandom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TerraChunkGenerator getHandle() {
|
public TerraChunkGenerator getHandle() {
|
||||||
return delegate;
|
return delegate;
|
||||||
|
|||||||
+6
-11
@@ -4,6 +4,7 @@ import com.dfsek.terra.api.world.biome.UserDefinedBiome;
|
|||||||
import com.dfsek.terra.api.world.biome.provider.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.provider.BiomeProvider;
|
||||||
import com.dfsek.terra.config.pack.ConfigPack;
|
import com.dfsek.terra.config.pack.ConfigPack;
|
||||||
import com.dfsek.terra.fabric.TerraFabricPlugin;
|
import com.dfsek.terra.fabric.TerraFabricPlugin;
|
||||||
|
import com.dfsek.terra.fabric.util.FabricUtil;
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
@@ -11,8 +12,8 @@ import net.minecraft.util.registry.Registry;
|
|||||||
import net.minecraft.util.registry.RegistryLookupCodec;
|
import net.minecraft.util.registry.RegistryLookupCodec;
|
||||||
import net.minecraft.world.biome.Biome;
|
import net.minecraft.world.biome.Biome;
|
||||||
import net.minecraft.world.biome.source.BiomeSource;
|
import net.minecraft.world.biome.source.BiomeSource;
|
||||||
import net.minecraft.world.gen.feature.StructureFeature;
|
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class TerraBiomeSource extends BiomeSource {
|
public class TerraBiomeSource extends BiomeSource {
|
||||||
@@ -31,7 +32,9 @@ public class TerraBiomeSource extends BiomeSource {
|
|||||||
private final ConfigPack pack;
|
private final ConfigPack pack;
|
||||||
|
|
||||||
public TerraBiomeSource(Registry<Biome> biomes, long seed, ConfigPack pack) {
|
public TerraBiomeSource(Registry<Biome> biomes, long seed, ConfigPack pack) {
|
||||||
super(biomes.stream().collect(Collectors.toList()));
|
super(biomes.stream()
|
||||||
|
.filter(biome -> Objects.requireNonNull(biomes.getId(biome)).getNamespace().equals("terra")) // Filter out non-Terra biomes.
|
||||||
|
.collect(Collectors.toList()));
|
||||||
this.biomeRegistry = biomes;
|
this.biomeRegistry = biomes;
|
||||||
this.seed = seed;
|
this.seed = seed;
|
||||||
this.grid = pack.getBiomeProviderBuilder().build(seed);
|
this.grid = pack.getBiomeProviderBuilder().build(seed);
|
||||||
@@ -51,14 +54,6 @@ public class TerraBiomeSource extends BiomeSource {
|
|||||||
@Override
|
@Override
|
||||||
public Biome getBiomeForNoiseGen(int biomeX, int biomeY, int biomeZ) {
|
public Biome getBiomeForNoiseGen(int biomeX, int biomeY, int biomeZ) {
|
||||||
UserDefinedBiome biome = (UserDefinedBiome) grid.getBiome(biomeX << 2, biomeZ << 2);
|
UserDefinedBiome biome = (UserDefinedBiome) grid.getBiome(biomeX << 2, biomeZ << 2);
|
||||||
return biomeRegistry.get(new Identifier("terra", TerraFabricPlugin.createBiomeID(pack, biome.getID())));
|
return biomeRegistry.get(new Identifier("terra", FabricUtil.createBiomeID(pack, biome.getID())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasStructureFeature(StructureFeature<?> feature) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
package com.dfsek.terra.fabric.generation;
|
||||||
|
|
||||||
|
import com.dfsek.terra.config.pack.ConfigPack;
|
||||||
|
import net.minecraft.client.world.GeneratorType;
|
||||||
|
import net.minecraft.util.registry.Registry;
|
||||||
|
import net.minecraft.world.biome.Biome;
|
||||||
|
import net.minecraft.world.gen.chunk.ChunkGenerator;
|
||||||
|
import net.minecraft.world.gen.chunk.ChunkGeneratorSettings;
|
||||||
|
|
||||||
|
public class TerraGeneratorType extends GeneratorType {
|
||||||
|
private final ConfigPack pack;
|
||||||
|
|
||||||
|
public TerraGeneratorType(ConfigPack pack) {
|
||||||
|
super("terra." + pack.getTemplate().getID());
|
||||||
|
this.pack = pack;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ChunkGenerator getChunkGenerator(Registry<Biome> biomeRegistry, Registry<ChunkGeneratorSettings> chunkGeneratorSettingsRegistry, long seed) {
|
||||||
|
return new FabricChunkGeneratorWrapper(new TerraBiomeSource(biomeRegistry, seed, pack), seed, pack);
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -31,7 +31,7 @@ public abstract class CommandManagerMixin {
|
|||||||
@Final
|
@Final
|
||||||
private CommandDispatcher<ServerCommandSource> dispatcher;
|
private CommandDispatcher<ServerCommandSource> dispatcher;
|
||||||
|
|
||||||
@Inject(method = "<init>", at = @At(value = "INVOKE", target = "Lcom/mojang/brigadier/CommandDispatcher;findAmbiguities(Lcom/mojang/brigadier/AmbiguityConsumer;)V"))
|
@Inject(method = "<init>", at = @At(value = "INVOKE", target = "Lcom/mojang/brigadier/CommandDispatcher;findAmbiguities(Lcom/mojang/brigadier/AmbiguityConsumer;)V", remap = false))
|
||||||
private void injectTerraCommands(CommandManager.RegistrationEnvironment environment, CallbackInfo ci) {
|
private void injectTerraCommands(CommandManager.RegistrationEnvironment environment, CallbackInfo ci) {
|
||||||
com.dfsek.terra.api.command.CommandManager manager = TerraFabricPlugin.getInstance().getManager();
|
com.dfsek.terra.api.command.CommandManager manager = TerraFabricPlugin.getInstance().getManager();
|
||||||
int max = manager.getMaxArgumentDepth();
|
int max = manager.getMaxArgumentDepth();
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.dfsek.terra.fabric.mixin;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.util.generic.pair.Pair;
|
||||||
|
import com.dfsek.terra.fabric.TerraFabricPlugin;
|
||||||
|
import com.dfsek.terra.fabric.generation.FabricChunkGeneratorWrapper;
|
||||||
|
import com.dfsek.terra.world.TerraWorld;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.server.WorldGenerationProgressListener;
|
||||||
|
import net.minecraft.server.world.ServerWorld;
|
||||||
|
import net.minecraft.util.registry.RegistryKey;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraft.world.dimension.DimensionType;
|
||||||
|
import net.minecraft.world.gen.Spawner;
|
||||||
|
import net.minecraft.world.gen.chunk.ChunkGenerator;
|
||||||
|
import net.minecraft.world.level.ServerWorldProperties;
|
||||||
|
import net.minecraft.world.level.storage.LevelStorage;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
@Mixin(ServerWorld.class)
|
||||||
|
public abstract class ServerWorldMixin {
|
||||||
|
@Inject(method = "<init>", at = @At(value = "RETURN"))
|
||||||
|
public void injectConstructor(MinecraftServer server, Executor workerExecutor, LevelStorage.Session session, ServerWorldProperties properties, RegistryKey<World> registryKey, DimensionType dimensionType, WorldGenerationProgressListener worldGenerationProgressListener, ChunkGenerator chunkGenerator, boolean debugWorld, long l, List<Spawner> list, boolean bl, CallbackInfo ci) {
|
||||||
|
if(chunkGenerator instanceof FabricChunkGeneratorWrapper) {
|
||||||
|
TerraFabricPlugin.getInstance().getWorldMap().put(dimensionType, Pair.of((ServerWorld) (Object) this, new TerraWorld((com.dfsek.terra.api.platform.world.World) this, ((FabricChunkGeneratorWrapper) chunkGenerator).getPack(), TerraFabricPlugin.getInstance())));
|
||||||
|
((FabricChunkGeneratorWrapper) chunkGenerator).setDimensionType(dimensionType);
|
||||||
|
TerraFabricPlugin.getInstance().logger().info("Registered world " + this + " to dimension type " + dimensionType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+10
@@ -1,8 +1,12 @@
|
|||||||
package com.dfsek.terra.fabric.mixin.init;
|
package com.dfsek.terra.fabric.mixin.init;
|
||||||
|
|
||||||
import com.dfsek.terra.fabric.TerraFabricPlugin;
|
import com.dfsek.terra.fabric.TerraFabricPlugin;
|
||||||
|
import com.dfsek.terra.fabric.generation.TerraGeneratorType;
|
||||||
|
import com.dfsek.terra.fabric.mixin.access.GeneratorTypeAccessor;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.RunArgs;
|
import net.minecraft.client.RunArgs;
|
||||||
|
import net.minecraft.client.world.GeneratorType;
|
||||||
|
import net.minecraft.text.LiteralText;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
@@ -15,5 +19,11 @@ public class MinecraftClientMixin {
|
|||||||
shift = At.Shift.BEFORE))
|
shift = At.Shift.BEFORE))
|
||||||
public void injectConstructor(RunArgs args, CallbackInfo callbackInfo) {
|
public void injectConstructor(RunArgs args, CallbackInfo callbackInfo) {
|
||||||
TerraFabricPlugin.getInstance().packInit(); // Load during MinecraftClient construction, after other mods have registered blocks and stuff
|
TerraFabricPlugin.getInstance().packInit(); // Load during MinecraftClient construction, after other mods have registered blocks and stuff
|
||||||
|
TerraFabricPlugin.getInstance().getConfigRegistry().forEach(pack -> {
|
||||||
|
final GeneratorType generatorType = new TerraGeneratorType(pack);
|
||||||
|
//noinspection ConstantConditions
|
||||||
|
((GeneratorTypeAccessor) generatorType).setTranslationKey(new LiteralText("Terra:" + pack.getTemplate().getID()));
|
||||||
|
GeneratorTypeAccessor.getValues().add(1, generatorType);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
package com.dfsek.terra.fabric.util;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.util.generic.pair.Pair;
|
||||||
|
import com.dfsek.terra.config.builder.BiomeBuilder;
|
||||||
|
import com.dfsek.terra.config.pack.ConfigPack;
|
||||||
|
import com.dfsek.terra.config.templates.BiomeTemplate;
|
||||||
|
import com.dfsek.terra.fabric.TerraFabricPlugin;
|
||||||
|
import com.dfsek.terra.fabric.config.PostLoadCompatibilityOptions;
|
||||||
|
import com.dfsek.terra.fabric.config.PreLoadCompatibilityOptions;
|
||||||
|
import com.dfsek.terra.fabric.mixin.access.BiomeEffectsAccessor;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.registry.BuiltinRegistries;
|
||||||
|
import net.minecraft.world.biome.Biome;
|
||||||
|
import net.minecraft.world.biome.BiomeEffects;
|
||||||
|
import net.minecraft.world.biome.GenerationSettings;
|
||||||
|
import net.minecraft.world.gen.GenerationStep;
|
||||||
|
import net.minecraft.world.gen.carver.ConfiguredCarver;
|
||||||
|
import net.minecraft.world.gen.feature.ConfiguredFeature;
|
||||||
|
import net.minecraft.world.gen.feature.ConfiguredStructureFeature;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public final class FabricUtil {
|
||||||
|
public static String createBiomeID(ConfigPack pack, String biomeID) {
|
||||||
|
return pack.getTemplate().getID().toLowerCase() + "/" + biomeID.toLowerCase(Locale.ROOT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clones a Vanilla biome and injects Terra data to create a Terra-vanilla biome delegate.
|
||||||
|
*
|
||||||
|
* @param fabricAddon The Fabric addon instance.
|
||||||
|
* @param biome The Terra BiomeBuilder.
|
||||||
|
* @param pack The ConfigPack this biome belongs to.
|
||||||
|
* @return The Minecraft delegate biome.
|
||||||
|
*/
|
||||||
|
public static Biome createBiome(TerraFabricPlugin.FabricAddon fabricAddon, BiomeBuilder biome, ConfigPack pack) {
|
||||||
|
BiomeTemplate template = biome.getTemplate();
|
||||||
|
Map<String, Integer> colors = template.getColors();
|
||||||
|
|
||||||
|
Biome vanilla = (Biome) (new ArrayList<>(biome.getVanillaBiomes().getContents()).get(0)).getHandle();
|
||||||
|
|
||||||
|
GenerationSettings.Builder generationSettings = new GenerationSettings.Builder();
|
||||||
|
|
||||||
|
generationSettings.surfaceBuilder(vanilla.getGenerationSettings().getSurfaceBuilder()); // It needs a surfacebuilder, even though we dont use it.
|
||||||
|
|
||||||
|
generationSettings.feature(GenerationStep.Feature.VEGETAL_DECORATION, TerraFabricPlugin.POPULATOR_CONFIGURED_FEATURE);
|
||||||
|
|
||||||
|
if(pack.getTemplate().vanillaCaves()) {
|
||||||
|
for(GenerationStep.Carver carver : GenerationStep.Carver.values()) {
|
||||||
|
for(Supplier<ConfiguredCarver<?>> configuredCarverSupplier : vanilla.getGenerationSettings().getCarversForStep(carver)) {
|
||||||
|
generationSettings.carver(carver, configuredCarverSupplier.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Pair<PreLoadCompatibilityOptions, PostLoadCompatibilityOptions> pair = fabricAddon.getTemplates().get(pack);
|
||||||
|
PreLoadCompatibilityOptions compatibilityOptions = pair.getLeft();
|
||||||
|
PostLoadCompatibilityOptions postLoadCompatibilityOptions = pair.getRight();
|
||||||
|
|
||||||
|
TerraFabricPlugin.getInstance().getDebugLogger().info("Injecting Vanilla structures and features into Terra biome " + biome.getTemplate().getID());
|
||||||
|
|
||||||
|
for(Supplier<ConfiguredStructureFeature<?, ?>> structureFeature : vanilla.getGenerationSettings().getStructureFeatures()) {
|
||||||
|
Identifier key = BuiltinRegistries.CONFIGURED_STRUCTURE_FEATURE.getId(structureFeature.get());
|
||||||
|
if(!compatibilityOptions.getExcludedBiomeStructures().contains(key) && !postLoadCompatibilityOptions.getExcludedPerBiomeStructures().getOrDefault(biome, Collections.emptySet()).contains(key)) {
|
||||||
|
generationSettings.structureFeature(structureFeature.get());
|
||||||
|
TerraFabricPlugin.getInstance().getDebugLogger().info("Injected structure " + key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(compatibilityOptions.doBiomeInjection()) {
|
||||||
|
for(int step = 0; step < vanilla.getGenerationSettings().getFeatures().size(); step++) {
|
||||||
|
for(Supplier<ConfiguredFeature<?, ?>> featureSupplier : vanilla.getGenerationSettings().getFeatures().get(step)) {
|
||||||
|
Identifier key = BuiltinRegistries.CONFIGURED_FEATURE.getId(featureSupplier.get());
|
||||||
|
if(!compatibilityOptions.getExcludedBiomeFeatures().contains(key) && !postLoadCompatibilityOptions.getExcludedPerBiomeFeatures().getOrDefault(biome, Collections.emptySet()).contains(key)) {
|
||||||
|
generationSettings.feature(step, featureSupplier);
|
||||||
|
TerraFabricPlugin.getInstance().getDebugLogger().info("Injected feature " + key + " at stage " + step);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BiomeEffectsAccessor accessor = (BiomeEffectsAccessor) vanilla.getEffects();
|
||||||
|
BiomeEffects.Builder effects = new BiomeEffects.Builder()
|
||||||
|
.waterColor(colors.getOrDefault("water", accessor.getWaterColor()))
|
||||||
|
.waterFogColor(colors.getOrDefault("water-fog", accessor.getWaterFogColor()))
|
||||||
|
.fogColor(colors.getOrDefault("fog", accessor.getFogColor()))
|
||||||
|
.skyColor(colors.getOrDefault("sky", accessor.getSkyColor()))
|
||||||
|
.grassColorModifier(accessor.getGrassColorModifier());
|
||||||
|
|
||||||
|
if(colors.containsKey("grass")) {
|
||||||
|
effects.grassColor(colors.get("grass"));
|
||||||
|
} else {
|
||||||
|
accessor.getGrassColor().ifPresent(effects::grassColor);
|
||||||
|
}
|
||||||
|
if(colors.containsKey("foliage")) {
|
||||||
|
effects.foliageColor(colors.get("foliage"));
|
||||||
|
} else {
|
||||||
|
accessor.getFoliageColor().ifPresent(effects::foliageColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Biome.Builder()
|
||||||
|
.precipitation(vanilla.getPrecipitation())
|
||||||
|
.category(vanilla.getCategory())
|
||||||
|
.depth(vanilla.getDepth())
|
||||||
|
.scale(vanilla.getScale())
|
||||||
|
.temperature(vanilla.getTemperature())
|
||||||
|
.downfall(vanilla.getDownfall())
|
||||||
|
.effects(effects.build())
|
||||||
|
.spawnSettings(vanilla.getSpawnSettings())
|
||||||
|
.generationSettings(generationSettings.build())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
"mixins": [
|
"mixins": [
|
||||||
"CommandManagerMixin",
|
"CommandManagerMixin",
|
||||||
"GeneratorOptionsMixin",
|
"GeneratorOptionsMixin",
|
||||||
|
"ServerWorldMixin",
|
||||||
"access.BiomeEffectsAccessor",
|
"access.BiomeEffectsAccessor",
|
||||||
"access.MobSpawnerLogicAccessor",
|
"access.MobSpawnerLogicAccessor",
|
||||||
"access.StateAccessor",
|
"access.StateAccessor",
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ import com.dfsek.terra.api.platform.world.Tree;
|
|||||||
import com.dfsek.terra.api.platform.world.World;
|
import com.dfsek.terra.api.platform.world.World;
|
||||||
import com.dfsek.terra.api.registry.CheckedRegistry;
|
import com.dfsek.terra.api.registry.CheckedRegistry;
|
||||||
import com.dfsek.terra.api.registry.LockedRegistry;
|
import com.dfsek.terra.api.registry.LockedRegistry;
|
||||||
import com.dfsek.terra.api.transform.NotNullValidator;
|
|
||||||
import com.dfsek.terra.api.transform.Transformer;
|
import com.dfsek.terra.api.transform.Transformer;
|
||||||
|
import com.dfsek.terra.api.transform.Validator;
|
||||||
import com.dfsek.terra.api.util.JarUtil;
|
import com.dfsek.terra.api.util.JarUtil;
|
||||||
import com.dfsek.terra.api.util.logging.DebugLogger;
|
import com.dfsek.terra.api.util.logging.DebugLogger;
|
||||||
import com.dfsek.terra.commands.CommandUtil;
|
import com.dfsek.terra.commands.CommandUtil;
|
||||||
@@ -113,8 +113,8 @@ public class TerraForgePlugin implements TerraPlugin {
|
|||||||
private final LockedRegistry<TerraAddon> addonLockedRegistry = new LockedRegistry<>(addonRegistry);
|
private final LockedRegistry<TerraAddon> addonLockedRegistry = new LockedRegistry<>(addonRegistry);
|
||||||
private final PluginConfig config = new PluginConfig();
|
private final PluginConfig config = new PluginConfig();
|
||||||
private final Transformer<String, Biome> biomeFixer = new Transformer.Builder<String, Biome>()
|
private final Transformer<String, Biome> biomeFixer = new Transformer.Builder<String, Biome>()
|
||||||
.addTransform(id -> ForgeRegistries.BIOMES.getValue(ResourceLocation.tryParse(id)), new NotNullValidator<>())
|
.addTransform(id -> ForgeRegistries.BIOMES.getValue(ResourceLocation.tryParse(id)), Validator.notNull())
|
||||||
.addTransform(id -> ForgeRegistries.BIOMES.getValue(ResourceLocation.tryParse("minecraft:" + id.toLowerCase())), new NotNullValidator<>()).build();
|
.addTransform(id -> ForgeRegistries.BIOMES.getValue(ResourceLocation.tryParse("minecraft:" + id.toLowerCase())), Validator.notNull()).build();
|
||||||
private final File dataFolder;
|
private final File dataFolder;
|
||||||
|
|
||||||
public TerraForgePlugin() {
|
public TerraForgePlugin() {
|
||||||
|
|||||||
Reference in new issue
Block a user