mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-06-17 22:31:52 +00:00
Change Java whitespace handling in .editorconfig (#425)
* Change whitespace handling in .editorconfig * Reformat code * fix format error * Reformat code --------- Co-authored-by: Zoë Gidiere <duplexsys@protonmail.com>
This commit is contained in:
@@ -14,37 +14,37 @@ import com.dfsek.terra.bukkit.config.VanillaBiomeProperties;
|
||||
|
||||
public class BukkitAddon implements BaseAddon {
|
||||
private static final Version VERSION = Versions.getVersion(1, 0, 0);
|
||||
|
||||
|
||||
private final PlatformImpl terraBukkitPlugin;
|
||||
|
||||
|
||||
public BukkitAddon(PlatformImpl terraBukkitPlugin) {
|
||||
this.terraBukkitPlugin = terraBukkitPlugin;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
terraBukkitPlugin.getEventManager()
|
||||
.getHandler(FunctionalEventHandler.class)
|
||||
.register(this, ConfigPackPreLoadEvent.class)
|
||||
.then(event -> event.getPack().getContext().put(event.loadTemplate(new PreLoadCompatibilityOptions())))
|
||||
.global();
|
||||
|
||||
.getHandler(FunctionalEventHandler.class)
|
||||
.register(this, ConfigPackPreLoadEvent.class)
|
||||
.then(event -> event.getPack().getContext().put(event.loadTemplate(new PreLoadCompatibilityOptions())))
|
||||
.global();
|
||||
|
||||
terraBukkitPlugin.getEventManager()
|
||||
.getHandler(FunctionalEventHandler.class)
|
||||
.register(this, ConfigurationLoadEvent.class)
|
||||
.then(event -> {
|
||||
if(event.is(Biome.class)) {
|
||||
event.getLoadedObject(Biome.class).getContext().put(event.load(new VanillaBiomeProperties()));
|
||||
}
|
||||
})
|
||||
.global();
|
||||
.getHandler(FunctionalEventHandler.class)
|
||||
.register(this, ConfigurationLoadEvent.class)
|
||||
.then(event -> {
|
||||
if(event.is(Biome.class)) {
|
||||
event.getLoadedObject(Biome.class).getContext().put(event.load(new VanillaBiomeProperties()));
|
||||
}
|
||||
})
|
||||
.global();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Version getVersion() {
|
||||
return VERSION;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
return "terra-bukkit";
|
||||
|
||||
+5
-5
@@ -29,16 +29,16 @@ import com.dfsek.terra.bukkit.world.BukkitAdapter;
|
||||
|
||||
public class BukkitCommandSender implements CommandSender {
|
||||
private final org.bukkit.command.CommandSender delegate;
|
||||
|
||||
|
||||
public BukkitCommandSender(org.bukkit.command.CommandSender delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void sendMessage(String message) {
|
||||
delegate.sendMessage(ChatColor.translateAlternateColorCodes('&', message));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Optional<Entity> getEntity() {
|
||||
if(delegate instanceof org.bukkit.entity.Entity entity) {
|
||||
@@ -46,7 +46,7 @@ public class BukkitCommandSender implements CommandSender {
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Optional<Player> getPlayer() {
|
||||
if(delegate instanceof org.bukkit.entity.Player player) {
|
||||
@@ -54,7 +54,7 @@ public class BukkitCommandSender implements CommandSender {
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public org.bukkit.command.CommandSender getHandle() {
|
||||
return delegate;
|
||||
|
||||
@@ -17,44 +17,44 @@
|
||||
|
||||
package com.dfsek.terra.bukkit;
|
||||
|
||||
import io.papermc.lib.PaperLib;
|
||||
import org.bukkit.Location;
|
||||
|
||||
import com.dfsek.terra.api.entity.Entity;
|
||||
import com.dfsek.terra.api.util.vector.Vector3;
|
||||
import com.dfsek.terra.api.world.ServerWorld;
|
||||
import com.dfsek.terra.bukkit.world.BukkitAdapter;
|
||||
|
||||
import io.papermc.lib.PaperLib;
|
||||
import org.bukkit.Location;
|
||||
|
||||
|
||||
public class BukkitEntity implements Entity {
|
||||
private final org.bukkit.entity.Entity entity;
|
||||
|
||||
|
||||
public BukkitEntity(org.bukkit.entity.Entity entity) {
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public org.bukkit.entity.Entity getHandle() {
|
||||
return entity;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Vector3 position() {
|
||||
return BukkitAdapter.adapt(entity.getLocation().toVector());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void position(Vector3 location) {
|
||||
PaperLib.teleportAsync(entity, BukkitAdapter.adapt(location).toLocation(entity.getWorld()));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void world(ServerWorld world) {
|
||||
Location newLoc = entity.getLocation().clone();
|
||||
newLoc.setWorld(BukkitAdapter.adapt(world));
|
||||
PaperLib.teleportAsync(entity, newLoc);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ServerWorld world() {
|
||||
return BukkitAdapter.adapt(entity.getWorld());
|
||||
|
||||
@@ -28,34 +28,34 @@ import com.dfsek.terra.bukkit.world.BukkitAdapter;
|
||||
|
||||
public class BukkitPlayer implements Player {
|
||||
private final org.bukkit.entity.Player delegate;
|
||||
|
||||
|
||||
public BukkitPlayer(org.bukkit.entity.Player delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public org.bukkit.entity.Player getHandle() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Vector3 position() {
|
||||
org.bukkit.Location bukkit = delegate.getLocation();
|
||||
return Vector3.of(bukkit.getX(), bukkit.getY(), bukkit.getZ());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void position(Vector3 location) {
|
||||
PaperLib.teleportAsync(delegate, BukkitAdapter.adapt(location).toLocation(delegate.getWorld()));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void world(ServerWorld world) {
|
||||
Location newLoc = delegate.getLocation().clone();
|
||||
newLoc.setWorld(BukkitAdapter.adapt(world));
|
||||
PaperLib.teleportAsync(delegate, newLoc);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ServerWorld world() {
|
||||
return BukkitAdapter.adapt(delegate.getWorld());
|
||||
|
||||
@@ -44,28 +44,28 @@ import com.dfsek.terra.bukkit.world.BukkitPlatformBiome;
|
||||
|
||||
public class PlatformImpl extends AbstractPlatform {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(PlatformImpl.class);
|
||||
|
||||
|
||||
private final ItemHandle itemHandle = new BukkitItemHandle();
|
||||
|
||||
|
||||
private final WorldHandle handle = new BukkitWorldHandle();
|
||||
|
||||
|
||||
private final TerraBukkitPlugin plugin;
|
||||
|
||||
|
||||
public PlatformImpl(TerraBukkitPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
load();
|
||||
}
|
||||
|
||||
|
||||
public TerraBukkitPlugin getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean reload() {
|
||||
getTerraConfig().load(this);
|
||||
getRawConfigRegistry().clear();
|
||||
boolean succeed = getRawConfigRegistry().loadAll(this);
|
||||
|
||||
|
||||
Bukkit.getWorlds().forEach(world -> {
|
||||
if(world.getGenerator() instanceof BukkitChunkGeneratorWrapper wrapper) {
|
||||
getConfigRegistry().get(wrapper.getPack().getRegistryKey()).ifPresent(pack -> {
|
||||
@@ -74,49 +74,49 @@ public class PlatformImpl extends AbstractPlatform {
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return succeed;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull String platformName() {
|
||||
return "Bukkit";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void runPossiblyUnsafeTask(@NotNull Runnable task) {
|
||||
plugin.getFoliaLib().getImpl().runAsync(task);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Iterable<BaseAddon> platformAddon() {
|
||||
return List.of(new BukkitAddon(this));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull WorldHandle getWorldHandle() {
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull File getDataFolder() {
|
||||
return plugin.getDataFolder();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull ItemHandle getItemHandle() {
|
||||
return itemHandle;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void register(TypeRegistry registry) {
|
||||
super.register(registry);
|
||||
registry.registerLoader(BlockState.class, (type, o, loader, depthTracker) -> handle.createBlockState((String) o))
|
||||
.registerLoader(PlatformBiome.class, (type, o, loader, depthTracker) -> parseBiome((String) o, depthTracker))
|
||||
.registerLoader(EntityType.class, (type, o, loader, depthTracker) -> EntityType.valueOf((String) o));
|
||||
|
||||
.registerLoader(PlatformBiome.class, (type, o, loader, depthTracker) -> parseBiome((String) o, depthTracker))
|
||||
.registerLoader(EntityType.class, (type, o, loader, depthTracker) -> EntityType.valueOf((String) o));
|
||||
|
||||
}
|
||||
|
||||
|
||||
private BukkitPlatformBiome parseBiome(String id, DepthTracker depthTracker) throws LoadException {
|
||||
if(!id.startsWith("minecraft:")) throw new LoadException("Invalid biome identifier " + id, depthTracker);
|
||||
return new BukkitPlatformBiome(org.bukkit.block.Biome.valueOf(id.toUpperCase(Locale.ROOT).substring(10)));
|
||||
|
||||
+23
-23
@@ -47,26 +47,26 @@ import com.dfsek.terra.bukkit.world.BukkitAdapter;
|
||||
|
||||
public class TerraBukkitPlugin extends JavaPlugin {
|
||||
private static final Logger logger = LoggerFactory.getLogger(TerraBukkitPlugin.class);
|
||||
|
||||
|
||||
private final PlatformImpl platform = new PlatformImpl(this);
|
||||
private final Map<String, com.dfsek.terra.api.world.chunk.generation.ChunkGenerator> generatorMap = new HashMap<>();
|
||||
|
||||
|
||||
private final FoliaLib foliaLib = new FoliaLib(this);
|
||||
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
if(!doVersionCheck()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
platform.getEventManager().callEvent(new PlatformInitializationEvent());
|
||||
|
||||
|
||||
|
||||
|
||||
try {
|
||||
PaperCommandManager<CommandSender> commandManager = getCommandSenderPaperCommandManager();
|
||||
|
||||
|
||||
platform.getEventManager().callEvent(new CommandRegistrationEvent(commandManager));
|
||||
|
||||
|
||||
} catch(Exception e) { // This should never happen.
|
||||
logger.error("""
|
||||
TERRA HAS BEEN DISABLED
|
||||
@@ -77,19 +77,19 @@ public class TerraBukkitPlugin extends JavaPlugin {
|
||||
Bukkit.getPluginManager().disablePlugin(this);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Bukkit.getPluginManager().registerEvents(new CommonListener(), this); // Register master event listener
|
||||
PaperUtil.checkPaper(this);
|
||||
|
||||
|
||||
Initializer.init(platform);
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
private PaperCommandManager<CommandSender> getCommandSenderPaperCommandManager() throws Exception {
|
||||
PaperCommandManager<CommandSender> commandManager = new PaperCommandManager<>(this,
|
||||
CommandExecutionCoordinator.simpleCoordinator(),
|
||||
BukkitAdapter::adapt,
|
||||
BukkitAdapter::adapt);
|
||||
CommandExecutionCoordinator.simpleCoordinator(),
|
||||
BukkitAdapter::adapt,
|
||||
BukkitAdapter::adapt);
|
||||
if(commandManager.hasCapability(CloudBukkitCapabilities.NATIVE_BRIGADIER)) {
|
||||
commandManager.registerBrigadier();
|
||||
final CloudBrigadierManager<?, ?> brigManager = commandManager.brigadierManager();
|
||||
@@ -97,25 +97,25 @@ public class TerraBukkitPlugin extends JavaPlugin {
|
||||
brigManager.setNativeNumberSuggestions(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(commandManager.hasCapability(CloudBukkitCapabilities.ASYNCHRONOUS_COMPLETION)) {
|
||||
commandManager.registerAsynchronousCompletions();
|
||||
}
|
||||
return commandManager;
|
||||
}
|
||||
|
||||
|
||||
public PlatformImpl getPlatform() {
|
||||
return platform;
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings({ "deprecation", "AccessOfSystemProperties" })
|
||||
private boolean doVersionCheck() {
|
||||
logger.info("Running on Minecraft version {} with server implementation {}.", VersionUtil.getMinecraftVersionInfo(),
|
||||
Bukkit.getServer().getName());
|
||||
|
||||
Bukkit.getServer().getName());
|
||||
|
||||
if(!VersionUtil.getSpigotVersionInfo().isSpigot())
|
||||
logger.error("YOU ARE RUNNING A CRAFTBUKKIT OR BUKKIT SERVER. PLEASE UPGRADE TO PAPER.");
|
||||
|
||||
|
||||
if(VersionUtil.getSpigotVersionInfo().isMohist()) {
|
||||
if(System.getProperty("IKnowMohistCausesLotsOfIssuesButIWillUseItAnyways") == null) {
|
||||
Runnable runnable = () -> { // scary big block of text
|
||||
@@ -176,17 +176,17 @@ public class TerraBukkitPlugin extends JavaPlugin {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @Nullable
|
||||
ChunkGenerator getDefaultWorldGenerator(@NotNull String worldName, String id) {
|
||||
return new BukkitChunkGeneratorWrapper(generatorMap.computeIfAbsent(worldName, name -> {
|
||||
ConfigPack pack = platform.getConfigRegistry().getByID(id).orElseThrow(
|
||||
() -> new IllegalArgumentException("No such config pack \"" + id + "\""));
|
||||
() -> new IllegalArgumentException("No such config pack \"" + id + "\""));
|
||||
return pack.getGeneratorProvider().newInstance(pack);
|
||||
}), platform.getRawConfigRegistry().getByID(id).orElseThrow(), platform.getWorldHandle().air());
|
||||
}
|
||||
|
||||
|
||||
public FoliaLib getFoliaLib() {
|
||||
return foliaLib;
|
||||
}
|
||||
|
||||
+7
-7
@@ -29,31 +29,31 @@ public class PreLoadCompatibilityOptions implements ConfigTemplate, Properties {
|
||||
@Value("minecraft.use-vanilla-biomes")
|
||||
@Default
|
||||
private boolean vanillaBiomes = false;
|
||||
|
||||
|
||||
@Value("minecraft.beard.enable")
|
||||
@Default
|
||||
private boolean beard = true;
|
||||
|
||||
|
||||
@Value("minecraft.beard.threshold")
|
||||
@Default
|
||||
private double beardThreshold = 0.5;
|
||||
|
||||
|
||||
@Value("minecraft.beard.air-threshold")
|
||||
@Default
|
||||
private double airThreshold = -0.5;
|
||||
|
||||
|
||||
public boolean useVanillaBiomes() {
|
||||
return vanillaBiomes;
|
||||
}
|
||||
|
||||
|
||||
public boolean isBeard() {
|
||||
return beard;
|
||||
}
|
||||
|
||||
|
||||
public double getBeardThreshold() {
|
||||
return beardThreshold;
|
||||
}
|
||||
|
||||
|
||||
public double getAirThreshold() {
|
||||
return airThreshold;
|
||||
}
|
||||
|
||||
+11
-11
@@ -11,47 +11,47 @@ public class VanillaBiomeProperties implements ConfigTemplate, Properties {
|
||||
@Value("colors.grass")
|
||||
@Default
|
||||
private Integer grassColor = null;
|
||||
|
||||
|
||||
@Value("colors.fog")
|
||||
@Default
|
||||
private Integer fogColor = null;
|
||||
|
||||
|
||||
@Value("colors.water")
|
||||
@Default
|
||||
private Integer waterColor = null;
|
||||
|
||||
|
||||
@Value("colors.water-fog")
|
||||
@Default
|
||||
private Integer waterFogColor = null;
|
||||
|
||||
|
||||
@Value("colors.foliage")
|
||||
@Default
|
||||
private Integer foliageColor = null;
|
||||
|
||||
|
||||
@Value("colors.sky")
|
||||
@Default
|
||||
private Integer skyColor = null;
|
||||
|
||||
|
||||
public Integer getFogColor() {
|
||||
return fogColor;
|
||||
}
|
||||
|
||||
|
||||
public Integer getFoliageColor() {
|
||||
return foliageColor;
|
||||
}
|
||||
|
||||
|
||||
public Integer getGrassColor() {
|
||||
return grassColor;
|
||||
}
|
||||
|
||||
|
||||
public Integer getWaterColor() {
|
||||
return waterColor;
|
||||
}
|
||||
|
||||
|
||||
public Integer getWaterFogColor() {
|
||||
return waterFogColor;
|
||||
}
|
||||
|
||||
|
||||
public Integer getSkyColor() {
|
||||
return skyColor;
|
||||
}
|
||||
|
||||
+6
-6
@@ -14,22 +14,22 @@ import com.dfsek.terra.api.world.biome.Biome;
|
||||
|
||||
public class BukkitBiomeProvider extends BiomeProvider implements Handle {
|
||||
private final com.dfsek.terra.api.world.biome.generation.BiomeProvider delegate;
|
||||
|
||||
|
||||
public BukkitBiomeProvider(com.dfsek.terra.api.world.biome.generation.BiomeProvider delegate) { this.delegate = delegate; }
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull org.bukkit.block.Biome getBiome(@NotNull WorldInfo worldInfo, int x, int y, int z) {
|
||||
Biome biome = delegate.getBiome(x, y, z, worldInfo.getSeed());
|
||||
return (org.bukkit.block.Biome) biome.getPlatformBiome().getHandle();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull List<org.bukkit.block.Biome> getBiomes(@NotNull WorldInfo worldInfo) {
|
||||
return StreamSupport.stream(delegate.getBiomes().spliterator(), false)
|
||||
.map(terraBiome -> (org.bukkit.block.Biome) terraBiome.getPlatformBiome().getHandle())
|
||||
.collect(Collectors.toList());
|
||||
.map(terraBiome -> (org.bukkit.block.Biome) terraBiome.getPlatformBiome().getHandle())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object getHandle() {
|
||||
return delegate;
|
||||
|
||||
+4
-4
@@ -15,20 +15,20 @@ import com.dfsek.terra.bukkit.world.BukkitProtoWorld;
|
||||
public class BukkitBlockPopulator extends BlockPopulator {
|
||||
private final BlockState air;
|
||||
private ConfigPack pack;
|
||||
|
||||
|
||||
public BukkitBlockPopulator(ConfigPack pack, BlockState air) {
|
||||
this.pack = pack;
|
||||
this.air = air;
|
||||
}
|
||||
|
||||
|
||||
public void setPack(ConfigPack pack) {
|
||||
this.pack = pack;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void populate(@NotNull WorldInfo worldInfo, @NotNull Random random, int chunkX, int chunkZ,
|
||||
@NotNull LimitedRegion limitedRegion) {
|
||||
pack.getStages().forEach(
|
||||
generationStage -> generationStage.populate(new BukkitProtoWorld(limitedRegion, air, pack.getBiomeProvider())));
|
||||
generationStage -> generationStage.populate(new BukkitProtoWorld(limitedRegion, air, pack.getBiomeProvider())));
|
||||
}
|
||||
}
|
||||
|
||||
+16
-16
@@ -43,71 +43,71 @@ public class BukkitChunkGeneratorWrapper extends org.bukkit.generator.ChunkGener
|
||||
private final BukkitBlockPopulator blockPopulator;
|
||||
private ChunkGenerator delegate;
|
||||
private ConfigPack pack;
|
||||
|
||||
|
||||
|
||||
|
||||
public BukkitChunkGeneratorWrapper(ChunkGenerator delegate, ConfigPack pack, BlockState air) {
|
||||
this.delegate = delegate;
|
||||
this.pack = pack;
|
||||
this.air = air;
|
||||
this.blockPopulator = new BukkitBlockPopulator(pack, air);
|
||||
}
|
||||
|
||||
|
||||
public void setDelegate(ChunkGenerator delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @Nullable BiomeProvider getDefaultBiomeProvider(@NotNull WorldInfo worldInfo) {
|
||||
return new BukkitBiomeProvider(pack.getBiomeProvider());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void generateNoise(@NotNull WorldInfo worldInfo, @NotNull Random random, int x, int z, @NotNull ChunkData chunkData) {
|
||||
BukkitWorldProperties properties = new BukkitWorldProperties(worldInfo);
|
||||
delegate.generateChunkData(new BukkitProtoChunk(chunkData), properties, pack.getBiomeProvider(), x, z);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull List<BlockPopulator> getDefaultPopulators(@NotNull World world) {
|
||||
return List.of(blockPopulator);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean shouldGenerateCaves() {
|
||||
return false;
|
||||
//return pack.vanillaCaves();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean shouldGenerateDecorations() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean shouldGenerateMobs() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean shouldGenerateStructures() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public ConfigPack getPack() {
|
||||
return pack;
|
||||
}
|
||||
|
||||
|
||||
public void setPack(ConfigPack pack) {
|
||||
this.pack = pack;
|
||||
setDelegate(pack.getGeneratorProvider().newInstance(pack));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ChunkGenerator getHandle() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private record SeededVector(int x, int z, WorldProperties worldProperties) {
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
@@ -116,7 +116,7 @@ public class BukkitChunkGeneratorWrapper extends org.bukkit.generator.ChunkGener
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int code = x;
|
||||
|
||||
+8
-8
@@ -26,30 +26,30 @@ import com.dfsek.terra.bukkit.world.block.data.BukkitBlockState;
|
||||
|
||||
|
||||
public class BukkitProtoChunk implements ProtoChunk {
|
||||
|
||||
|
||||
private final ChunkGenerator.ChunkData delegate;
|
||||
|
||||
|
||||
public BukkitProtoChunk(ChunkGenerator.ChunkData delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ChunkGenerator.ChunkData getHandle() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMaxHeight() {
|
||||
return delegate.getMaxHeight();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, @NotNull BlockState blockState) {
|
||||
delegate.setBlock(x, y, z, ((BukkitBlockState) blockState).getHandle());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull BlockState getBlock(int x, int y, int z) {
|
||||
return BukkitBlockState.newInstance(delegate.getBlockData(x, y, z));
|
||||
|
||||
+4
-4
@@ -32,18 +32,18 @@ import com.dfsek.terra.bukkit.world.BukkitAdapter;
|
||||
|
||||
|
||||
public class BukkitItemHandle implements ItemHandle {
|
||||
|
||||
|
||||
@Override
|
||||
public Item createItem(String data) {
|
||||
return BukkitAdapter.adapt(Material.matchMaterial(data));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Enchantment getEnchantment(String id) {
|
||||
return BukkitAdapter.adapt(
|
||||
org.bukkit.enchantments.Enchantment.getByKey(NamespacedKey.minecraft(MinecraftUtils.stripMinecraftNamespace(id))));
|
||||
org.bukkit.enchantments.Enchantment.getByKey(NamespacedKey.minecraft(MinecraftUtils.stripMinecraftNamespace(id))));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Set<Enchantment> getEnchantments() {
|
||||
return Arrays.stream(org.bukkit.enchantments.Enchantment.values()).map(BukkitAdapter::adapt).collect(Collectors.toSet());
|
||||
|
||||
+7
-7
@@ -32,32 +32,32 @@ import com.dfsek.terra.bukkit.world.entity.BukkitEntityType;
|
||||
|
||||
public class BukkitWorldHandle implements WorldHandle {
|
||||
private final BlockState air;
|
||||
|
||||
|
||||
public BukkitWorldHandle() {
|
||||
this.air = BukkitBlockState.newInstance(Material.AIR.createBlockData());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public synchronized @NotNull BlockState createBlockState(@NotNull String data) {
|
||||
org.bukkit.block.data.BlockData bukkitData = Bukkit.createBlockData(
|
||||
data); // somehow bukkit managed to make this not thread safe! :)
|
||||
data); // somehow bukkit managed to make this not thread safe! :)
|
||||
return BukkitBlockState.newInstance(bukkitData);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull BlockState air() {
|
||||
return air;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull EntityType getEntity(@NotNull String id) {
|
||||
if(!id.startsWith("minecraft:")) throw new IllegalArgumentException("Invalid entity identifier " + id);
|
||||
String entityID = id.toUpperCase(Locale.ROOT).substring(10);
|
||||
|
||||
|
||||
return new BukkitEntityType(switch(entityID) {
|
||||
case "END_CRYSTAL" -> org.bukkit.entity.EntityType.ENDER_CRYSTAL;
|
||||
case "ENDER_CRYSTAL" -> throw new IllegalArgumentException(
|
||||
"Invalid entity identifier " + id); // make sure this issue can't happen the other way around.
|
||||
"Invalid entity identifier " + id); // make sure this issue can't happen the other way around.
|
||||
default -> org.bukkit.entity.EntityType.valueOf(entityID);
|
||||
});
|
||||
}
|
||||
|
||||
+4
-4
@@ -39,11 +39,11 @@ import com.dfsek.terra.api.Platform;
|
||||
public class SpigotListener implements Listener {
|
||||
private static final Logger logger = LoggerFactory.getLogger(SpigotListener.class);
|
||||
private final Platform platform;
|
||||
|
||||
|
||||
public SpigotListener(Platform platform) {
|
||||
this.platform = platform;
|
||||
}
|
||||
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL)
|
||||
public void onEnderEye(EntitySpawnEvent e) {
|
||||
/*
|
||||
@@ -68,7 +68,7 @@ public class SpigotListener implements Listener {
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
@EventHandler
|
||||
public void onCartographerChange(VillagerAcquireTradeEvent e) {
|
||||
if(!(e.getEntity() instanceof Villager))
|
||||
@@ -85,7 +85,7 @@ public class SpigotListener implements Listener {
|
||||
e.setCancelled(true); // Cancel leveling if the villager is a Cartographer, to prevent crashing server.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@EventHandler
|
||||
public void onCartographerLevel(VillagerCareerChangeEvent e) {
|
||||
if(e.getProfession() == Villager.Profession.CARTOGRAPHER) {
|
||||
|
||||
@@ -10,7 +10,7 @@ import com.dfsek.terra.bukkit.PlatformImpl;
|
||||
public interface Initializer {
|
||||
String NMS = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
|
||||
String TERRA_PACKAGE = Initializer.class.getPackageName();
|
||||
|
||||
|
||||
static void init(PlatformImpl platform) {
|
||||
Logger logger = LoggerFactory.getLogger(Initializer.class);
|
||||
try {
|
||||
@@ -35,6 +35,6 @@ public interface Initializer {
|
||||
logger.error("This is usually due to running Terra on an unsupported Minecraft version.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void initialize(PlatformImpl plugin);
|
||||
}
|
||||
|
||||
+27
-27
@@ -12,12 +12,12 @@ import java.util.regex.Pattern;
|
||||
public final class VersionUtil {
|
||||
public static final SpigotVersionInfo SPIGOT_VERSION_INFO;
|
||||
public static final MinecraftVersionInfo MINECRAFT_VERSION_INFO;
|
||||
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(VersionUtil.class);
|
||||
|
||||
|
||||
static {
|
||||
SPIGOT_VERSION_INFO = new SpigotVersionInfo();
|
||||
|
||||
|
||||
MinecraftVersionInfo mcVersionInfo;
|
||||
try {
|
||||
mcVersionInfo = new MinecraftVersionInfo();
|
||||
@@ -27,28 +27,28 @@ public final class VersionUtil {
|
||||
}
|
||||
MINECRAFT_VERSION_INFO = mcVersionInfo;
|
||||
}
|
||||
|
||||
|
||||
public static MinecraftVersionInfo getMinecraftVersionInfo() {
|
||||
return MINECRAFT_VERSION_INFO;
|
||||
}
|
||||
|
||||
|
||||
public static SpigotVersionInfo getSpigotVersionInfo() {
|
||||
return SPIGOT_VERSION_INFO;
|
||||
}
|
||||
|
||||
|
||||
public static final class SpigotVersionInfo {
|
||||
private final boolean spigot;
|
||||
private final boolean paper;
|
||||
private final boolean mohist;
|
||||
|
||||
|
||||
|
||||
|
||||
public SpigotVersionInfo() {
|
||||
logger.debug("Parsing spigot version info...");
|
||||
|
||||
|
||||
paper = PaperLib.isPaper();
|
||||
spigot = PaperLib.isSpigot();
|
||||
|
||||
|
||||
|
||||
|
||||
boolean isMohist = false;
|
||||
try {
|
||||
Class.forName("com.mohistmc.MohistMC");
|
||||
@@ -56,42 +56,42 @@ public final class VersionUtil {
|
||||
isMohist = true;
|
||||
} catch(ClassNotFoundException ignore) { }
|
||||
this.mohist = isMohist;
|
||||
|
||||
|
||||
logger.debug("Spigot version info parsed successfully.");
|
||||
}
|
||||
|
||||
|
||||
public boolean isPaper() {
|
||||
return paper;
|
||||
}
|
||||
|
||||
|
||||
public boolean isMohist() {
|
||||
return mohist;
|
||||
}
|
||||
|
||||
|
||||
public boolean isSpigot() {
|
||||
return spigot;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static final class MinecraftVersionInfo {
|
||||
private static final Logger logger = LoggerFactory.getLogger(MinecraftVersionInfo.class);
|
||||
|
||||
|
||||
private static final Pattern VERSION_PATTERN = Pattern.compile("v?(\\d+)_(\\d+)_R(\\d+)");
|
||||
private final int major;
|
||||
private final int minor;
|
||||
private final int patch;
|
||||
|
||||
|
||||
private MinecraftVersionInfo() {
|
||||
this(Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]);
|
||||
}
|
||||
|
||||
|
||||
private MinecraftVersionInfo(int major, int minor, int patch) {
|
||||
this.major = major;
|
||||
this.minor = minor;
|
||||
this.patch = patch;
|
||||
}
|
||||
|
||||
|
||||
private MinecraftVersionInfo(String versionString) {
|
||||
Matcher versionMatcher = VERSION_PATTERN.matcher(versionString);
|
||||
if(versionMatcher.find()) {
|
||||
@@ -100,29 +100,29 @@ public final class VersionUtil {
|
||||
patch = Integer.parseInt(versionMatcher.group(3));
|
||||
} else {
|
||||
logger.warn("Error while parsing minecraft version info. Continuing launch, but setting all versions to -1.");
|
||||
|
||||
|
||||
major = -1;
|
||||
minor = -1;
|
||||
patch = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if(major == -1 && minor == -1 && patch == -1)
|
||||
return "Unknown";
|
||||
|
||||
|
||||
return String.format("v%d.%d.%d", major, minor, patch);
|
||||
}
|
||||
|
||||
|
||||
public int getMajor() {
|
||||
return major;
|
||||
}
|
||||
|
||||
|
||||
public int getMinor() {
|
||||
return minor;
|
||||
}
|
||||
|
||||
|
||||
public int getPatch() {
|
||||
return patch;
|
||||
}
|
||||
|
||||
+42
-42
@@ -55,26 +55,26 @@ import com.dfsek.terra.transform.TransformerImpl;
|
||||
*/
|
||||
public final class BukkitAdapter {
|
||||
public static TransformerImpl<TreeType, String> TREE_TRANSFORMER = new TransformerImpl.Builder<TreeType, String>()
|
||||
.addTransform(new MapTransform<TreeType, String>()
|
||||
.add(TreeType.COCOA_TREE, "JUNGLE_COCOA")
|
||||
.add(TreeType.BIG_TREE, "LARGE_OAK")
|
||||
.add(TreeType.TALL_REDWOOD, "LARGE_SPRUCE")
|
||||
.add(TreeType.REDWOOD, "SPRUCE")
|
||||
.add(TreeType.TREE, "OAK")
|
||||
.add(TreeType.MEGA_REDWOOD, "MEGA_SPRUCE")
|
||||
.add(TreeType.SWAMP, "SWAMP_OAK"))
|
||||
.addTransform(TreeType::toString)
|
||||
.build();
|
||||
|
||||
|
||||
.addTransform(new MapTransform<TreeType, String>()
|
||||
.add(TreeType.COCOA_TREE, "JUNGLE_COCOA")
|
||||
.add(TreeType.BIG_TREE, "LARGE_OAK")
|
||||
.add(TreeType.TALL_REDWOOD, "LARGE_SPRUCE")
|
||||
.add(TreeType.REDWOOD, "SPRUCE")
|
||||
.add(TreeType.TREE, "OAK")
|
||||
.add(TreeType.MEGA_REDWOOD, "MEGA_SPRUCE")
|
||||
.add(TreeType.SWAMP, "SWAMP_OAK"))
|
||||
.addTransform(TreeType::toString)
|
||||
.build();
|
||||
|
||||
|
||||
public static BlockState adapt(org.bukkit.block.data.BlockData data) {
|
||||
return BukkitBlockState.newInstance(data);
|
||||
}
|
||||
|
||||
|
||||
public static org.bukkit.block.data.BlockData adapt(BlockState data) {
|
||||
return ((BukkitBlockState) data).getHandle();
|
||||
}
|
||||
|
||||
|
||||
public static Axis adapt(org.bukkit.Axis axis) {
|
||||
return switch(axis) {
|
||||
case X -> Axis.X;
|
||||
@@ -82,22 +82,22 @@ public final class BukkitAdapter {
|
||||
case Z -> Axis.Z;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static WorldProperties adapt(WorldInfo worldInfo) {
|
||||
return new BukkitWorldProperties(worldInfo);
|
||||
}
|
||||
|
||||
|
||||
public static WorldInfo adapt(WorldProperties properties) {
|
||||
return (WorldInfo) properties.getHandle();
|
||||
}
|
||||
|
||||
|
||||
public static Half adapt(org.bukkit.block.data.Bisected.Half half) {
|
||||
return switch(half) {
|
||||
case BOTTOM -> Half.BOTTOM;
|
||||
case TOP -> Half.TOP;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static RedstoneConnection adapt(org.bukkit.block.data.type.RedstoneWire.Connection connection) {
|
||||
return switch(connection) {
|
||||
case NONE -> RedstoneConnection.NONE;
|
||||
@@ -105,7 +105,7 @@ public final class BukkitAdapter {
|
||||
case SIDE -> RedstoneConnection.SIDE;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static org.bukkit.block.data.type.RedstoneWire.Connection adapt(RedstoneConnection connection) {
|
||||
return switch(connection) {
|
||||
case SIDE -> org.bukkit.block.data.type.RedstoneWire.Connection.SIDE;
|
||||
@@ -113,7 +113,7 @@ public final class BukkitAdapter {
|
||||
case NONE -> org.bukkit.block.data.type.RedstoneWire.Connection.NONE;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static RailShape adapt(org.bukkit.block.data.Rail.Shape shape) {
|
||||
return switch(shape) {
|
||||
case SOUTH_WEST -> RailShape.SOUTH_WEST;
|
||||
@@ -128,7 +128,7 @@ public final class BukkitAdapter {
|
||||
case EAST_WEST -> RailShape.EAST_WEST;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static org.bukkit.block.data.Rail.Shape adapt(RailShape shape) {
|
||||
return switch(shape) {
|
||||
case EAST_WEST -> org.bukkit.block.data.Rail.Shape.EAST_WEST;
|
||||
@@ -143,8 +143,8 @@ public final class BukkitAdapter {
|
||||
case SOUTH_WEST -> org.bukkit.block.data.Rail.Shape.SOUTH_WEST;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static org.bukkit.block.data.Bisected.Half adapt(Half half) {
|
||||
return switch(half) {
|
||||
case TOP -> org.bukkit.block.data.Bisected.Half.TOP;
|
||||
@@ -152,7 +152,7 @@ public final class BukkitAdapter {
|
||||
default -> throw new IllegalStateException();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static org.bukkit.Axis adapt(Axis axis) {
|
||||
return switch(axis) {
|
||||
case Z -> org.bukkit.Axis.Z;
|
||||
@@ -160,75 +160,75 @@ public final class BukkitAdapter {
|
||||
case X -> org.bukkit.Axis.X;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static Vector3 adapt(Location location) {
|
||||
return Vector3.of(location.getX(), location.getY(), location.getZ());
|
||||
}
|
||||
|
||||
|
||||
public static Vector adapt(Vector3 vector3) {
|
||||
return new Vector(vector3.getX(), vector3.getY(), vector3.getZ());
|
||||
}
|
||||
|
||||
|
||||
public static Vector3 adapt(Vector vector) {
|
||||
return Vector3.of(vector.getX(), vector.getY(), vector.getZ());
|
||||
}
|
||||
|
||||
|
||||
public static CommandSender adapt(org.bukkit.command.CommandSender sender) {
|
||||
return new BukkitCommandSender(sender);
|
||||
}
|
||||
|
||||
|
||||
public static Entity adapt(org.bukkit.entity.Entity entity) {
|
||||
return new BukkitEntity(entity);
|
||||
}
|
||||
|
||||
|
||||
public static org.bukkit.command.CommandSender adapt(CommandSender sender) {
|
||||
return ((BukkitCommandSender) sender).getHandle();
|
||||
}
|
||||
|
||||
|
||||
public static ServerWorld adapt(org.bukkit.World world) {
|
||||
return new BukkitServerWorld(world);
|
||||
}
|
||||
|
||||
|
||||
public static org.bukkit.World adapt(ServerWorld world) {
|
||||
return (org.bukkit.World) world.getHandle();
|
||||
}
|
||||
|
||||
|
||||
public static Chunk adapt(org.bukkit.Chunk chunk) {
|
||||
return new BukkitChunk(chunk);
|
||||
}
|
||||
|
||||
|
||||
public static org.bukkit.Chunk adapt(Chunk chunk) {
|
||||
return (org.bukkit.Chunk) chunk.getHandle();
|
||||
}
|
||||
|
||||
|
||||
public static Enchantment adapt(org.bukkit.enchantments.Enchantment enchantment) {
|
||||
return new BukkitEnchantment(enchantment);
|
||||
}
|
||||
|
||||
|
||||
public static org.bukkit.enchantments.Enchantment adapt(Enchantment enchantment) {
|
||||
return ((BukkitEnchantment) enchantment).getHandle();
|
||||
}
|
||||
|
||||
|
||||
public static Player adapt(com.dfsek.terra.api.entity.Player player) {
|
||||
return ((BukkitPlayer) player).getHandle();
|
||||
}
|
||||
|
||||
|
||||
public static com.dfsek.terra.api.entity.Player adapt(Player player) {
|
||||
return new BukkitPlayer(player);
|
||||
}
|
||||
|
||||
|
||||
public static BukkitBlockTypeAndItem adapt(Material material) {
|
||||
return new BukkitBlockTypeAndItem(material);
|
||||
}
|
||||
|
||||
|
||||
public static Material adapt(BlockType type) {
|
||||
return ((BukkitBlockTypeAndItem) type).getHandle();
|
||||
}
|
||||
|
||||
|
||||
public static ItemStack adapt(org.bukkit.inventory.ItemStack in) {
|
||||
return new BukkitItemStack(in);
|
||||
}
|
||||
|
||||
|
||||
public static org.bukkit.inventory.ItemStack adapt(ItemStack in) {
|
||||
return ((BukkitItemStack) in).getHandle();
|
||||
}
|
||||
|
||||
@@ -26,41 +26,41 @@ import com.dfsek.terra.api.world.chunk.Chunk;
|
||||
|
||||
public class BukkitChunk implements Chunk {
|
||||
private final org.bukkit.Chunk delegate;
|
||||
|
||||
|
||||
public BukkitChunk(org.bukkit.Chunk delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public org.bukkit.Chunk getHandle() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, BlockState data, boolean physics) {
|
||||
delegate.getBlock(x, y, z).setBlockData(BukkitAdapter.adapt(data), physics);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, @NotNull BlockState blockState) {
|
||||
delegate.getBlock(x, y, z).setBlockData(BukkitAdapter.adapt(blockState));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull BlockState getBlock(int x, int y, int z) {
|
||||
return BukkitAdapter.adapt(delegate.getBlock(x, y, z).getBlockData());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getX() {
|
||||
return delegate.getX();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getZ() {
|
||||
return delegate.getZ();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ServerWorld getWorld() {
|
||||
return BukkitAdapter.adapt(delegate.getWorld());
|
||||
|
||||
+3
-3
@@ -25,16 +25,16 @@ import com.dfsek.terra.api.world.biome.PlatformBiome;
|
||||
public class BukkitPlatformBiome implements PlatformBiome, PropertyHolder {
|
||||
private final org.bukkit.block.Biome biome;
|
||||
private final Context context = new Context();
|
||||
|
||||
|
||||
public BukkitPlatformBiome(org.bukkit.block.Biome biome) {
|
||||
this.biome = biome;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public org.bukkit.block.Biome getHandle() {
|
||||
return biome;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Context getContext() {
|
||||
return context;
|
||||
|
||||
+24
-24
@@ -32,20 +32,20 @@ public class BukkitProtoWorld implements ProtoWorld {
|
||||
private static final AtomicBoolean warn = new AtomicBoolean(true);
|
||||
private final LimitedRegion delegate;
|
||||
private final BlockState air;
|
||||
|
||||
|
||||
private final BiomeProvider biomeProvider;
|
||||
|
||||
|
||||
public BukkitProtoWorld(LimitedRegion delegate, BlockState air, BiomeProvider provider) {
|
||||
this.delegate = delegate;
|
||||
this.air = air;
|
||||
this.biomeProvider = provider;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public LimitedRegion getHandle() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setBlockState(int x, int y, int z, BlockState data, boolean physics) {
|
||||
access(x, y, z, () -> {
|
||||
@@ -60,91 +60,91 @@ public class BukkitProtoWorld implements ProtoWorld {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long getSeed() {
|
||||
return delegate.getWorld().getSeed();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMaxHeight() {
|
||||
return delegate.getWorld().getMaxHeight();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BlockState getBlockState(int x, int y, int z) {
|
||||
return access(x, y, z, () -> BukkitBlockState.newInstance(delegate.getBlockData(x, y, z))).orElse(air);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BlockEntity getBlockEntity(int x, int y, int z) {
|
||||
return access(x, y, z, () -> BukkitBlockEntity.newInstance(delegate.getBlockState(x, y, z))).orElse(null);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMinHeight() {
|
||||
return delegate.getWorld().getMinHeight();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Entity spawnEntity(double x, double y, double z, EntityType entityType) {
|
||||
return access((int) x, (int) y, (int) z, () -> new BukkitEntity(
|
||||
delegate.spawnEntity(new Location(delegate.getWorld(), x, y, z), ((BukkitEntityType) entityType).getHandle()))).orElse(
|
||||
null);
|
||||
delegate.spawnEntity(new Location(delegate.getWorld(), x, y, z), ((BukkitEntityType) entityType).getHandle()))).orElse(
|
||||
null);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ChunkGenerator getGenerator() {
|
||||
return ((BukkitChunkGeneratorWrapper) delegate.getWorld().getGenerator()).getHandle();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BiomeProvider getBiomeProvider() {
|
||||
return biomeProvider;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ConfigPack getPack() {
|
||||
return ((BukkitChunkGeneratorWrapper) delegate.getWorld().getGenerator()).getPack();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int centerChunkX() {
|
||||
return delegate.getCenterChunkX();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int centerChunkZ() {
|
||||
return delegate.getCenterChunkZ();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ServerWorld getWorld() {
|
||||
return new BukkitServerWorld(delegate.getWorld());
|
||||
}
|
||||
|
||||
|
||||
private <T> Optional<T> access(int x, int y, int z, Supplier<T> action) {
|
||||
if(delegate.isInRegion(x, y, z)) {
|
||||
return Optional.of(action.get());
|
||||
} else if(warn.getAndSet(false)) {
|
||||
LOGGER.warn("Detected world access at coordinates out of bounds: ({}, {}, {}) accessed for region [{}, {}]", x, y, z,
|
||||
delegate.getCenterChunkX(), delegate.getCenterChunkZ());
|
||||
delegate.getCenterChunkX(), delegate.getCenterChunkZ());
|
||||
} else {
|
||||
LOGGER.debug("Detected world access at coordinates out of bounds: ({}, {}, {}) accessed for region [{}, {}]", x, y, z,
|
||||
delegate.getCenterChunkX(), delegate.getCenterChunkZ());
|
||||
delegate.getCenterChunkX(), delegate.getCenterChunkZ());
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
|
||||
private void access(int x, int y, int z, Runnable action) {
|
||||
if(delegate.isInRegion(x, y, z)) {
|
||||
action.run();
|
||||
} else if(warn.getAndSet(false)) {
|
||||
LOGGER.warn("Detected world access at coordinates out of bounds: ({}, {}, {}) accessed for region [{}, {}]", x, y, z,
|
||||
delegate.getCenterChunkX(), delegate.getCenterChunkZ());
|
||||
delegate.getCenterChunkX(), delegate.getCenterChunkZ());
|
||||
} else {
|
||||
LOGGER.debug("Detected world access at coordinates out of bounds: ({}, {}, {}) accessed for region [{}, {}]", x, y, z,
|
||||
delegate.getCenterChunkX(), delegate.getCenterChunkZ());
|
||||
delegate.getCenterChunkX(), delegate.getCenterChunkZ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+17
-17
@@ -36,83 +36,83 @@ import com.dfsek.terra.bukkit.world.entity.BukkitEntityType;
|
||||
|
||||
public class BukkitServerWorld implements ServerWorld {
|
||||
private final org.bukkit.World delegate;
|
||||
|
||||
|
||||
public BukkitServerWorld(org.bukkit.World delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Entity spawnEntity(double x, double y, double z, EntityType entityType) {
|
||||
return new BukkitEntity(
|
||||
delegate.spawnEntity(new Location(delegate, x, y, z), ((BukkitEntityType) entityType).getHandle()));
|
||||
delegate.spawnEntity(new Location(delegate, x, y, z), ((BukkitEntityType) entityType).getHandle()));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setBlockState(int x, int y, int z, BlockState data, boolean physics) {
|
||||
delegate.getBlockAt(x, y, z).setBlockData(BukkitAdapter.adapt(data), physics);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long getSeed() {
|
||||
return delegate.getSeed();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMaxHeight() {
|
||||
return delegate.getMaxHeight();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Chunk getChunkAt(int x, int z) {
|
||||
return BukkitAdapter.adapt(delegate.getChunkAt(x, z));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BlockState getBlockState(int x, int y, int z) {
|
||||
return BukkitAdapter.adapt(delegate.getBlockAt(x, y, z).getBlockData());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BlockEntity getBlockEntity(int x, int y, int z) {
|
||||
return BukkitBlockEntity.newInstance(delegate.getBlockAt(x, y, z).getState());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMinHeight() {
|
||||
return delegate.getMinHeight();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ChunkGenerator getGenerator() {
|
||||
return ((BukkitChunkGeneratorWrapper) delegate.getGenerator()).getHandle();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BiomeProvider getBiomeProvider() {
|
||||
return ((BukkitChunkGeneratorWrapper) delegate.getGenerator()).getPack().getBiomeProvider();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ConfigPack getPack() {
|
||||
return ((BukkitChunkGeneratorWrapper) delegate.getGenerator()).getPack();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public org.bukkit.World getHandle() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return delegate.hashCode();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(!(obj instanceof BukkitServerWorld other)) return false;
|
||||
return other.getHandle().equals(delegate);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return delegate.toString();
|
||||
|
||||
+7
-7
@@ -7,36 +7,36 @@ import com.dfsek.terra.api.world.info.WorldProperties;
|
||||
|
||||
public class BukkitWorldProperties implements WorldProperties {
|
||||
private final WorldInfo delegate;
|
||||
|
||||
|
||||
public BukkitWorldProperties(WorldInfo delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object getHandle() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long getSeed() {
|
||||
return delegate.getSeed();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMaxHeight() {
|
||||
return delegate.getMaxHeight();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMinHeight() {
|
||||
return delegate.getMinHeight();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return delegate.hashCode();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(obj instanceof WorldProperties that) {
|
||||
|
||||
+9
-9
@@ -28,46 +28,46 @@ import com.dfsek.terra.bukkit.world.BukkitAdapter;
|
||||
|
||||
public class BukkitBlockTypeAndItem implements BlockType, Item {
|
||||
private final Material delegate;
|
||||
|
||||
|
||||
public BukkitBlockTypeAndItem(Material delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Material getHandle() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BlockState getDefaultState() {
|
||||
return BukkitAdapter.adapt(delegate.createBlockData());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isSolid() {
|
||||
return delegate.isOccluding();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isWater() {
|
||||
return delegate == Material.WATER;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ItemStack newItemStack(int amount) {
|
||||
return BukkitAdapter.adapt(new org.bukkit.inventory.ItemStack(delegate, amount));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public double getMaxDurability() {
|
||||
return delegate.getMaxDurability();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return delegate.hashCode();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(!(obj instanceof BukkitBlockTypeAndItem)) return false;
|
||||
|
||||
+11
-11
@@ -25,51 +25,51 @@ import com.dfsek.terra.bukkit.world.BukkitAdapter;
|
||||
|
||||
public class BukkitBlockState implements BlockState {
|
||||
private final org.bukkit.block.data.BlockData delegate;
|
||||
|
||||
|
||||
protected BukkitBlockState(org.bukkit.block.data.BlockData delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
|
||||
public static BlockState newInstance(org.bukkit.block.data.BlockData bukkitData) {
|
||||
return new BukkitBlockState(bukkitData);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public org.bukkit.block.data.BlockData getHandle() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean matches(BlockState data) {
|
||||
return delegate.getMaterial() == ((BukkitBlockState) data).getHandle().getMaterial();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public <T extends Comparable<T>> boolean has(Property<T> property) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public <T extends Comparable<T>> T get(Property<T> property) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public <T extends Comparable<T>> BlockState set(Property<T> property, T value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BlockType getBlockType() {
|
||||
return BukkitAdapter.adapt(delegate.getMaterial());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getAsString(boolean properties) {
|
||||
return delegate.getAsString(!properties);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isAir() {
|
||||
return delegate.getMaterial().isAir();
|
||||
|
||||
+9
-9
@@ -30,48 +30,48 @@ import com.dfsek.terra.bukkit.world.block.data.BukkitBlockState;
|
||||
|
||||
public class BukkitBlockEntity implements BlockEntity {
|
||||
private final org.bukkit.block.BlockState delegate;
|
||||
|
||||
|
||||
protected BukkitBlockEntity(org.bukkit.block.BlockState block) {
|
||||
this.delegate = block;
|
||||
}
|
||||
|
||||
|
||||
public static BukkitBlockEntity newInstance(org.bukkit.block.BlockState block) {
|
||||
if(block instanceof Container) return new BukkitContainer((Container) block);
|
||||
if(block instanceof Sign) return new BukkitSign((Sign) block);
|
||||
if(block instanceof CreatureSpawner) return new BukkitMobSpawner((CreatureSpawner) block);
|
||||
return new BukkitBlockEntity(block);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public org.bukkit.block.BlockState getHandle() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean update(boolean applyPhysics) {
|
||||
return delegate.update(true, applyPhysics);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Vector3 getPosition() {
|
||||
return BukkitAdapter.adapt(delegate.getBlock().getLocation().toVector());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getX() {
|
||||
return delegate.getX();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getY() {
|
||||
return delegate.getY();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getZ() {
|
||||
return delegate.getZ();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BlockState getBlockState() {
|
||||
return BukkitBlockState.newInstance(delegate.getBlockData());
|
||||
|
||||
+3
-3
@@ -23,16 +23,16 @@ import com.dfsek.terra.bukkit.world.inventory.BukkitInventory;
|
||||
|
||||
|
||||
public class BukkitContainer extends BukkitBlockEntity implements Container {
|
||||
|
||||
|
||||
protected BukkitContainer(org.bukkit.block.Container block) {
|
||||
super(block);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Inventory getInventory() {
|
||||
return new BukkitInventory(((org.bukkit.block.Container) getHandle()).getInventory());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean update(boolean applyPhysics) {
|
||||
return false; // This clears the inventory. we don't want that.
|
||||
|
||||
+17
-17
@@ -30,87 +30,87 @@ public class BukkitMobSpawner extends BukkitBlockEntity implements MobSpawner {
|
||||
protected BukkitMobSpawner(CreatureSpawner block) {
|
||||
super(block);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public EntityType getSpawnedType() {
|
||||
return new BukkitEntityType(((CreatureSpawner) getHandle()).getSpawnedType());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setSpawnedType(@NotNull EntityType creatureType) {
|
||||
((CreatureSpawner) getHandle()).setSpawnedType(((BukkitEntityType) creatureType).getHandle());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getDelay() {
|
||||
return ((CreatureSpawner) getHandle()).getDelay();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setDelay(int delay) {
|
||||
((CreatureSpawner) getHandle()).setDelay(delay);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMinSpawnDelay() {
|
||||
return ((CreatureSpawner) getHandle()).getMinSpawnDelay();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setMinSpawnDelay(int delay) {
|
||||
((CreatureSpawner) getHandle()).setMinSpawnDelay(delay);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMaxSpawnDelay() {
|
||||
return ((CreatureSpawner) getHandle()).getMaxSpawnDelay();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setMaxSpawnDelay(int delay) {
|
||||
((CreatureSpawner) getHandle()).setMaxSpawnDelay(delay);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getSpawnCount() {
|
||||
return ((CreatureSpawner) getHandle()).getSpawnCount();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setSpawnCount(int spawnCount) {
|
||||
((CreatureSpawner) getHandle()).setSpawnCount(spawnCount);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMaxNearbyEntities() {
|
||||
return ((CreatureSpawner) getHandle()).getMaxNearbyEntities();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setMaxNearbyEntities(int maxNearbyEntities) {
|
||||
((CreatureSpawner) getHandle()).setMaxNearbyEntities(maxNearbyEntities);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getRequiredPlayerRange() {
|
||||
return ((CreatureSpawner) getHandle()).getRequiredPlayerRange();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setRequiredPlayerRange(int requiredPlayerRange) {
|
||||
((CreatureSpawner) getHandle()).setRequiredPlayerRange(requiredPlayerRange);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getSpawnRange() {
|
||||
return ((CreatureSpawner) getHandle()).getSpawnRange();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setSpawnRange(int spawnRange) {
|
||||
((CreatureSpawner) getHandle()).setSpawnRange(spawnRange);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void applyState(String state) {
|
||||
SerialState.parse(state).forEach((k, v) -> {
|
||||
|
||||
+4
-4
@@ -28,22 +28,22 @@ public class BukkitSign extends BukkitBlockEntity implements Sign {
|
||||
protected BukkitSign(org.bukkit.block.Sign block) {
|
||||
super(block);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setLine(int index, @NotNull String line) throws IndexOutOfBoundsException {
|
||||
((org.bukkit.block.Sign) getHandle()).setLine(index, line);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull String[] getLines() {
|
||||
return ((org.bukkit.block.Sign) getHandle()).getLines();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull String getLine(int index) throws IndexOutOfBoundsException {
|
||||
return ((org.bukkit.block.Sign) getHandle()).getLine(index);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void applyState(String state) {
|
||||
SerialState.parse(state).forEach((k, v) -> {
|
||||
|
||||
+2
-2
@@ -22,11 +22,11 @@ import com.dfsek.terra.api.entity.EntityType;
|
||||
|
||||
public class BukkitEntityType implements EntityType {
|
||||
private final org.bukkit.entity.EntityType delegate;
|
||||
|
||||
|
||||
public BukkitEntityType(org.bukkit.entity.EntityType delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public org.bukkit.entity.EntityType getHandle() {
|
||||
return delegate;
|
||||
|
||||
+5
-5
@@ -23,27 +23,27 @@ import com.dfsek.terra.api.inventory.ItemStack;
|
||||
|
||||
public class BukkitInventory implements Inventory {
|
||||
private final org.bukkit.inventory.Inventory delegate;
|
||||
|
||||
|
||||
public BukkitInventory(org.bukkit.inventory.Inventory delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setItem(int slot, ItemStack newStack) {
|
||||
delegate.setItem(slot, ((BukkitItemStack) newStack).getHandle());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
return delegate.getSize();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ItemStack getItem(int slot) {
|
||||
org.bukkit.inventory.ItemStack itemStack = delegate.getItem(slot);
|
||||
return itemStack == null ? null : new BukkitItemStack(itemStack);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public org.bukkit.inventory.Inventory getHandle() {
|
||||
return delegate;
|
||||
|
||||
+5
-5
@@ -31,26 +31,26 @@ import com.dfsek.terra.bukkit.world.inventory.meta.BukkitEnchantment;
|
||||
|
||||
public class BukkitItemMeta implements ItemMeta {
|
||||
private final org.bukkit.inventory.meta.ItemMeta delegate;
|
||||
|
||||
|
||||
protected BukkitItemMeta(org.bukkit.inventory.meta.ItemMeta delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
|
||||
public static BukkitItemMeta newInstance(org.bukkit.inventory.meta.ItemMeta delegate) {
|
||||
if(delegate instanceof Damageable) return new BukkitDamageable((Damageable) delegate);
|
||||
return new BukkitItemMeta(delegate);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public org.bukkit.inventory.meta.ItemMeta getHandle() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addEnchantment(Enchantment enchantment, int level) {
|
||||
delegate.addEnchant(((BukkitEnchantment) enchantment).getHandle(), level, true);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Map<Enchantment, Integer> getEnchantments() {
|
||||
Map<Enchantment, Integer> map = new HashMap<>();
|
||||
|
||||
+7
-7
@@ -25,36 +25,36 @@ import com.dfsek.terra.bukkit.world.BukkitAdapter;
|
||||
|
||||
public class BukkitItemStack implements ItemStack {
|
||||
private final org.bukkit.inventory.ItemStack delegate;
|
||||
|
||||
|
||||
public BukkitItemStack(org.bukkit.inventory.ItemStack delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getAmount() {
|
||||
return delegate.getAmount();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setAmount(int i) {
|
||||
delegate.setAmount(i);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Item getType() {
|
||||
return BukkitAdapter.adapt(delegate.getType());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ItemMeta getItemMeta() {
|
||||
return BukkitItemMeta.newInstance(delegate.getItemMeta());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setItemMeta(ItemMeta meta) {
|
||||
delegate.setItemMeta(((BukkitItemMeta) meta).getHandle());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public org.bukkit.inventory.ItemStack getHandle() {
|
||||
return delegate;
|
||||
|
||||
+3
-3
@@ -25,17 +25,17 @@ public class BukkitDamageable extends BukkitItemMeta implements Damageable {
|
||||
public BukkitDamageable(org.bukkit.inventory.meta.Damageable delegate) {
|
||||
super(delegate);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getDamage() {
|
||||
return ((org.bukkit.inventory.meta.Damageable) getHandle()).getDamage();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setDamage(int damage) {
|
||||
((org.bukkit.inventory.meta.Damageable) getHandle()).setDamage(damage);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean hasDamage() {
|
||||
return ((org.bukkit.inventory.meta.Damageable) getHandle()).hasDamage();
|
||||
|
||||
+6
-6
@@ -24,31 +24,31 @@ import com.dfsek.terra.bukkit.world.inventory.BukkitItemStack;
|
||||
|
||||
public class BukkitEnchantment implements Enchantment {
|
||||
private final org.bukkit.enchantments.Enchantment delegate;
|
||||
|
||||
|
||||
public BukkitEnchantment(org.bukkit.enchantments.Enchantment delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public org.bukkit.enchantments.Enchantment getHandle() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean canEnchantItem(ItemStack itemStack) {
|
||||
return delegate.canEnchantItem(((BukkitItemStack) itemStack).getHandle());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean conflictsWith(Enchantment other) {
|
||||
return delegate.conflictsWith(((BukkitEnchantment) other).getHandle());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
return delegate.getKey().toString();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMaxLevel() {
|
||||
return delegate.getMaxLevel();
|
||||
|
||||
+54
-54
@@ -27,87 +27,87 @@ import com.dfsek.terra.registry.master.ConfigRegistry;
|
||||
public class AwfulBukkitHacks {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(NMSBiomeInjector.class);
|
||||
private static final Map<ResourceLocation, List<ResourceLocation>> terraBiomeMap = new HashMap<>();
|
||||
|
||||
|
||||
|
||||
|
||||
public static void registerBiomes(ConfigRegistry configRegistry) {
|
||||
try {
|
||||
LOGGER.info("Hacking biome registry...");
|
||||
WritableRegistry<Biome> biomeRegistry = (WritableRegistry<Biome>) Registries.biomeRegistry();
|
||||
|
||||
|
||||
Reflection.MAPPED_REGISTRY.setFrozen((MappedRegistry<?>) biomeRegistry, false);
|
||||
|
||||
|
||||
configRegistry.forEach(pack -> pack.getRegistry(com.dfsek.terra.api.world.biome.Biome.class).forEach((key, biome) -> {
|
||||
try {
|
||||
BukkitPlatformBiome platformBiome = (BukkitPlatformBiome) biome.getPlatformBiome();
|
||||
NamespacedKey vanillaBukkitKey = platformBiome.getHandle().getKey();
|
||||
ResourceLocation vanillaMinecraftKey = new ResourceLocation(vanillaBukkitKey.getNamespace(), vanillaBukkitKey.getKey());
|
||||
Biome platform = NMSBiomeInjector.createBiome(
|
||||
biome,
|
||||
biomeRegistry.get(vanillaMinecraftKey) // get
|
||||
);
|
||||
|
||||
biome,
|
||||
biomeRegistry.get(vanillaMinecraftKey) // get
|
||||
);
|
||||
|
||||
ResourceKey<Biome> delegateKey = ResourceKey.create(Registry.BIOME_REGISTRY, new ResourceLocation("terra",
|
||||
NMSBiomeInjector.createBiomeID(
|
||||
pack, key)));
|
||||
|
||||
NMSBiomeInjector.createBiomeID(
|
||||
pack, key)));
|
||||
|
||||
BuiltinRegistries.register(BuiltinRegistries.BIOME, delegateKey, platform);
|
||||
biomeRegistry.register(delegateKey, platform, Lifecycle.stable());
|
||||
platformBiome.getContext().put(new NMSBiomeInfo(delegateKey));
|
||||
|
||||
|
||||
terraBiomeMap.computeIfAbsent(vanillaMinecraftKey, i -> new ArrayList<>()).add(delegateKey.location());
|
||||
|
||||
|
||||
LOGGER.debug("Registered biome: " + delegateKey);
|
||||
} catch(NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
Reflection.MAPPED_REGISTRY.setFrozen((MappedRegistry<?>) biomeRegistry, true); // freeze registry again :)
|
||||
|
||||
|
||||
LOGGER.info("Doing tag garbage....");
|
||||
Map<TagKey<Biome>, List<Holder<Biome>>> collect = biomeRegistry
|
||||
.getTags() // streamKeysAndEntries
|
||||
.collect(HashMap::new,
|
||||
(map, pair) ->
|
||||
map.put(pair.getFirst(), new ArrayList<>(pair.getSecond().stream().toList())),
|
||||
HashMap::putAll);
|
||||
|
||||
.getTags() // streamKeysAndEntries
|
||||
.collect(HashMap::new,
|
||||
(map, pair) ->
|
||||
map.put(pair.getFirst(), new ArrayList<>(pair.getSecond().stream().toList())),
|
||||
HashMap::putAll);
|
||||
|
||||
terraBiomeMap
|
||||
.forEach((vb, terraBiomes) ->
|
||||
NMSBiomeInjector.getEntry(biomeRegistry, vb)
|
||||
.ifPresentOrElse(
|
||||
vanilla -> terraBiomes
|
||||
.forEach(tb -> NMSBiomeInjector.getEntry(biomeRegistry, tb)
|
||||
.ifPresentOrElse(
|
||||
terra -> {
|
||||
LOGGER.debug(
|
||||
vanilla.unwrapKey()
|
||||
.orElseThrow()
|
||||
.location() +
|
||||
" (vanilla for " +
|
||||
terra.unwrapKey()
|
||||
.orElseThrow()
|
||||
.location() +
|
||||
": " +
|
||||
vanilla.tags()
|
||||
.toList());
|
||||
|
||||
vanilla.tags()
|
||||
.forEach(
|
||||
tag -> collect
|
||||
.computeIfAbsent(
|
||||
tag,
|
||||
t -> new ArrayList<>())
|
||||
.add(terra));
|
||||
},
|
||||
() -> LOGGER.error(
|
||||
"No such biome: {}",
|
||||
tb))),
|
||||
() -> LOGGER.error("No vanilla biome: {}", vb)));
|
||||
|
||||
.forEach((vb, terraBiomes) ->
|
||||
NMSBiomeInjector.getEntry(biomeRegistry, vb)
|
||||
.ifPresentOrElse(
|
||||
vanilla -> terraBiomes
|
||||
.forEach(tb -> NMSBiomeInjector.getEntry(biomeRegistry, tb)
|
||||
.ifPresentOrElse(
|
||||
terra -> {
|
||||
LOGGER.debug(
|
||||
vanilla.unwrapKey()
|
||||
.orElseThrow()
|
||||
.location() +
|
||||
" (vanilla for " +
|
||||
terra.unwrapKey()
|
||||
.orElseThrow()
|
||||
.location() +
|
||||
": " +
|
||||
vanilla.tags()
|
||||
.toList());
|
||||
|
||||
vanilla.tags()
|
||||
.forEach(
|
||||
tag -> collect
|
||||
.computeIfAbsent(
|
||||
tag,
|
||||
t -> new ArrayList<>())
|
||||
.add(terra));
|
||||
},
|
||||
() -> LOGGER.error(
|
||||
"No such biome: {}",
|
||||
tb))),
|
||||
() -> LOGGER.error("No vanilla biome: {}", vb)));
|
||||
|
||||
biomeRegistry.resetTags(); // clearTags
|
||||
biomeRegistry.bindTags(ImmutableMap.copyOf(collect)); // populateTags
|
||||
|
||||
|
||||
} catch(SecurityException | IllegalArgumentException exception) {
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
|
||||
+28
-28
@@ -15,63 +15,63 @@ import com.dfsek.terra.bukkit.config.VanillaBiomeProperties;
|
||||
|
||||
|
||||
public class NMSBiomeInjector {
|
||||
|
||||
|
||||
public static <T> Optional<Holder<T>> getEntry(Registry<T> registry, ResourceLocation identifier) {
|
||||
return registry.getOptional(identifier)
|
||||
.flatMap(registry::getResourceKey)
|
||||
.map(registry::getOrCreateHolder);
|
||||
.flatMap(registry::getResourceKey)
|
||||
.map(registry::getOrCreateHolder);
|
||||
}
|
||||
|
||||
|
||||
public static Biome createBiome(com.dfsek.terra.api.world.biome.Biome biome, Biome vanilla)
|
||||
throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
|
||||
Biome.BiomeBuilder builder = new Biome.BiomeBuilder(); // Builder
|
||||
|
||||
|
||||
|
||||
|
||||
builder.biomeCategory(Reflection.BIOME.getBiomeCategory(vanilla))
|
||||
.precipitation(vanilla.getPrecipitation()) // getPrecipitation
|
||||
.mobSpawnSettings(vanilla.getMobSettings())
|
||||
.generationSettings(vanilla.getGenerationSettings())
|
||||
.temperature(vanilla.getBaseTemperature())
|
||||
.downfall(vanilla.getDownfall());
|
||||
|
||||
|
||||
.precipitation(vanilla.getPrecipitation()) // getPrecipitation
|
||||
.mobSpawnSettings(vanilla.getMobSettings())
|
||||
.generationSettings(vanilla.getGenerationSettings())
|
||||
.temperature(vanilla.getBaseTemperature())
|
||||
.downfall(vanilla.getDownfall());
|
||||
|
||||
|
||||
BiomeSpecialEffects.Builder effects = new BiomeSpecialEffects.Builder();
|
||||
|
||||
|
||||
effects.grassColorModifier(vanilla.getSpecialEffects().getGrassColorModifier());
|
||||
|
||||
|
||||
VanillaBiomeProperties vanillaBiomeProperties = biome.getContext().get(VanillaBiomeProperties.class);
|
||||
|
||||
|
||||
effects.fogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getFogColor(), vanilla.getFogColor()))
|
||||
|
||||
.waterColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterColor(), vanilla.getWaterColor()))
|
||||
|
||||
.waterFogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterFogColor(), vanilla.getWaterFogColor()))
|
||||
|
||||
.skyColor(Objects.requireNonNullElse(vanillaBiomeProperties.getSkyColor(), vanilla.getSkyColor()));
|
||||
|
||||
|
||||
.waterColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterColor(), vanilla.getWaterColor()))
|
||||
|
||||
.waterFogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterFogColor(), vanilla.getWaterFogColor()))
|
||||
|
||||
.skyColor(Objects.requireNonNullElse(vanillaBiomeProperties.getSkyColor(), vanilla.getSkyColor()));
|
||||
|
||||
if(vanillaBiomeProperties.getFoliageColor() == null) {
|
||||
vanilla.getSpecialEffects().getFoliageColorOverride().ifPresent(effects::foliageColorOverride);
|
||||
} else {
|
||||
effects.foliageColorOverride(vanillaBiomeProperties.getFoliageColor());
|
||||
}
|
||||
|
||||
|
||||
if(vanillaBiomeProperties.getGrassColor() == null) {
|
||||
vanilla.getSpecialEffects().getGrassColorOverride().ifPresent(effects::grassColorOverride);
|
||||
} else {
|
||||
effects.grassColorOverride(vanillaBiomeProperties.getGrassColor());
|
||||
}
|
||||
|
||||
|
||||
vanilla.getAmbientLoop().ifPresent(effects::ambientLoopSound);
|
||||
vanilla.getAmbientAdditions().ifPresent(effects::ambientAdditionsSound);
|
||||
vanilla.getAmbientMood().ifPresent(effects::ambientMoodSound);
|
||||
vanilla.getBackgroundMusic().ifPresent(effects::backgroundMusic);
|
||||
vanilla.getAmbientParticle().ifPresent(effects::ambientParticle);
|
||||
|
||||
|
||||
builder.specialEffects(effects.build());
|
||||
|
||||
|
||||
return builder.build(); // build()
|
||||
}
|
||||
|
||||
|
||||
public static String createBiomeID(ConfigPack pack, com.dfsek.terra.api.registry.key.RegistryKey biomeID) {
|
||||
return pack.getID()
|
||||
.toLowerCase() + "/" + biomeID.getNamespace().toLowerCase(Locale.ROOT) + "/" + biomeID.getID().toLowerCase(Locale.ROOT);
|
||||
|
||||
+11
-11
@@ -17,33 +17,33 @@ public class NMSBiomeProvider extends BiomeSource {
|
||||
private final BiomeSource vanilla;
|
||||
private final long seed;
|
||||
private final Registry<Biome> biomeRegistry = Registries.biomeRegistry();
|
||||
|
||||
|
||||
public NMSBiomeProvider(BiomeProvider delegate, BiomeSource vanilla, long seed) {
|
||||
super(delegate.stream()
|
||||
.map(biome -> Registries.biomeRegistry()
|
||||
.getOrCreateHolder(((BukkitPlatformBiome) biome.getPlatformBiome()).getContext()
|
||||
.get(NMSBiomeInfo.class)
|
||||
.biomeKey())));
|
||||
.map(biome -> Registries.biomeRegistry()
|
||||
.getOrCreateHolder(((BukkitPlatformBiome) biome.getPlatformBiome()).getContext()
|
||||
.get(NMSBiomeInfo.class)
|
||||
.biomeKey())));
|
||||
this.delegate = delegate;
|
||||
this.vanilla = vanilla;
|
||||
this.seed = seed;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Codec<? extends BiomeSource> codec() {
|
||||
return BiomeSource.CODEC;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull BiomeSource withSeed(long seed) {
|
||||
return new NMSBiomeProvider(delegate, vanilla, seed);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull Holder<Biome> getNoiseBiome(int x, int y, int z, @NotNull Sampler sampler) {
|
||||
return biomeRegistry.getOrCreateHolder(((BukkitPlatformBiome) delegate.getBiome(x << 2, y << 2, z << 2, seed).getPlatformBiome())
|
||||
.getContext()
|
||||
.get(NMSBiomeInfo.class)
|
||||
.biomeKey());
|
||||
.getContext()
|
||||
.get(NMSBiomeInfo.class)
|
||||
.biomeKey());
|
||||
}
|
||||
}
|
||||
|
||||
+35
-35
@@ -58,7 +58,7 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
private final long seed;
|
||||
private final Map<ConcentricRingsStructurePlacement, Lazy<List<ChunkPos>>> ringPositions = new Object2ObjectArrayMap<>();
|
||||
private volatile boolean rings = false;
|
||||
|
||||
|
||||
public NMSChunkGeneratorDelegate(ChunkGenerator vanilla, ConfigPack pack, NMSBiomeProvider biomeProvider, long seed) {
|
||||
super(Registries.structureSet(), Optional.empty(), biomeProvider, biomeProvider, seed);
|
||||
this.delegate = pack.getGeneratorProvider().newInstance(pack);
|
||||
@@ -67,42 +67,42 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
this.pack = pack;
|
||||
this.seed = seed;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void applyCarvers(@NotNull WorldGenRegion chunkRegion, long seed, @NotNull BiomeManager biomeAccess,
|
||||
@NotNull StructureFeatureManager structureAccessor,
|
||||
@NotNull ChunkAccess chunk, GenerationStep.@NotNull Carving generationStep) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void applyBiomeDecoration(@NotNull WorldGenLevel world, @NotNull ChunkAccess chunk,
|
||||
@NotNull StructureFeatureManager structureAccessor) {
|
||||
vanilla.applyBiomeDecoration(world, chunk, structureAccessor);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getSeaLevel() {
|
||||
return vanilla.getSeaLevel();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull CompletableFuture<ChunkAccess> fillFromNoise(@NotNull Executor executor, @NotNull Blender blender,
|
||||
@NotNull StructureFeatureManager structureAccessor,
|
||||
@NotNull ChunkAccess chunk) {
|
||||
return vanilla.fillFromNoise(executor, blender, structureAccessor, chunk);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void buildSurface(@NotNull WorldGenRegion region, @NotNull StructureFeatureManager structures, @NotNull ChunkAccess chunk) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected @NotNull Codec<? extends ChunkGenerator> codec() {
|
||||
return ChunkGenerator.CODEC;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull NoiseColumn getBaseColumn(int x, int z, LevelHeightAccessor height) {
|
||||
/*
|
||||
@@ -117,51 +117,51 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
*/
|
||||
return vanilla.getBaseColumn(x, z, height);
|
||||
}
|
||||
|
||||
|
||||
@Override // withSeed
|
||||
public @NotNull ChunkGenerator withSeed(long seed) {
|
||||
return new NMSChunkGeneratorDelegate(vanilla, pack, biomeSource, seed);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void spawnOriginalMobs(@NotNull WorldGenRegion regionlimitedworldaccess) {
|
||||
vanilla.spawnOriginalMobs(regionlimitedworldaccess);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getGenDepth() {
|
||||
return vanilla.getGenDepth();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull Sampler climateSampler() {
|
||||
return Climate.empty();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMinY() {
|
||||
return vanilla.getMinY();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getBaseHeight(int x, int z, Heightmap.@NotNull Types heightmap, @NotNull LevelHeightAccessor world) {
|
||||
WorldProperties properties = new NMSWorldProperties(seed, world);
|
||||
int y = properties.getMaxHeight();
|
||||
BiomeProvider biomeProvider = pack.getBiomeProvider();
|
||||
while(y >= getMinY() && !heightmap.isOpaque().test(
|
||||
((CraftBlockData) delegate.getBlock(properties, x, y - 1, z, biomeProvider).getHandle()).getState())) {
|
||||
((CraftBlockData) delegate.getBlock(properties, x, y - 1, z, biomeProvider).getHandle()).getState())) {
|
||||
y--;
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<ChunkPos> getRingPositionsFor(@NotNull ConcentricRingsStructurePlacement concentricringsstructureplacement) {
|
||||
ensureStructuresGenerated();
|
||||
return ringPositions.getOrDefault(concentricringsstructureplacement, EMPTY).value();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public synchronized void ensureStructuresGenerated() {
|
||||
if(!this.rings) {
|
||||
@@ -170,7 +170,7 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
this.rings = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void populateStrongholdData() {
|
||||
LOGGER.info("Generating safe stronghold data. This may take up to a minute.");
|
||||
Set<Holder<Biome>> set = this.runtimeBiomeSource.possibleBiomes();
|
||||
@@ -179,29 +179,29 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
if(structureplacement instanceof ConcentricRingsStructurePlacement concentricringsstructureplacement) {
|
||||
if(holder.structures().stream().anyMatch((structureset_a1) -> structureset_a1.generatesInMatchingBiome(set::contains))) {
|
||||
this.ringPositions.put(concentricringsstructureplacement,
|
||||
Lazy.lazy(() -> this.generateRingPositions(holder, concentricringsstructureplacement)));
|
||||
Lazy.lazy(() -> this.generateRingPositions(holder, concentricringsstructureplacement)));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private List<ChunkPos> generateRingPositions(StructureSet holder,
|
||||
ConcentricRingsStructurePlacement concentricringsstructureplacement) { // Spigot
|
||||
if(concentricringsstructureplacement.count() == 0) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
|
||||
List<ChunkPos> list = new ArrayList<>();
|
||||
Set<Holder<Biome>> set = holder
|
||||
.structures()
|
||||
.stream()
|
||||
.flatMap((structureset_a) -> structureset_a.structure().value().biomes().stream())
|
||||
.collect(Collectors.toSet());
|
||||
.structures()
|
||||
.stream()
|
||||
.flatMap((structureset_a) -> structureset_a.structure().value().biomes().stream())
|
||||
.collect(Collectors.toSet());
|
||||
int i = concentricringsstructureplacement.distance();
|
||||
int j = concentricringsstructureplacement.count();
|
||||
int k = concentricringsstructureplacement.spread();
|
||||
Random random = new Random();
|
||||
|
||||
|
||||
// Paper start
|
||||
if(this.conf.strongholdSeed != null && this.structureSets.getResourceKey(holder).orElse(null) ==
|
||||
net.minecraft.world.level.levelgen.structure.BuiltinStructureSets.STRONGHOLDS) {
|
||||
@@ -213,25 +213,25 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
double d0 = random.nextDouble() * 3.141592653589793D * 2.0D;
|
||||
int l = 0;
|
||||
int i1 = 0;
|
||||
|
||||
|
||||
for(int j1 = 0; j1 < j; ++j1) {
|
||||
double d1 = (double) (4 * i + i * i1 * 6) + (random.nextDouble() - 0.5D) * (double) i * 2.5D;
|
||||
int k1 = (int) Math.round(MathUtil.cos(d0) * d1);
|
||||
int l1 = (int) Math.round(MathUtil.sin(d0) * d1);
|
||||
int i2 = SectionPos.sectionToBlockCoord(k1, 8);
|
||||
int j2 = SectionPos.sectionToBlockCoord(l1, 8);
|
||||
|
||||
|
||||
Objects.requireNonNull(set);
|
||||
Pair<BlockPos, Holder<Biome>> pair = this.biomeSource.findBiomeHorizontal(i2, 0, j2, 112, set::contains, random,
|
||||
this.climateSampler());
|
||||
|
||||
this.climateSampler());
|
||||
|
||||
if(pair != null) {
|
||||
BlockPos blockposition = pair.getFirst();
|
||||
|
||||
|
||||
k1 = SectionPos.blockToSectionCoord(blockposition.getX());
|
||||
l1 = SectionPos.blockToSectionCoord(blockposition.getZ());
|
||||
}
|
||||
|
||||
|
||||
list.add(new ChunkPos(k1, l1));
|
||||
d0 += 6.283185307179586D / (double) k;
|
||||
++l;
|
||||
@@ -243,12 +243,12 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
d0 += random.nextDouble() * 3.141592653589793D * 2.0D;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addDebugScreenInfo(@NotNull List<String> arg0, @NotNull BlockPos arg1) {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+8
-8
@@ -22,7 +22,7 @@ public class NMSInjectListener implements Listener {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(NMSInjectListener.class);
|
||||
private static final Set<World> INJECTED = new HashSet<>();
|
||||
private static final ReentrantLock INJECT_LOCK = new ReentrantLock();
|
||||
|
||||
|
||||
@EventHandler
|
||||
public void onWorldInit(WorldInitEvent event) {
|
||||
if(!INJECTED.contains(event.getWorld()) &&
|
||||
@@ -32,21 +32,21 @@ public class NMSInjectListener implements Listener {
|
||||
LOGGER.info("Preparing to take over the world: {}", event.getWorld().getName());
|
||||
CraftWorld craftWorld = (CraftWorld) event.getWorld();
|
||||
ServerLevel serverWorld = craftWorld.getHandle();
|
||||
|
||||
|
||||
ConfigPack pack = bukkitChunkGeneratorWrapper.getPack();
|
||||
|
||||
|
||||
ChunkGenerator vanilla = serverWorld.getChunkSource().getGenerator();
|
||||
NMSBiomeProvider provider = new NMSBiomeProvider(pack.getBiomeProvider(), vanilla.getBiomeSource(), craftWorld.getSeed());
|
||||
NMSChunkGeneratorDelegate custom = new NMSChunkGeneratorDelegate(vanilla, pack, provider, craftWorld.getSeed());
|
||||
|
||||
|
||||
custom.conf = vanilla.conf; // world config from Spigot
|
||||
|
||||
|
||||
serverWorld.getChunkSource().chunkMap.generator = custom;
|
||||
|
||||
|
||||
LOGGER.info("Successfully injected into world.");
|
||||
|
||||
|
||||
serverWorld.getChunkSource().chunkMap.generator.ensureStructuresGenerated(); // generate stronghold data now
|
||||
|
||||
|
||||
INJECT_LOCK.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -8,27 +8,27 @@ import com.dfsek.terra.api.world.info.WorldProperties;
|
||||
public class NMSWorldProperties implements WorldProperties {
|
||||
private final long seed;
|
||||
private final LevelHeightAccessor height;
|
||||
|
||||
|
||||
public NMSWorldProperties(long seed, LevelHeightAccessor height) {
|
||||
this.seed = seed;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object getHandle() {
|
||||
return height;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long getSeed() {
|
||||
return seed;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMaxHeight() {
|
||||
return height.getMaxBuildHeight();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMinHeight() {
|
||||
return height.getMinBuildHeight();
|
||||
|
||||
+7
-7
@@ -12,24 +12,24 @@ import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies;
|
||||
public class Reflection {
|
||||
public static final MappedRegistryProxy MAPPED_REGISTRY;
|
||||
public static final BiomeProxy BIOME;
|
||||
|
||||
|
||||
static {
|
||||
ReflectionRemapper reflectionRemapper = ReflectionRemapper.forReobfMappingsInPaperJar();
|
||||
ReflectionProxyFactory reflectionProxyFactory = ReflectionProxyFactory.create(reflectionRemapper,
|
||||
Reflection.class.getClassLoader());
|
||||
|
||||
Reflection.class.getClassLoader());
|
||||
|
||||
MAPPED_REGISTRY = reflectionProxyFactory.reflectionProxy(MappedRegistryProxy.class);
|
||||
BIOME = reflectionProxyFactory.reflectionProxy(BiomeProxy.class);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Proxies(MappedRegistry.class)
|
||||
public interface MappedRegistryProxy {
|
||||
@FieldSetter("frozen")
|
||||
void setFrozen(MappedRegistry<?> instance, boolean frozen);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Proxies(Biome.class)
|
||||
public interface BiomeProxy {
|
||||
@FieldGetter("biomeCategory")
|
||||
|
||||
+6
-6
@@ -14,16 +14,16 @@ public class Registries {
|
||||
CraftServer craftserver = (CraftServer) Bukkit.getServer();
|
||||
DedicatedServer dedicatedserver = craftserver.getServer();
|
||||
return dedicatedserver
|
||||
.registryAccess()
|
||||
.registryOrThrow( // getRegistry
|
||||
key
|
||||
);
|
||||
.registryAccess()
|
||||
.registryOrThrow( // getRegistry
|
||||
key
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public static Registry<Biome> biomeRegistry() {
|
||||
return getRegistry(Registry.BIOME_REGISTRY);
|
||||
}
|
||||
|
||||
|
||||
public static Registry<StructureSet> structureSet() {
|
||||
return getRegistry(Registry.STRUCTURE_SET_REGISTRY);
|
||||
}
|
||||
|
||||
+54
-54
@@ -27,88 +27,88 @@ import com.dfsek.terra.registry.master.ConfigRegistry;
|
||||
|
||||
public class AwfulBukkitHacks {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(AwfulBukkitHacks.class);
|
||||
|
||||
|
||||
private static final Map<ResourceLocation, List<ResourceLocation>> terraBiomeMap = new HashMap<>();
|
||||
|
||||
|
||||
public static void registerBiomes(ConfigRegistry configRegistry) {
|
||||
try {
|
||||
LOGGER.info("Hacking biome registry...");
|
||||
WritableRegistry<Biome> biomeRegistry = (WritableRegistry<Biome>) Registries.biomeRegistry();
|
||||
|
||||
|
||||
Reflection.MAPPED_REGISTRY.setFrozen((MappedRegistry<?>) biomeRegistry, false);
|
||||
|
||||
|
||||
configRegistry.forEach(pack -> pack.getRegistry(com.dfsek.terra.api.world.biome.Biome.class).forEach((key, biome) -> {
|
||||
try {
|
||||
BukkitPlatformBiome platformBiome = (BukkitPlatformBiome) biome.getPlatformBiome();
|
||||
NamespacedKey vanillaBukkitKey = platformBiome.getHandle().getKey();
|
||||
ResourceLocation vanillaMinecraftKey = new ResourceLocation(vanillaBukkitKey.getNamespace(), vanillaBukkitKey.getKey());
|
||||
Biome platform = NMSBiomeInjector.createBiome(
|
||||
biome,
|
||||
Objects.requireNonNull(biomeRegistry.get(vanillaMinecraftKey)) // get
|
||||
);
|
||||
|
||||
biome,
|
||||
Objects.requireNonNull(biomeRegistry.get(vanillaMinecraftKey)) // get
|
||||
);
|
||||
|
||||
ResourceKey<Biome> delegateKey = ResourceKey.create(Registry.BIOME_REGISTRY,
|
||||
new ResourceLocation("terra",
|
||||
NMSBiomeInjector.createBiomeID(pack, key)));
|
||||
|
||||
new ResourceLocation("terra",
|
||||
NMSBiomeInjector.createBiomeID(pack, key)));
|
||||
|
||||
BuiltinRegistries.register(BuiltinRegistries.BIOME, delegateKey, platform);
|
||||
biomeRegistry.register(delegateKey, platform, Lifecycle.stable());
|
||||
platformBiome.getContext().put(new NMSBiomeInfo(delegateKey));
|
||||
|
||||
|
||||
terraBiomeMap.computeIfAbsent(vanillaMinecraftKey, i -> new ArrayList<>()).add(delegateKey.location());
|
||||
|
||||
|
||||
LOGGER.debug("Registered biome: " + delegateKey);
|
||||
} catch(NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
Reflection.MAPPED_REGISTRY.setFrozen((MappedRegistry<?>) biomeRegistry, true); // freeze registry again :)
|
||||
|
||||
|
||||
LOGGER.info("Doing tag garbage....");
|
||||
Map<TagKey<Biome>, List<Holder<Biome>>> collect = biomeRegistry
|
||||
.getTags() // streamKeysAndEntries
|
||||
.collect(HashMap::new,
|
||||
(map, pair) ->
|
||||
map.put(pair.getFirst(), new ArrayList<>(pair.getSecond().stream().toList())),
|
||||
HashMap::putAll);
|
||||
|
||||
.getTags() // streamKeysAndEntries
|
||||
.collect(HashMap::new,
|
||||
(map, pair) ->
|
||||
map.put(pair.getFirst(), new ArrayList<>(pair.getSecond().stream().toList())),
|
||||
HashMap::putAll);
|
||||
|
||||
terraBiomeMap
|
||||
.forEach((vb, terraBiomes) ->
|
||||
NMSBiomeInjector.getEntry(biomeRegistry, vb)
|
||||
.ifPresentOrElse(
|
||||
vanilla -> terraBiomes
|
||||
.forEach(tb -> NMSBiomeInjector.getEntry(biomeRegistry, tb)
|
||||
.ifPresentOrElse(
|
||||
terra -> {
|
||||
LOGGER.debug(
|
||||
vanilla.unwrapKey()
|
||||
.orElseThrow()
|
||||
.location() +
|
||||
" (vanilla for " +
|
||||
terra.unwrapKey()
|
||||
.orElseThrow()
|
||||
.location() +
|
||||
": " +
|
||||
vanilla.tags()
|
||||
.toList());
|
||||
|
||||
vanilla.tags()
|
||||
.forEach(
|
||||
tag -> collect
|
||||
.computeIfAbsent(
|
||||
tag,
|
||||
t -> new ArrayList<>())
|
||||
.add(terra));
|
||||
},
|
||||
() -> LOGGER.error(
|
||||
"No such biome: {}",
|
||||
tb))),
|
||||
() -> LOGGER.error("No vanilla biome: {}", vb)));
|
||||
|
||||
.forEach((vb, terraBiomes) ->
|
||||
NMSBiomeInjector.getEntry(biomeRegistry, vb)
|
||||
.ifPresentOrElse(
|
||||
vanilla -> terraBiomes
|
||||
.forEach(tb -> NMSBiomeInjector.getEntry(biomeRegistry, tb)
|
||||
.ifPresentOrElse(
|
||||
terra -> {
|
||||
LOGGER.debug(
|
||||
vanilla.unwrapKey()
|
||||
.orElseThrow()
|
||||
.location() +
|
||||
" (vanilla for " +
|
||||
terra.unwrapKey()
|
||||
.orElseThrow()
|
||||
.location() +
|
||||
": " +
|
||||
vanilla.tags()
|
||||
.toList());
|
||||
|
||||
vanilla.tags()
|
||||
.forEach(
|
||||
tag -> collect
|
||||
.computeIfAbsent(
|
||||
tag,
|
||||
t -> new ArrayList<>())
|
||||
.add(terra));
|
||||
},
|
||||
() -> LOGGER.error(
|
||||
"No such biome: {}",
|
||||
tb))),
|
||||
() -> LOGGER.error("No vanilla biome: {}", vb)));
|
||||
|
||||
biomeRegistry.resetTags();
|
||||
biomeRegistry.bindTags(ImmutableMap.copyOf(collect));
|
||||
|
||||
|
||||
} catch(SecurityException | IllegalArgumentException exception) {
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
|
||||
+27
-27
@@ -15,63 +15,63 @@ import com.dfsek.terra.bukkit.config.VanillaBiomeProperties;
|
||||
|
||||
|
||||
public class NMSBiomeInjector {
|
||||
|
||||
|
||||
public static <T> Optional<Holder<T>> getEntry(Registry<T> registry, ResourceLocation identifier) {
|
||||
return registry.getOptional(identifier)
|
||||
.flatMap(registry::getResourceKey)
|
||||
.map(registry::getOrCreateHolderOrThrow);
|
||||
.flatMap(registry::getResourceKey)
|
||||
.map(registry::getOrCreateHolderOrThrow);
|
||||
}
|
||||
|
||||
|
||||
public static Biome createBiome(com.dfsek.terra.api.world.biome.Biome biome, Biome vanilla)
|
||||
throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
|
||||
Biome.BiomeBuilder builder = new Biome.BiomeBuilder();
|
||||
|
||||
|
||||
builder
|
||||
.precipitation(vanilla.getPrecipitation())
|
||||
.downfall(vanilla.getDownfall())
|
||||
.temperature(vanilla.getBaseTemperature())
|
||||
.mobSpawnSettings(vanilla.getMobSettings())
|
||||
.generationSettings(vanilla.getGenerationSettings());
|
||||
|
||||
|
||||
.precipitation(vanilla.getPrecipitation())
|
||||
.downfall(vanilla.getDownfall())
|
||||
.temperature(vanilla.getBaseTemperature())
|
||||
.mobSpawnSettings(vanilla.getMobSettings())
|
||||
.generationSettings(vanilla.getGenerationSettings());
|
||||
|
||||
|
||||
BiomeSpecialEffects.Builder effects = new BiomeSpecialEffects.Builder();
|
||||
|
||||
|
||||
effects.grassColorModifier(vanilla.getSpecialEffects().getGrassColorModifier());
|
||||
|
||||
|
||||
VanillaBiomeProperties vanillaBiomeProperties = biome.getContext().get(VanillaBiomeProperties.class);
|
||||
|
||||
|
||||
effects.fogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getFogColor(), vanilla.getFogColor()))
|
||||
|
||||
.waterColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterColor(), vanilla.getWaterColor()))
|
||||
|
||||
.waterFogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterFogColor(), vanilla.getWaterFogColor()))
|
||||
|
||||
.skyColor(Objects.requireNonNullElse(vanillaBiomeProperties.getSkyColor(), vanilla.getSkyColor()));
|
||||
|
||||
|
||||
.waterColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterColor(), vanilla.getWaterColor()))
|
||||
|
||||
.waterFogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterFogColor(), vanilla.getWaterFogColor()))
|
||||
|
||||
.skyColor(Objects.requireNonNullElse(vanillaBiomeProperties.getSkyColor(), vanilla.getSkyColor()));
|
||||
|
||||
if(vanillaBiomeProperties.getFoliageColor() == null) {
|
||||
vanilla.getSpecialEffects().getFoliageColorOverride().ifPresent(effects::foliageColorOverride);
|
||||
} else {
|
||||
effects.foliageColorOverride(vanillaBiomeProperties.getFoliageColor());
|
||||
}
|
||||
|
||||
|
||||
if(vanillaBiomeProperties.getGrassColor() == null) {
|
||||
vanilla.getSpecialEffects().getGrassColorOverride().ifPresent(effects::grassColorOverride);
|
||||
} else {
|
||||
// grass
|
||||
effects.grassColorOverride(vanillaBiomeProperties.getGrassColor());
|
||||
}
|
||||
|
||||
|
||||
vanilla.getAmbientLoop().ifPresent(effects::ambientLoopSound);
|
||||
vanilla.getAmbientAdditions().ifPresent(effects::ambientAdditionsSound);
|
||||
vanilla.getAmbientMood().ifPresent(effects::ambientMoodSound);
|
||||
vanilla.getBackgroundMusic().ifPresent(effects::backgroundMusic);
|
||||
vanilla.getAmbientParticle().ifPresent(effects::ambientParticle);
|
||||
|
||||
|
||||
builder.specialEffects(effects.build());
|
||||
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
||||
public static String createBiomeID(ConfigPack pack, com.dfsek.terra.api.registry.key.RegistryKey biomeID) {
|
||||
return pack.getID()
|
||||
.toLowerCase() + "/" + biomeID.getNamespace().toLowerCase(Locale.ROOT) + "/" + biomeID.getID().toLowerCase(Locale.ROOT);
|
||||
|
||||
+10
-10
@@ -16,27 +16,27 @@ public class NMSBiomeProvider extends BiomeSource {
|
||||
private final BiomeProvider delegate;
|
||||
private final long seed;
|
||||
private final Registry<Biome> biomeRegistry = Registries.biomeRegistry();
|
||||
|
||||
|
||||
public NMSBiomeProvider(BiomeProvider delegate, long seed) {
|
||||
super(delegate.stream()
|
||||
.map(biome -> Registries.biomeRegistry()
|
||||
.getHolderOrThrow(((BukkitPlatformBiome) biome.getPlatformBiome()).getContext()
|
||||
.get(NMSBiomeInfo.class)
|
||||
.biomeKey())));
|
||||
.map(biome -> Registries.biomeRegistry()
|
||||
.getHolderOrThrow(((BukkitPlatformBiome) biome.getPlatformBiome()).getContext()
|
||||
.get(NMSBiomeInfo.class)
|
||||
.biomeKey())));
|
||||
this.delegate = delegate;
|
||||
this.seed = seed;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected @NotNull Codec<? extends BiomeSource> codec() {
|
||||
return BiomeSource.CODEC;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull Holder<Biome> getNoiseBiome(int x, int y, int z, @NotNull Sampler sampler) {
|
||||
return biomeRegistry.getHolderOrThrow(((BukkitPlatformBiome) delegate.getBiome(x << 2, y << 2, z << 2, seed)
|
||||
.getPlatformBiome()).getContext()
|
||||
.get(NMSBiomeInfo.class)
|
||||
.biomeKey());
|
||||
.getPlatformBiome()).getContext()
|
||||
.get(NMSBiomeInfo.class)
|
||||
.biomeKey());
|
||||
}
|
||||
}
|
||||
|
||||
+46
-46
@@ -58,14 +58,14 @@ import com.dfsek.terra.bukkit.world.block.data.BukkitBlockState;
|
||||
public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(NMSChunkGeneratorDelegate.class);
|
||||
private final com.dfsek.terra.api.world.chunk.generation.ChunkGenerator delegate;
|
||||
|
||||
|
||||
private final ChunkGenerator vanilla;
|
||||
private final ConfigPack pack;
|
||||
|
||||
|
||||
private final long seed;
|
||||
private final Map<ConcentricRingsStructurePlacement, Lazy<List<ChunkPos>>> ringPositions = new Object2ObjectArrayMap<>();
|
||||
private volatile boolean rings = false;
|
||||
|
||||
|
||||
public NMSChunkGeneratorDelegate(ChunkGenerator vanilla, ConfigPack pack, NMSBiomeProvider biomeProvider, long seed) {
|
||||
super(Registries.structureSet(), Optional.empty(), biomeProvider);
|
||||
this.delegate = pack.getGeneratorProvider().newInstance(pack);
|
||||
@@ -73,57 +73,57 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
this.pack = pack;
|
||||
this.seed = seed;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected @NotNull Codec<? extends ChunkGenerator> codec() {
|
||||
return ChunkGenerator.CODEC;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void applyCarvers(@NotNull WorldGenRegion chunkRegion, long seed, @NotNull RandomState noiseConfig, @NotNull BiomeManager world,
|
||||
@NotNull StructureManager structureAccessor, @NotNull ChunkAccess chunk, @NotNull Carving carverStep) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void buildSurface(@NotNull WorldGenRegion region, @NotNull StructureManager structures, @NotNull RandomState noiseConfig,
|
||||
@NotNull ChunkAccess chunk) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void applyBiomeDecoration(@NotNull WorldGenLevel world, @NotNull ChunkAccess chunk,
|
||||
@NotNull StructureManager structureAccessor) {
|
||||
vanilla.applyBiomeDecoration(world, chunk, structureAccessor);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void spawnOriginalMobs(@NotNull WorldGenRegion region) {
|
||||
vanilla.spawnOriginalMobs(region);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getGenDepth() {
|
||||
return vanilla.getGenDepth();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull CompletableFuture<ChunkAccess> fillFromNoise(@NotNull Executor executor, @NotNull Blender blender,
|
||||
@NotNull RandomState noiseConfig,
|
||||
@NotNull StructureManager structureAccessor, @NotNull ChunkAccess chunk) {
|
||||
return vanilla.fillFromNoise(executor, blender, noiseConfig, structureAccessor, chunk)
|
||||
.thenApply(c -> {
|
||||
LevelAccessor level = Reflection.STRUCTURE_MANAGER.getLevel(structureAccessor);
|
||||
BiomeProvider biomeProvider = pack.getBiomeProvider();
|
||||
PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class);
|
||||
if(compatibilityOptions.isBeard()) {
|
||||
beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()),
|
||||
biomeProvider, compatibilityOptions);
|
||||
}
|
||||
return c;
|
||||
});
|
||||
.thenApply(c -> {
|
||||
LevelAccessor level = Reflection.STRUCTURE_MANAGER.getLevel(structureAccessor);
|
||||
BiomeProvider biomeProvider = pack.getBiomeProvider();
|
||||
PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class);
|
||||
if(compatibilityOptions.isBeard()) {
|
||||
beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()),
|
||||
biomeProvider, compatibilityOptions);
|
||||
}
|
||||
return c;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void beard(StructureManager structureAccessor, ChunkAccess chunk, WorldProperties world, BiomeProvider biomeProvider,
|
||||
PreLoadCompatibilityOptions compatibilityOptions) {
|
||||
Beardifier structureWeightSampler = Beardifier.forStructuresInChunk(structureAccessor, chunk.getPos());
|
||||
@@ -138,8 +138,8 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
double noise = structureWeightSampler.compute(new SinglePointContext(x + xi, y, z + zi));
|
||||
if(noise > threshold) {
|
||||
chunk.setBlockState(new BlockPos(x, y, z), ((CraftBlockData) ((BukkitBlockState) delegate
|
||||
.getPalette(x + xi, y, z + zi, world, biomeProvider)
|
||||
.get(depth, x + xi, y, z + zi, world.getSeed())).getHandle()).getState(), false);
|
||||
.getPalette(x + xi, y, z + zi, world, biomeProvider)
|
||||
.get(depth, x + xi, y, z + zi, world.getSeed())).getHandle()).getState(), false);
|
||||
depth++;
|
||||
} else if(noise < airThreshold) {
|
||||
chunk.setBlockState(new BlockPos(x, y, z), Blocks.AIR.defaultBlockState(), false);
|
||||
@@ -150,29 +150,29 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getSeaLevel() {
|
||||
return vanilla.getSeaLevel();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMinY() {
|
||||
return vanilla.getMinY();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getBaseHeight(int x, int z, @NotNull Types heightmap, @NotNull LevelHeightAccessor world, @NotNull RandomState noiseConfig) {
|
||||
WorldProperties properties = new NMSWorldProperties(seed, world);
|
||||
int y = properties.getMaxHeight();
|
||||
BiomeProvider biomeProvider = pack.getBiomeProvider();
|
||||
while(y >= getMinY() && !heightmap.isOpaque().test(
|
||||
((CraftBlockData) delegate.getBlock(properties, x, y - 1, z, biomeProvider).getHandle()).getState())) {
|
||||
((CraftBlockData) delegate.getBlock(properties, x, y - 1, z, biomeProvider).getHandle()).getState())) {
|
||||
y--;
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull NoiseColumn getBaseColumn(int x, int z, @NotNull LevelHeightAccessor world, @NotNull RandomState noiseConfig) {
|
||||
/*
|
||||
@@ -188,12 +188,12 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
*/
|
||||
return vanilla.getBaseColumn(x, z, world, noiseConfig);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addDebugScreenInfo(@NotNull List<String> text, @NotNull RandomState noiseConfig, @NotNull BlockPos pos) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void ensureStructuresGenerated(@NotNull RandomState noiseConfig) {
|
||||
if(!this.rings) {
|
||||
@@ -201,16 +201,16 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
this.populateStrongholdData(noiseConfig);
|
||||
this.rings = true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<ChunkPos> getRingPositionsFor(@NotNull ConcentricRingsStructurePlacement structurePlacement,
|
||||
@NotNull RandomState noiseConfig) {
|
||||
ensureStructuresGenerated(noiseConfig);
|
||||
return ringPositions.get(structurePlacement).value();
|
||||
}
|
||||
|
||||
|
||||
private void populateStrongholdData(RandomState noiseConfig) {
|
||||
LOGGER.info("Generating safe stronghold data. This may take up to a minute.");
|
||||
Set<Holder<Biome>> set = this.biomeSource.possibleBiomes();
|
||||
@@ -223,29 +223,29 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
match = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(match) {
|
||||
if(holder.placement() instanceof ConcentricRingsStructurePlacement concentricringsstructureplacement) {
|
||||
this.ringPositions.put(concentricringsstructureplacement, Lazy.lazy(
|
||||
() -> this.generateRingPositions(holder, noiseConfig, concentricringsstructureplacement)));
|
||||
() -> this.generateRingPositions(holder, noiseConfig, concentricringsstructureplacement)));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private List<ChunkPos> generateRingPositions(StructureSet holder, RandomState randomstate,
|
||||
ConcentricRingsStructurePlacement concentricringsstructureplacement) { // Spigot
|
||||
if(concentricringsstructureplacement.count() == 0) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
|
||||
List<ChunkPos> list = new ArrayList<>();
|
||||
int i = concentricringsstructureplacement.distance();
|
||||
int j = concentricringsstructureplacement.count();
|
||||
int k = concentricringsstructureplacement.spread();
|
||||
HolderSet<Biome> holderset = concentricringsstructureplacement.preferredBiomes();
|
||||
RandomSource randomsource = RandomSource.create();
|
||||
|
||||
|
||||
if(this.conf.strongholdSeed != null && this.structureSets.getResourceKey(holder).orElse(null) ==
|
||||
net.minecraft.world.level.levelgen.structure.BuiltinStructureSets.STRONGHOLDS) {
|
||||
randomsource.setSeed(this.conf.strongholdSeed);
|
||||
@@ -255,25 +255,25 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
double d0 = randomsource.nextDouble() * 3.141592653589793D * 2.0D;
|
||||
int l = 0;
|
||||
int i1 = 0;
|
||||
|
||||
|
||||
for(int j1 = 0; j1 < j; ++j1) {
|
||||
double d1 = (double) (4 * i + i * i1 * 6) + (randomsource.nextDouble() - 0.5D) * (double) i * 2.5D;
|
||||
int k1 = (int) Math.round(MathUtil.cos(d0) * d1);
|
||||
int l1 = (int) Math.round(MathUtil.sin(d0) * d1);
|
||||
int i2 = SectionPos.sectionToBlockCoord(k1, 8);
|
||||
int j2 = SectionPos.sectionToBlockCoord(l1, 8);
|
||||
|
||||
|
||||
Objects.requireNonNull(holderset);
|
||||
Pair<BlockPos, Holder<Biome>> pair = this.biomeSource.findBiomeHorizontal(i2, 0, j2, 112, holderset::contains, randomsource,
|
||||
randomstate.sampler());
|
||||
|
||||
randomstate.sampler());
|
||||
|
||||
if(pair != null) {
|
||||
BlockPos blockposition = pair.getFirst();
|
||||
|
||||
|
||||
k1 = SectionPos.blockToSectionCoord(blockposition.getX());
|
||||
l1 = SectionPos.blockToSectionCoord(blockposition.getZ());
|
||||
}
|
||||
|
||||
|
||||
list.add(new ChunkPos(k1, l1));
|
||||
d0 += 6.283185307179586D / (double) k;
|
||||
++l;
|
||||
@@ -285,7 +285,7 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
d0 += randomsource.nextDouble() * 3.141592653589793D * 2.0D;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
+7
-7
@@ -22,7 +22,7 @@ public class NMSInjectListener implements Listener {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(NMSInjectListener.class);
|
||||
private static final Set<World> INJECTED = new HashSet<>();
|
||||
private static final ReentrantLock INJECT_LOCK = new ReentrantLock();
|
||||
|
||||
|
||||
@EventHandler
|
||||
public void onWorldInit(WorldInitEvent event) {
|
||||
if(!INJECTED.contains(event.getWorld()) &&
|
||||
@@ -32,19 +32,19 @@ public class NMSInjectListener implements Listener {
|
||||
LOGGER.info("Preparing to take over the world: {}", event.getWorld().getName());
|
||||
CraftWorld craftWorld = (CraftWorld) event.getWorld();
|
||||
ServerLevel serverWorld = craftWorld.getHandle();
|
||||
|
||||
|
||||
ConfigPack pack = bukkitChunkGeneratorWrapper.getPack();
|
||||
|
||||
|
||||
ChunkGenerator vanilla = serverWorld.getChunkSource().getGenerator();
|
||||
NMSBiomeProvider provider = new NMSBiomeProvider(pack.getBiomeProvider(), craftWorld.getSeed());
|
||||
NMSChunkGeneratorDelegate custom = new NMSChunkGeneratorDelegate(vanilla, pack, provider, craftWorld.getSeed());
|
||||
|
||||
|
||||
custom.conf = vanilla.conf; // world config from Spigot
|
||||
|
||||
|
||||
serverWorld.getChunkSource().chunkMap.generator = custom;
|
||||
|
||||
|
||||
LOGGER.info("Successfully injected into world.");
|
||||
|
||||
|
||||
INJECT_LOCK.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -8,27 +8,27 @@ import com.dfsek.terra.api.world.info.WorldProperties;
|
||||
public class NMSWorldProperties implements WorldProperties {
|
||||
private final long seed;
|
||||
private final LevelHeightAccessor height;
|
||||
|
||||
|
||||
public NMSWorldProperties(long seed, LevelHeightAccessor height) {
|
||||
this.seed = seed;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object getHandle() {
|
||||
return height;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long getSeed() {
|
||||
return seed;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMaxHeight() {
|
||||
return height.getMaxBuildHeight();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMinHeight() {
|
||||
return height.getMinBuildHeight();
|
||||
|
||||
+7
-7
@@ -13,24 +13,24 @@ import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies;
|
||||
public class Reflection {
|
||||
public static final MappedRegistryProxy MAPPED_REGISTRY;
|
||||
public static final StructureManagerProxy STRUCTURE_MANAGER;
|
||||
|
||||
|
||||
static {
|
||||
ReflectionRemapper reflectionRemapper = ReflectionRemapper.forReobfMappingsInPaperJar();
|
||||
ReflectionProxyFactory reflectionProxyFactory = ReflectionProxyFactory.create(reflectionRemapper,
|
||||
Reflection.class.getClassLoader());
|
||||
|
||||
Reflection.class.getClassLoader());
|
||||
|
||||
MAPPED_REGISTRY = reflectionProxyFactory.reflectionProxy(MappedRegistryProxy.class);
|
||||
STRUCTURE_MANAGER = reflectionProxyFactory.reflectionProxy(StructureManagerProxy.class);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Proxies(MappedRegistry.class)
|
||||
public interface MappedRegistryProxy {
|
||||
@FieldSetter("frozen")
|
||||
void setFrozen(MappedRegistry<?> instance, boolean frozen);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Proxies(StructureManager.class)
|
||||
public interface StructureManagerProxy {
|
||||
@FieldGetter("level")
|
||||
|
||||
+6
-6
@@ -14,16 +14,16 @@ public class Registries {
|
||||
CraftServer craftserver = (CraftServer) Bukkit.getServer();
|
||||
DedicatedServer dedicatedserver = craftserver.getServer();
|
||||
return dedicatedserver
|
||||
.registryAccess()
|
||||
.registryOrThrow( // getRegistry
|
||||
key
|
||||
);
|
||||
.registryAccess()
|
||||
.registryOrThrow( // getRegistry
|
||||
key
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public static Registry<Biome> biomeRegistry() {
|
||||
return getRegistry(Registry.BIOME_REGISTRY);
|
||||
}
|
||||
|
||||
|
||||
public static Registry<StructureSet> structureSet() {
|
||||
return getRegistry(Registry.STRUCTURE_SET_REGISTRY);
|
||||
}
|
||||
|
||||
+38
-38
@@ -27,72 +27,72 @@ import com.dfsek.terra.registry.master.ConfigRegistry;
|
||||
|
||||
public class AwfulBukkitHacks {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(AwfulBukkitHacks.class);
|
||||
|
||||
|
||||
private static final Map<ResourceLocation, List<ResourceLocation>> terraBiomeMap = new HashMap<>();
|
||||
|
||||
|
||||
public static void registerBiomes(ConfigRegistry configRegistry) {
|
||||
try {
|
||||
LOGGER.info("Hacking biome registry...");
|
||||
WritableRegistry<Biome> biomeRegistry = (WritableRegistry<Biome>) RegistryFetcher.biomeRegistry();
|
||||
|
||||
|
||||
Reflection.MAPPED_REGISTRY.setFrozen((MappedRegistry<?>) biomeRegistry, false);
|
||||
|
||||
|
||||
configRegistry.forEach(pack -> pack.getRegistry(com.dfsek.terra.api.world.biome.Biome.class).forEach((key, biome) -> {
|
||||
try {
|
||||
BukkitPlatformBiome platformBiome = (BukkitPlatformBiome) biome.getPlatformBiome();
|
||||
NamespacedKey vanillaBukkitKey = platformBiome.getHandle().getKey();
|
||||
ResourceLocation vanillaMinecraftKey = new ResourceLocation(vanillaBukkitKey.getNamespace(), vanillaBukkitKey.getKey());
|
||||
Biome platform = NMSBiomeInjector.createBiome(biome, Objects.requireNonNull(biomeRegistry.get(vanillaMinecraftKey)));
|
||||
|
||||
|
||||
ResourceKey<Biome> delegateKey = ResourceKey.create(
|
||||
Registries.BIOME,
|
||||
new ResourceLocation("terra", NMSBiomeInjector.createBiomeID(pack, key))
|
||||
);
|
||||
|
||||
Registries.BIOME,
|
||||
new ResourceLocation("terra", NMSBiomeInjector.createBiomeID(pack, key))
|
||||
);
|
||||
|
||||
Reference<Biome> holder = biomeRegistry.register(delegateKey, platform, Lifecycle.stable());
|
||||
Reflection.REFERENCE.invokeBindValue(holder, platform); // IMPORTANT: bind holder.
|
||||
|
||||
|
||||
platformBiome.getContext().put(new NMSBiomeInfo(delegateKey));
|
||||
|
||||
|
||||
terraBiomeMap.computeIfAbsent(vanillaMinecraftKey, i -> new ArrayList<>()).add(delegateKey.location());
|
||||
|
||||
|
||||
LOGGER.debug("Registered biome: " + delegateKey);
|
||||
} catch(NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
Reflection.MAPPED_REGISTRY.setFrozen((MappedRegistry<?>) biomeRegistry, true); // freeze registry again :)
|
||||
|
||||
|
||||
LOGGER.info("Doing tag garbage....");
|
||||
Map<TagKey<Biome>, List<Holder<Biome>>> collect = biomeRegistry
|
||||
.getTags() // streamKeysAndEntries
|
||||
.collect(HashMap::new,
|
||||
(map, pair) ->
|
||||
map.put(pair.getFirst(), new ArrayList<>(pair.getSecond().stream().toList())),
|
||||
HashMap::putAll);
|
||||
|
||||
.getTags() // streamKeysAndEntries
|
||||
.collect(HashMap::new,
|
||||
(map, pair) ->
|
||||
map.put(pair.getFirst(), new ArrayList<>(pair.getSecond().stream().toList())),
|
||||
HashMap::putAll);
|
||||
|
||||
terraBiomeMap
|
||||
.forEach((vb, terraBiomes) ->
|
||||
NMSBiomeInjector.getEntry(biomeRegistry, vb).ifPresentOrElse(
|
||||
vanilla -> terraBiomes.forEach(
|
||||
tb -> NMSBiomeInjector.getEntry(biomeRegistry, tb).ifPresentOrElse(
|
||||
terra -> {
|
||||
LOGGER.debug("{} (vanilla for {}): {}",
|
||||
vanilla.unwrapKey().orElseThrow().location(),
|
||||
terra.unwrapKey().orElseThrow().location(),
|
||||
vanilla.tags().toList());
|
||||
vanilla.tags()
|
||||
.forEach(tag -> collect
|
||||
.computeIfAbsent(tag, t -> new ArrayList<>())
|
||||
.add(terra));
|
||||
},
|
||||
() -> LOGGER.error("No such biome: {}", tb))),
|
||||
() -> LOGGER.error("No vanilla biome: {}", vb)));
|
||||
|
||||
.forEach((vb, terraBiomes) ->
|
||||
NMSBiomeInjector.getEntry(biomeRegistry, vb).ifPresentOrElse(
|
||||
vanilla -> terraBiomes.forEach(
|
||||
tb -> NMSBiomeInjector.getEntry(biomeRegistry, tb).ifPresentOrElse(
|
||||
terra -> {
|
||||
LOGGER.debug("{} (vanilla for {}): {}",
|
||||
vanilla.unwrapKey().orElseThrow().location(),
|
||||
terra.unwrapKey().orElseThrow().location(),
|
||||
vanilla.tags().toList());
|
||||
vanilla.tags()
|
||||
.forEach(tag -> collect
|
||||
.computeIfAbsent(tag, t -> new ArrayList<>())
|
||||
.add(terra));
|
||||
},
|
||||
() -> LOGGER.error("No such biome: {}", tb))),
|
||||
() -> LOGGER.error("No vanilla biome: {}", vb)));
|
||||
|
||||
biomeRegistry.resetTags();
|
||||
biomeRegistry.bindTags(ImmutableMap.copyOf(collect));
|
||||
|
||||
|
||||
} catch(SecurityException | IllegalArgumentException exception) {
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
|
||||
+27
-27
@@ -15,63 +15,63 @@ import com.dfsek.terra.bukkit.config.VanillaBiomeProperties;
|
||||
|
||||
|
||||
public class NMSBiomeInjector {
|
||||
|
||||
|
||||
public static <T> Optional<Holder<T>> getEntry(Registry<T> registry, ResourceLocation identifier) {
|
||||
return registry.getOptional(identifier)
|
||||
.flatMap(registry::getResourceKey)
|
||||
.flatMap(registry::getHolder);
|
||||
.flatMap(registry::getResourceKey)
|
||||
.flatMap(registry::getHolder);
|
||||
}
|
||||
|
||||
|
||||
public static Biome createBiome(com.dfsek.terra.api.world.biome.Biome biome, Biome vanilla)
|
||||
throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
|
||||
Biome.BiomeBuilder builder = new Biome.BiomeBuilder();
|
||||
|
||||
|
||||
builder
|
||||
.precipitation(vanilla.getPrecipitation())
|
||||
.downfall(vanilla.getDownfall())
|
||||
.temperature(vanilla.getBaseTemperature())
|
||||
.mobSpawnSettings(vanilla.getMobSettings())
|
||||
.generationSettings(vanilla.getGenerationSettings());
|
||||
|
||||
|
||||
.precipitation(vanilla.getPrecipitation())
|
||||
.downfall(vanilla.getDownfall())
|
||||
.temperature(vanilla.getBaseTemperature())
|
||||
.mobSpawnSettings(vanilla.getMobSettings())
|
||||
.generationSettings(vanilla.getGenerationSettings());
|
||||
|
||||
|
||||
BiomeSpecialEffects.Builder effects = new BiomeSpecialEffects.Builder();
|
||||
|
||||
|
||||
effects.grassColorModifier(vanilla.getSpecialEffects().getGrassColorModifier());
|
||||
|
||||
|
||||
VanillaBiomeProperties vanillaBiomeProperties = biome.getContext().get(VanillaBiomeProperties.class);
|
||||
|
||||
|
||||
effects.fogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getFogColor(), vanilla.getFogColor()))
|
||||
|
||||
.waterColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterColor(), vanilla.getWaterColor()))
|
||||
|
||||
.waterFogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterFogColor(), vanilla.getWaterFogColor()))
|
||||
|
||||
.skyColor(Objects.requireNonNullElse(vanillaBiomeProperties.getSkyColor(), vanilla.getSkyColor()));
|
||||
|
||||
|
||||
.waterColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterColor(), vanilla.getWaterColor()))
|
||||
|
||||
.waterFogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterFogColor(), vanilla.getWaterFogColor()))
|
||||
|
||||
.skyColor(Objects.requireNonNullElse(vanillaBiomeProperties.getSkyColor(), vanilla.getSkyColor()));
|
||||
|
||||
if(vanillaBiomeProperties.getFoliageColor() == null) {
|
||||
vanilla.getSpecialEffects().getFoliageColorOverride().ifPresent(effects::foliageColorOverride);
|
||||
} else {
|
||||
effects.foliageColorOverride(vanillaBiomeProperties.getFoliageColor());
|
||||
}
|
||||
|
||||
|
||||
if(vanillaBiomeProperties.getGrassColor() == null) {
|
||||
vanilla.getSpecialEffects().getGrassColorOverride().ifPresent(effects::grassColorOverride);
|
||||
} else {
|
||||
// grass
|
||||
effects.grassColorOverride(vanillaBiomeProperties.getGrassColor());
|
||||
}
|
||||
|
||||
|
||||
vanilla.getAmbientLoop().ifPresent(effects::ambientLoopSound);
|
||||
vanilla.getAmbientAdditions().ifPresent(effects::ambientAdditionsSound);
|
||||
vanilla.getAmbientMood().ifPresent(effects::ambientMoodSound);
|
||||
vanilla.getBackgroundMusic().ifPresent(effects::backgroundMusic);
|
||||
vanilla.getAmbientParticle().ifPresent(effects::ambientParticle);
|
||||
|
||||
|
||||
builder.specialEffects(effects.build());
|
||||
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
||||
public static String createBiomeID(ConfigPack pack, com.dfsek.terra.api.registry.key.RegistryKey biomeID) {
|
||||
return pack.getID()
|
||||
.toLowerCase() + "/" + biomeID.getNamespace().toLowerCase(Locale.ROOT) + "/" + biomeID.getID().toLowerCase(Locale.ROOT);
|
||||
|
||||
+10
-10
@@ -16,27 +16,27 @@ public class NMSBiomeProvider extends BiomeSource {
|
||||
private final BiomeProvider delegate;
|
||||
private final long seed;
|
||||
private final Registry<Biome> biomeRegistry = RegistryFetcher.biomeRegistry();
|
||||
|
||||
|
||||
public NMSBiomeProvider(BiomeProvider delegate, long seed) {
|
||||
super(delegate.stream()
|
||||
.map(biome -> RegistryFetcher.biomeRegistry()
|
||||
.getHolderOrThrow(((BukkitPlatformBiome) biome.getPlatformBiome()).getContext()
|
||||
.get(NMSBiomeInfo.class)
|
||||
.biomeKey())));
|
||||
.map(biome -> RegistryFetcher.biomeRegistry()
|
||||
.getHolderOrThrow(((BukkitPlatformBiome) biome.getPlatformBiome()).getContext()
|
||||
.get(NMSBiomeInfo.class)
|
||||
.biomeKey())));
|
||||
this.delegate = delegate;
|
||||
this.seed = seed;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected @NotNull Codec<? extends BiomeSource> codec() {
|
||||
return BiomeSource.CODEC;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull Holder<Biome> getNoiseBiome(int x, int y, int z, @NotNull Sampler sampler) {
|
||||
return biomeRegistry.getHolderOrThrow(((BukkitPlatformBiome) delegate.getBiome(x << 2, y << 2, z << 2, seed)
|
||||
.getPlatformBiome()).getContext()
|
||||
.get(NMSBiomeInfo.class)
|
||||
.biomeKey());
|
||||
.getPlatformBiome()).getContext()
|
||||
.get(NMSBiomeInfo.class)
|
||||
.biomeKey());
|
||||
}
|
||||
}
|
||||
|
||||
+30
-30
@@ -38,12 +38,12 @@ import com.dfsek.terra.bukkit.world.block.data.BukkitBlockState;
|
||||
public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(NMSChunkGeneratorDelegate.class);
|
||||
private final com.dfsek.terra.api.world.chunk.generation.ChunkGenerator delegate;
|
||||
|
||||
|
||||
private final ChunkGenerator vanilla;
|
||||
private final ConfigPack pack;
|
||||
|
||||
|
||||
private final long seed;
|
||||
|
||||
|
||||
public NMSChunkGeneratorDelegate(ChunkGenerator vanilla, ConfigPack pack, NMSBiomeProvider biomeProvider, long seed) {
|
||||
super(biomeProvider);
|
||||
this.delegate = pack.getGeneratorProvider().newInstance(pack);
|
||||
@@ -51,57 +51,57 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
this.pack = pack;
|
||||
this.seed = seed;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected @NotNull Codec<? extends ChunkGenerator> codec() {
|
||||
return ChunkGenerator.CODEC;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void applyCarvers(@NotNull WorldGenRegion chunkRegion, long seed, @NotNull RandomState noiseConfig, @NotNull BiomeManager world,
|
||||
@NotNull StructureManager structureAccessor, @NotNull ChunkAccess chunk, @NotNull Carving carverStep) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void buildSurface(@NotNull WorldGenRegion region, @NotNull StructureManager structures, @NotNull RandomState noiseConfig,
|
||||
@NotNull ChunkAccess chunk) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void applyBiomeDecoration(@NotNull WorldGenLevel world, @NotNull ChunkAccess chunk,
|
||||
@NotNull StructureManager structureAccessor) {
|
||||
vanilla.applyBiomeDecoration(world, chunk, structureAccessor);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void spawnOriginalMobs(@NotNull WorldGenRegion region) {
|
||||
vanilla.spawnOriginalMobs(region);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getGenDepth() {
|
||||
return vanilla.getGenDepth();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull CompletableFuture<ChunkAccess> fillFromNoise(@NotNull Executor executor, @NotNull Blender blender,
|
||||
@NotNull RandomState noiseConfig,
|
||||
@NotNull StructureManager structureAccessor, @NotNull ChunkAccess chunk) {
|
||||
return vanilla.fillFromNoise(executor, blender, noiseConfig, structureAccessor, chunk)
|
||||
.thenApply(c -> {
|
||||
LevelAccessor level = Reflection.STRUCTURE_MANAGER.getLevel(structureAccessor);
|
||||
BiomeProvider biomeProvider = pack.getBiomeProvider();
|
||||
PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class);
|
||||
if(compatibilityOptions.isBeard()) {
|
||||
beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()),
|
||||
biomeProvider, compatibilityOptions);
|
||||
}
|
||||
return c;
|
||||
});
|
||||
.thenApply(c -> {
|
||||
LevelAccessor level = Reflection.STRUCTURE_MANAGER.getLevel(structureAccessor);
|
||||
BiomeProvider biomeProvider = pack.getBiomeProvider();
|
||||
PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class);
|
||||
if(compatibilityOptions.isBeard()) {
|
||||
beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()),
|
||||
biomeProvider, compatibilityOptions);
|
||||
}
|
||||
return c;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void beard(StructureManager structureAccessor, ChunkAccess chunk, WorldProperties world, BiomeProvider biomeProvider,
|
||||
PreLoadCompatibilityOptions compatibilityOptions) {
|
||||
Beardifier structureWeightSampler = Beardifier.forStructuresInChunk(structureAccessor, chunk.getPos());
|
||||
@@ -116,8 +116,8 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
double noise = structureWeightSampler.compute(new SinglePointContext(x + xi, y, z + zi));
|
||||
if(noise > threshold) {
|
||||
chunk.setBlockState(new BlockPos(x, y, z), ((CraftBlockData) ((BukkitBlockState) delegate
|
||||
.getPalette(x + xi, y, z + zi, world, biomeProvider)
|
||||
.get(depth, x + xi, y, z + zi, world.getSeed())).getHandle()).getState(), false);
|
||||
.getPalette(x + xi, y, z + zi, world, biomeProvider)
|
||||
.get(depth, x + xi, y, z + zi, world.getSeed())).getHandle()).getState(), false);
|
||||
depth++;
|
||||
} else if(noise < airThreshold) {
|
||||
chunk.setBlockState(new BlockPos(x, y, z), Blocks.AIR.defaultBlockState(), false);
|
||||
@@ -128,29 +128,29 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getSeaLevel() {
|
||||
return vanilla.getSeaLevel();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMinY() {
|
||||
return vanilla.getMinY();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getBaseHeight(int x, int z, @NotNull Types heightmap, @NotNull LevelHeightAccessor world, @NotNull RandomState noiseConfig) {
|
||||
WorldProperties properties = new NMSWorldProperties(seed, world);
|
||||
int y = properties.getMaxHeight();
|
||||
BiomeProvider biomeProvider = pack.getBiomeProvider();
|
||||
while(y >= getMinY() && !heightmap.isOpaque().test(
|
||||
((CraftBlockData) delegate.getBlock(properties, x, y - 1, z, biomeProvider).getHandle()).getState())) {
|
||||
((CraftBlockData) delegate.getBlock(properties, x, y - 1, z, biomeProvider).getHandle()).getState())) {
|
||||
y--;
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull NoiseColumn getBaseColumn(int x, int z, @NotNull LevelHeightAccessor world, @NotNull RandomState noiseConfig) {
|
||||
/*
|
||||
@@ -166,9 +166,9 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
*/
|
||||
return vanilla.getBaseColumn(x, z, world, noiseConfig);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addDebugScreenInfo(@NotNull List<String> text, @NotNull RandomState noiseConfig, @NotNull BlockPos pos) {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+6
-6
@@ -22,7 +22,7 @@ public class NMSInjectListener implements Listener {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(NMSInjectListener.class);
|
||||
private static final Set<World> INJECTED = new HashSet<>();
|
||||
private static final ReentrantLock INJECT_LOCK = new ReentrantLock();
|
||||
|
||||
|
||||
@EventHandler
|
||||
public void onWorldInit(WorldInitEvent event) {
|
||||
if(!INJECTED.contains(event.getWorld()) &&
|
||||
@@ -32,16 +32,16 @@ public class NMSInjectListener implements Listener {
|
||||
LOGGER.info("Preparing to take over the world: {}", event.getWorld().getName());
|
||||
CraftWorld craftWorld = (CraftWorld) event.getWorld();
|
||||
ServerLevel serverWorld = craftWorld.getHandle();
|
||||
|
||||
|
||||
ConfigPack pack = bukkitChunkGeneratorWrapper.getPack();
|
||||
|
||||
|
||||
ChunkGenerator vanilla = serverWorld.getChunkSource().getGenerator();
|
||||
NMSBiomeProvider provider = new NMSBiomeProvider(pack.getBiomeProvider(), craftWorld.getSeed());
|
||||
|
||||
|
||||
serverWorld.getChunkSource().chunkMap.generator = new NMSChunkGeneratorDelegate(vanilla, pack, provider, craftWorld.getSeed());
|
||||
|
||||
|
||||
LOGGER.info("Successfully injected into world.");
|
||||
|
||||
|
||||
INJECT_LOCK.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -8,27 +8,27 @@ import com.dfsek.terra.api.world.info.WorldProperties;
|
||||
public class NMSWorldProperties implements WorldProperties {
|
||||
private final long seed;
|
||||
private final LevelHeightAccessor height;
|
||||
|
||||
|
||||
public NMSWorldProperties(long seed, LevelHeightAccessor height) {
|
||||
this.seed = seed;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object getHandle() {
|
||||
return height;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long getSeed() {
|
||||
return seed;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMaxHeight() {
|
||||
return height.getMaxBuildHeight();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMinHeight() {
|
||||
return height.getMinBuildHeight();
|
||||
|
||||
+10
-10
@@ -16,34 +16,34 @@ import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies;
|
||||
public class Reflection {
|
||||
public static final MappedRegistryProxy MAPPED_REGISTRY;
|
||||
public static final StructureManagerProxy STRUCTURE_MANAGER;
|
||||
|
||||
|
||||
public static final ReferenceProxy REFERENCE;
|
||||
|
||||
|
||||
static {
|
||||
ReflectionRemapper reflectionRemapper = ReflectionRemapper.forReobfMappingsInPaperJar();
|
||||
ReflectionProxyFactory reflectionProxyFactory = ReflectionProxyFactory.create(reflectionRemapper,
|
||||
Reflection.class.getClassLoader());
|
||||
|
||||
Reflection.class.getClassLoader());
|
||||
|
||||
MAPPED_REGISTRY = reflectionProxyFactory.reflectionProxy(MappedRegistryProxy.class);
|
||||
STRUCTURE_MANAGER = reflectionProxyFactory.reflectionProxy(StructureManagerProxy.class);
|
||||
REFERENCE = reflectionProxyFactory.reflectionProxy(ReferenceProxy.class);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Proxies(MappedRegistry.class)
|
||||
public interface MappedRegistryProxy {
|
||||
@FieldSetter("frozen")
|
||||
void setFrozen(MappedRegistry<?> instance, boolean frozen);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Proxies(StructureManager.class)
|
||||
public interface StructureManagerProxy {
|
||||
@FieldGetter("level")
|
||||
LevelAccessor getLevel(StructureManager instance);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Proxies(Holder.Reference.class)
|
||||
public interface ReferenceProxy {
|
||||
@MethodName("bindValue")
|
||||
|
||||
+3
-3
@@ -14,10 +14,10 @@ public class RegistryFetcher {
|
||||
CraftServer craftserver = (CraftServer) Bukkit.getServer();
|
||||
DedicatedServer dedicatedserver = craftserver.getServer();
|
||||
return dedicatedserver
|
||||
.registryAccess()
|
||||
.registryOrThrow(key);
|
||||
.registryAccess()
|
||||
.registryOrThrow(key);
|
||||
}
|
||||
|
||||
|
||||
public static Registry<Biome> biomeRegistry() {
|
||||
return getRegistry(Registries.BIOME);
|
||||
}
|
||||
|
||||
+38
-38
@@ -27,72 +27,72 @@ import com.dfsek.terra.registry.master.ConfigRegistry;
|
||||
|
||||
public class AwfulBukkitHacks {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(AwfulBukkitHacks.class);
|
||||
|
||||
|
||||
private static final Map<ResourceLocation, List<ResourceLocation>> terraBiomeMap = new HashMap<>();
|
||||
|
||||
|
||||
public static void registerBiomes(ConfigRegistry configRegistry) {
|
||||
try {
|
||||
LOGGER.info("Hacking biome registry...");
|
||||
WritableRegistry<Biome> biomeRegistry = (WritableRegistry<Biome>) RegistryFetcher.biomeRegistry();
|
||||
|
||||
|
||||
Reflection.MAPPED_REGISTRY.setFrozen((MappedRegistry<?>) biomeRegistry, false);
|
||||
|
||||
|
||||
configRegistry.forEach(pack -> pack.getRegistry(com.dfsek.terra.api.world.biome.Biome.class).forEach((key, biome) -> {
|
||||
try {
|
||||
BukkitPlatformBiome platformBiome = (BukkitPlatformBiome) biome.getPlatformBiome();
|
||||
NamespacedKey vanillaBukkitKey = platformBiome.getHandle().getKey();
|
||||
ResourceLocation vanillaMinecraftKey = new ResourceLocation(vanillaBukkitKey.getNamespace(), vanillaBukkitKey.getKey());
|
||||
Biome platform = NMSBiomeInjector.createBiome(biome, Objects.requireNonNull(biomeRegistry.get(vanillaMinecraftKey)));
|
||||
|
||||
|
||||
ResourceKey<Biome> delegateKey = ResourceKey.create(
|
||||
Registries.BIOME,
|
||||
new ResourceLocation("terra", NMSBiomeInjector.createBiomeID(pack, key))
|
||||
);
|
||||
|
||||
Registries.BIOME,
|
||||
new ResourceLocation("terra", NMSBiomeInjector.createBiomeID(pack, key))
|
||||
);
|
||||
|
||||
Reference<Biome> holder = biomeRegistry.register(delegateKey, platform, Lifecycle.stable());
|
||||
Reflection.REFERENCE.invokeBindValue(holder, platform); // IMPORTANT: bind holder.
|
||||
|
||||
|
||||
platformBiome.getContext().put(new NMSBiomeInfo(delegateKey));
|
||||
|
||||
|
||||
terraBiomeMap.computeIfAbsent(vanillaMinecraftKey, i -> new ArrayList<>()).add(delegateKey.location());
|
||||
|
||||
|
||||
LOGGER.debug("Registered biome: " + delegateKey);
|
||||
} catch(NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
Reflection.MAPPED_REGISTRY.setFrozen((MappedRegistry<?>) biomeRegistry, true); // freeze registry again :)
|
||||
|
||||
|
||||
LOGGER.info("Doing tag garbage....");
|
||||
Map<TagKey<Biome>, List<Holder<Biome>>> collect = biomeRegistry
|
||||
.getTags() // streamKeysAndEntries
|
||||
.collect(HashMap::new,
|
||||
(map, pair) ->
|
||||
map.put(pair.getFirst(), new ArrayList<>(pair.getSecond().stream().toList())),
|
||||
HashMap::putAll);
|
||||
|
||||
.getTags() // streamKeysAndEntries
|
||||
.collect(HashMap::new,
|
||||
(map, pair) ->
|
||||
map.put(pair.getFirst(), new ArrayList<>(pair.getSecond().stream().toList())),
|
||||
HashMap::putAll);
|
||||
|
||||
terraBiomeMap
|
||||
.forEach((vb, terraBiomes) ->
|
||||
NMSBiomeInjector.getEntry(biomeRegistry, vb).ifPresentOrElse(
|
||||
vanilla -> terraBiomes.forEach(
|
||||
tb -> NMSBiomeInjector.getEntry(biomeRegistry, tb).ifPresentOrElse(
|
||||
terra -> {
|
||||
LOGGER.debug("{} (vanilla for {}): {}",
|
||||
vanilla.unwrapKey().orElseThrow().location(),
|
||||
terra.unwrapKey().orElseThrow().location(),
|
||||
vanilla.tags().toList());
|
||||
vanilla.tags()
|
||||
.forEach(tag -> collect
|
||||
.computeIfAbsent(tag, t -> new ArrayList<>())
|
||||
.add(terra));
|
||||
},
|
||||
() -> LOGGER.error("No such biome: {}", tb))),
|
||||
() -> LOGGER.error("No vanilla biome: {}", vb)));
|
||||
|
||||
.forEach((vb, terraBiomes) ->
|
||||
NMSBiomeInjector.getEntry(biomeRegistry, vb).ifPresentOrElse(
|
||||
vanilla -> terraBiomes.forEach(
|
||||
tb -> NMSBiomeInjector.getEntry(biomeRegistry, tb).ifPresentOrElse(
|
||||
terra -> {
|
||||
LOGGER.debug("{} (vanilla for {}): {}",
|
||||
vanilla.unwrapKey().orElseThrow().location(),
|
||||
terra.unwrapKey().orElseThrow().location(),
|
||||
vanilla.tags().toList());
|
||||
vanilla.tags()
|
||||
.forEach(tag -> collect
|
||||
.computeIfAbsent(tag, t -> new ArrayList<>())
|
||||
.add(terra));
|
||||
},
|
||||
() -> LOGGER.error("No such biome: {}", tb))),
|
||||
() -> LOGGER.error("No vanilla biome: {}", vb)));
|
||||
|
||||
biomeRegistry.resetTags();
|
||||
biomeRegistry.bindTags(ImmutableMap.copyOf(collect));
|
||||
|
||||
|
||||
} catch(SecurityException | IllegalArgumentException exception) {
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
|
||||
+26
-26
@@ -15,62 +15,62 @@ import com.dfsek.terra.bukkit.config.VanillaBiomeProperties;
|
||||
|
||||
|
||||
public class NMSBiomeInjector {
|
||||
|
||||
|
||||
public static <T> Optional<Holder<T>> getEntry(Registry<T> registry, ResourceLocation identifier) {
|
||||
return registry.getOptional(identifier)
|
||||
.flatMap(registry::getResourceKey)
|
||||
.flatMap(registry::getHolder);
|
||||
.flatMap(registry::getResourceKey)
|
||||
.flatMap(registry::getHolder);
|
||||
}
|
||||
|
||||
|
||||
public static Biome createBiome(com.dfsek.terra.api.world.biome.Biome biome, Biome vanilla)
|
||||
throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
|
||||
Biome.BiomeBuilder builder = new Biome.BiomeBuilder();
|
||||
|
||||
|
||||
builder
|
||||
.downfall(vanilla.climateSettings.downfall())
|
||||
.temperature(vanilla.getBaseTemperature())
|
||||
.mobSpawnSettings(vanilla.getMobSettings())
|
||||
.generationSettings(vanilla.getGenerationSettings());
|
||||
|
||||
|
||||
.downfall(vanilla.climateSettings.downfall())
|
||||
.temperature(vanilla.getBaseTemperature())
|
||||
.mobSpawnSettings(vanilla.getMobSettings())
|
||||
.generationSettings(vanilla.getGenerationSettings());
|
||||
|
||||
|
||||
BiomeSpecialEffects.Builder effects = new BiomeSpecialEffects.Builder();
|
||||
|
||||
|
||||
effects.grassColorModifier(vanilla.getSpecialEffects().getGrassColorModifier());
|
||||
|
||||
|
||||
VanillaBiomeProperties vanillaBiomeProperties = biome.getContext().get(VanillaBiomeProperties.class);
|
||||
|
||||
|
||||
effects.fogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getFogColor(), vanilla.getFogColor()))
|
||||
|
||||
.waterColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterColor(), vanilla.getWaterColor()))
|
||||
|
||||
.waterFogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterFogColor(), vanilla.getWaterFogColor()))
|
||||
|
||||
.skyColor(Objects.requireNonNullElse(vanillaBiomeProperties.getSkyColor(), vanilla.getSkyColor()));
|
||||
|
||||
|
||||
.waterColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterColor(), vanilla.getWaterColor()))
|
||||
|
||||
.waterFogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterFogColor(), vanilla.getWaterFogColor()))
|
||||
|
||||
.skyColor(Objects.requireNonNullElse(vanillaBiomeProperties.getSkyColor(), vanilla.getSkyColor()));
|
||||
|
||||
if(vanillaBiomeProperties.getFoliageColor() == null) {
|
||||
vanilla.getSpecialEffects().getFoliageColorOverride().ifPresent(effects::foliageColorOverride);
|
||||
} else {
|
||||
effects.foliageColorOverride(vanillaBiomeProperties.getFoliageColor());
|
||||
}
|
||||
|
||||
|
||||
if(vanillaBiomeProperties.getGrassColor() == null) {
|
||||
vanilla.getSpecialEffects().getGrassColorOverride().ifPresent(effects::grassColorOverride);
|
||||
} else {
|
||||
// grass
|
||||
effects.grassColorOverride(vanillaBiomeProperties.getGrassColor());
|
||||
}
|
||||
|
||||
|
||||
vanilla.getAmbientLoop().ifPresent(effects::ambientLoopSound);
|
||||
vanilla.getAmbientAdditions().ifPresent(effects::ambientAdditionsSound);
|
||||
vanilla.getAmbientMood().ifPresent(effects::ambientMoodSound);
|
||||
vanilla.getBackgroundMusic().ifPresent(effects::backgroundMusic);
|
||||
vanilla.getAmbientParticle().ifPresent(effects::ambientParticle);
|
||||
|
||||
|
||||
builder.specialEffects(effects.build());
|
||||
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
||||
public static String createBiomeID(ConfigPack pack, com.dfsek.terra.api.registry.key.RegistryKey biomeID) {
|
||||
return pack.getID()
|
||||
.toLowerCase() + "/" + biomeID.getNamespace().toLowerCase(Locale.ROOT) + "/" + biomeID.getID().toLowerCase(Locale.ROOT);
|
||||
|
||||
+11
-11
@@ -18,32 +18,32 @@ public class NMSBiomeProvider extends BiomeSource {
|
||||
private final BiomeProvider delegate;
|
||||
private final long seed;
|
||||
private final Registry<Biome> biomeRegistry = RegistryFetcher.biomeRegistry();
|
||||
|
||||
|
||||
public NMSBiomeProvider(BiomeProvider delegate, long seed) {
|
||||
super();
|
||||
this.delegate = delegate;
|
||||
this.seed = seed;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Stream<Holder<Biome>> collectPossibleBiomes() {
|
||||
return delegate.stream()
|
||||
.map(biome -> RegistryFetcher.biomeRegistry()
|
||||
.getHolderOrThrow(((BukkitPlatformBiome) biome.getPlatformBiome()).getContext()
|
||||
.get(NMSBiomeInfo.class)
|
||||
.biomeKey()));
|
||||
.map(biome -> RegistryFetcher.biomeRegistry()
|
||||
.getHolderOrThrow(((BukkitPlatformBiome) biome.getPlatformBiome()).getContext()
|
||||
.get(NMSBiomeInfo.class)
|
||||
.biomeKey()));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected @NotNull Codec<? extends BiomeSource> codec() {
|
||||
return BiomeSource.CODEC;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull Holder<Biome> getNoiseBiome(int x, int y, int z, @NotNull Sampler sampler) {
|
||||
return biomeRegistry.getHolderOrThrow(((BukkitPlatformBiome) delegate.getBiome(x << 2, y << 2, z << 2, seed)
|
||||
.getPlatformBiome()).getContext()
|
||||
.get(NMSBiomeInfo.class)
|
||||
.biomeKey());
|
||||
.getPlatformBiome()).getContext()
|
||||
.get(NMSBiomeInfo.class)
|
||||
.biomeKey());
|
||||
}
|
||||
}
|
||||
|
||||
+31
-31
@@ -39,12 +39,12 @@ import com.dfsek.terra.bukkit.world.block.data.BukkitBlockState;
|
||||
public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(NMSChunkGeneratorDelegate.class);
|
||||
private final com.dfsek.terra.api.world.chunk.generation.ChunkGenerator delegate;
|
||||
|
||||
|
||||
private final ChunkGenerator vanilla;
|
||||
private final ConfigPack pack;
|
||||
|
||||
|
||||
private final long seed;
|
||||
|
||||
|
||||
public NMSChunkGeneratorDelegate(ChunkGenerator vanilla, ConfigPack pack, NMSBiomeProvider biomeProvider, long seed) {
|
||||
super(biomeProvider);
|
||||
this.delegate = pack.getGeneratorProvider().newInstance(pack);
|
||||
@@ -52,57 +52,57 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
this.pack = pack;
|
||||
this.seed = seed;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected @NotNull Codec<? extends ChunkGenerator> codec() {
|
||||
return ChunkGenerator.CODEC;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void applyCarvers(@NotNull WorldGenRegion chunkRegion, long seed, @NotNull RandomState noiseConfig, @NotNull BiomeManager world,
|
||||
@NotNull StructureManager structureAccessor, @NotNull ChunkAccess chunk, @NotNull Carving carverStep) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void buildSurface(@NotNull WorldGenRegion region, @NotNull StructureManager structures, @NotNull RandomState noiseConfig,
|
||||
@NotNull ChunkAccess chunk) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void applyBiomeDecoration(@NotNull WorldGenLevel world, @NotNull ChunkAccess chunk,
|
||||
@NotNull StructureManager structureAccessor) {
|
||||
vanilla.applyBiomeDecoration(world, chunk, structureAccessor);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void spawnOriginalMobs(@NotNull WorldGenRegion region) {
|
||||
vanilla.spawnOriginalMobs(region);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getGenDepth() {
|
||||
return vanilla.getGenDepth();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull CompletableFuture<ChunkAccess> fillFromNoise(@NotNull Executor executor, @NotNull Blender blender,
|
||||
@NotNull RandomState noiseConfig,
|
||||
@NotNull StructureManager structureAccessor, @NotNull ChunkAccess chunk) {
|
||||
return vanilla.fillFromNoise(executor, blender, noiseConfig, structureAccessor, chunk)
|
||||
.thenApply(c -> {
|
||||
LevelAccessor level = Reflection.STRUCTURE_MANAGER.getLevel(structureAccessor);
|
||||
BiomeProvider biomeProvider = pack.getBiomeProvider();
|
||||
PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class);
|
||||
if(compatibilityOptions.isBeard()) {
|
||||
beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()),
|
||||
biomeProvider, compatibilityOptions);
|
||||
}
|
||||
return c;
|
||||
});
|
||||
.thenApply(c -> {
|
||||
LevelAccessor level = Reflection.STRUCTURE_MANAGER.getLevel(structureAccessor);
|
||||
BiomeProvider biomeProvider = pack.getBiomeProvider();
|
||||
PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class);
|
||||
if(compatibilityOptions.isBeard()) {
|
||||
beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()),
|
||||
biomeProvider, compatibilityOptions);
|
||||
}
|
||||
return c;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void beard(StructureManager structureAccessor, ChunkAccess chunk, WorldProperties world, BiomeProvider biomeProvider,
|
||||
PreLoadCompatibilityOptions compatibilityOptions) {
|
||||
Beardifier structureWeightSampler = Beardifier.forStructuresInChunk(structureAccessor, chunk.getPos());
|
||||
@@ -117,8 +117,8 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
double noise = structureWeightSampler.compute(new SinglePointContext(x + xi, y, z + zi));
|
||||
if(noise > threshold) {
|
||||
chunk.setBlockState(new BlockPos(x, y, z), ((CraftBlockData) ((BukkitBlockState) delegate
|
||||
.getPalette(x + xi, y, z + zi, world, biomeProvider)
|
||||
.get(depth, x + xi, y, z + zi, world.getSeed())).getHandle()).getState(), false);
|
||||
.getPalette(x + xi, y, z + zi, world, biomeProvider)
|
||||
.get(depth, x + xi, y, z + zi, world.getSeed())).getHandle()).getState(), false);
|
||||
depth++;
|
||||
} else if(noise < airThreshold) {
|
||||
chunk.setBlockState(new BlockPos(x, y, z), Blocks.AIR.defaultBlockState(), false);
|
||||
@@ -129,29 +129,29 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getSeaLevel() {
|
||||
return vanilla.getSeaLevel();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMinY() {
|
||||
return vanilla.getMinY();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getBaseHeight(int x, int z, @NotNull Types heightmap, @NotNull LevelHeightAccessor world, @NotNull RandomState noiseConfig) {
|
||||
WorldProperties properties = new NMSWorldProperties(seed, world);
|
||||
int y = properties.getMaxHeight();
|
||||
BiomeProvider biomeProvider = pack.getBiomeProvider();
|
||||
while(y >= getMinY() && !heightmap.isOpaque().test(
|
||||
((CraftBlockData) delegate.getBlock(properties, x, y - 1, z, biomeProvider).getHandle()).getState())) {
|
||||
((CraftBlockData) delegate.getBlock(properties, x, y - 1, z, biomeProvider).getHandle()).getState())) {
|
||||
y--;
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull NoiseColumn getBaseColumn(int x, int z, @NotNull LevelHeightAccessor world, @NotNull RandomState noiseConfig) {
|
||||
BlockState[] array = new BlockState[world.getHeight()];
|
||||
@@ -159,13 +159,13 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
BiomeProvider biomeProvider = pack.getBiomeProvider();
|
||||
for(int y = properties.getMaxHeight() - 1; y >= properties.getMinHeight(); y--) {
|
||||
array[y - properties.getMinHeight()] = ((CraftBlockData) delegate.getBlock(properties, x, y, z, biomeProvider)
|
||||
.getHandle()).getState();
|
||||
.getHandle()).getState();
|
||||
}
|
||||
return new NoiseColumn(getMinY(), array);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addDebugScreenInfo(@NotNull List<String> text, @NotNull RandomState noiseConfig, @NotNull BlockPos pos) {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_19_R3;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import com.dfsek.terra.bukkit.PlatformImpl;
|
||||
import com.dfsek.terra.bukkit.nms.Initializer;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
|
||||
public class NMSInitializer implements Initializer {
|
||||
@Override
|
||||
|
||||
+6
-6
@@ -22,7 +22,7 @@ public class NMSInjectListener implements Listener {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(NMSInjectListener.class);
|
||||
private static final Set<World> INJECTED = new HashSet<>();
|
||||
private static final ReentrantLock INJECT_LOCK = new ReentrantLock();
|
||||
|
||||
|
||||
@EventHandler
|
||||
public void onWorldInit(WorldInitEvent event) {
|
||||
if(!INJECTED.contains(event.getWorld()) &&
|
||||
@@ -32,16 +32,16 @@ public class NMSInjectListener implements Listener {
|
||||
LOGGER.info("Preparing to take over the world: {}", event.getWorld().getName());
|
||||
CraftWorld craftWorld = (CraftWorld) event.getWorld();
|
||||
ServerLevel serverWorld = craftWorld.getHandle();
|
||||
|
||||
|
||||
ConfigPack pack = bukkitChunkGeneratorWrapper.getPack();
|
||||
|
||||
|
||||
ChunkGenerator vanilla = serverWorld.getChunkSource().getGenerator();
|
||||
NMSBiomeProvider provider = new NMSBiomeProvider(pack.getBiomeProvider(), craftWorld.getSeed());
|
||||
|
||||
|
||||
serverWorld.getChunkSource().chunkMap.generator = new NMSChunkGeneratorDelegate(vanilla, pack, provider, craftWorld.getSeed());
|
||||
|
||||
|
||||
LOGGER.info("Successfully injected into world.");
|
||||
|
||||
|
||||
INJECT_LOCK.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -8,27 +8,27 @@ import com.dfsek.terra.api.world.info.WorldProperties;
|
||||
public class NMSWorldProperties implements WorldProperties {
|
||||
private final long seed;
|
||||
private final LevelHeightAccessor height;
|
||||
|
||||
|
||||
public NMSWorldProperties(long seed, LevelHeightAccessor height) {
|
||||
this.seed = seed;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object getHandle() {
|
||||
return height;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long getSeed() {
|
||||
return seed;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMaxHeight() {
|
||||
return height.getMaxBuildHeight();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMinHeight() {
|
||||
return height.getMinBuildHeight();
|
||||
|
||||
+10
-10
@@ -16,34 +16,34 @@ import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies;
|
||||
public class Reflection {
|
||||
public static final MappedRegistryProxy MAPPED_REGISTRY;
|
||||
public static final StructureManagerProxy STRUCTURE_MANAGER;
|
||||
|
||||
|
||||
public static final ReferenceProxy REFERENCE;
|
||||
|
||||
|
||||
static {
|
||||
ReflectionRemapper reflectionRemapper = ReflectionRemapper.forReobfMappingsInPaperJar();
|
||||
ReflectionProxyFactory reflectionProxyFactory = ReflectionProxyFactory.create(reflectionRemapper,
|
||||
Reflection.class.getClassLoader());
|
||||
|
||||
Reflection.class.getClassLoader());
|
||||
|
||||
MAPPED_REGISTRY = reflectionProxyFactory.reflectionProxy(MappedRegistryProxy.class);
|
||||
STRUCTURE_MANAGER = reflectionProxyFactory.reflectionProxy(StructureManagerProxy.class);
|
||||
REFERENCE = reflectionProxyFactory.reflectionProxy(ReferenceProxy.class);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Proxies(MappedRegistry.class)
|
||||
public interface MappedRegistryProxy {
|
||||
@FieldSetter("frozen")
|
||||
void setFrozen(MappedRegistry<?> instance, boolean frozen);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Proxies(StructureManager.class)
|
||||
public interface StructureManagerProxy {
|
||||
@FieldGetter("level")
|
||||
LevelAccessor getLevel(StructureManager instance);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Proxies(Holder.Reference.class)
|
||||
public interface ReferenceProxy {
|
||||
@MethodName("bindValue")
|
||||
|
||||
+3
-3
@@ -14,10 +14,10 @@ public class RegistryFetcher {
|
||||
CraftServer craftserver = (CraftServer) Bukkit.getServer();
|
||||
DedicatedServer dedicatedserver = craftserver.getServer();
|
||||
return dedicatedserver
|
||||
.registryAccess()
|
||||
.registryOrThrow(key);
|
||||
.registryAccess()
|
||||
.registryOrThrow(key);
|
||||
}
|
||||
|
||||
|
||||
public static Registry<Biome> biomeRegistry() {
|
||||
return getRegistry(Registries.BIOME);
|
||||
}
|
||||
|
||||
+38
-38
@@ -27,72 +27,72 @@ import com.dfsek.terra.registry.master.ConfigRegistry;
|
||||
|
||||
public class AwfulBukkitHacks {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(AwfulBukkitHacks.class);
|
||||
|
||||
|
||||
private static final Map<ResourceLocation, List<ResourceLocation>> terraBiomeMap = new HashMap<>();
|
||||
|
||||
|
||||
public static void registerBiomes(ConfigRegistry configRegistry) {
|
||||
try {
|
||||
LOGGER.info("Hacking biome registry...");
|
||||
WritableRegistry<Biome> biomeRegistry = (WritableRegistry<Biome>) RegistryFetcher.biomeRegistry();
|
||||
|
||||
|
||||
Reflection.MAPPED_REGISTRY.setFrozen((MappedRegistry<?>) biomeRegistry, false);
|
||||
|
||||
|
||||
configRegistry.forEach(pack -> pack.getRegistry(com.dfsek.terra.api.world.biome.Biome.class).forEach((key, biome) -> {
|
||||
try {
|
||||
BukkitPlatformBiome platformBiome = (BukkitPlatformBiome) biome.getPlatformBiome();
|
||||
NamespacedKey vanillaBukkitKey = platformBiome.getHandle().getKey();
|
||||
ResourceLocation vanillaMinecraftKey = new ResourceLocation(vanillaBukkitKey.getNamespace(), vanillaBukkitKey.getKey());
|
||||
Biome platform = NMSBiomeInjector.createBiome(biome, Objects.requireNonNull(biomeRegistry.get(vanillaMinecraftKey)));
|
||||
|
||||
|
||||
ResourceKey<Biome> delegateKey = ResourceKey.create(
|
||||
Registries.BIOME,
|
||||
new ResourceLocation("terra", NMSBiomeInjector.createBiomeID(pack, key))
|
||||
);
|
||||
|
||||
Registries.BIOME,
|
||||
new ResourceLocation("terra", NMSBiomeInjector.createBiomeID(pack, key))
|
||||
);
|
||||
|
||||
Reference<Biome> holder = biomeRegistry.register(delegateKey, platform, Lifecycle.stable());
|
||||
Reflection.REFERENCE.invokeBindValue(holder, platform); // IMPORTANT: bind holder.
|
||||
|
||||
|
||||
platformBiome.getContext().put(new NMSBiomeInfo(delegateKey));
|
||||
|
||||
|
||||
terraBiomeMap.computeIfAbsent(vanillaMinecraftKey, i -> new ArrayList<>()).add(delegateKey.location());
|
||||
|
||||
|
||||
LOGGER.debug("Registered biome: " + delegateKey);
|
||||
} catch(NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
Reflection.MAPPED_REGISTRY.setFrozen((MappedRegistry<?>) biomeRegistry, true); // freeze registry again :)
|
||||
|
||||
|
||||
LOGGER.info("Doing tag garbage....");
|
||||
Map<TagKey<Biome>, List<Holder<Biome>>> collect = biomeRegistry
|
||||
.getTags() // streamKeysAndEntries
|
||||
.collect(HashMap::new,
|
||||
(map, pair) ->
|
||||
map.put(pair.getFirst(), new ArrayList<>(pair.getSecond().stream().toList())),
|
||||
HashMap::putAll);
|
||||
|
||||
.getTags() // streamKeysAndEntries
|
||||
.collect(HashMap::new,
|
||||
(map, pair) ->
|
||||
map.put(pair.getFirst(), new ArrayList<>(pair.getSecond().stream().toList())),
|
||||
HashMap::putAll);
|
||||
|
||||
terraBiomeMap
|
||||
.forEach((vb, terraBiomes) ->
|
||||
NMSBiomeInjector.getEntry(biomeRegistry, vb).ifPresentOrElse(
|
||||
vanilla -> terraBiomes.forEach(
|
||||
tb -> NMSBiomeInjector.getEntry(biomeRegistry, tb).ifPresentOrElse(
|
||||
terra -> {
|
||||
LOGGER.debug("{} (vanilla for {}): {}",
|
||||
vanilla.unwrapKey().orElseThrow().location(),
|
||||
terra.unwrapKey().orElseThrow().location(),
|
||||
vanilla.tags().toList());
|
||||
vanilla.tags()
|
||||
.forEach(tag -> collect
|
||||
.computeIfAbsent(tag, t -> new ArrayList<>())
|
||||
.add(terra));
|
||||
},
|
||||
() -> LOGGER.error("No such biome: {}", tb))),
|
||||
() -> LOGGER.error("No vanilla biome: {}", vb)));
|
||||
|
||||
.forEach((vb, terraBiomes) ->
|
||||
NMSBiomeInjector.getEntry(biomeRegistry, vb).ifPresentOrElse(
|
||||
vanilla -> terraBiomes.forEach(
|
||||
tb -> NMSBiomeInjector.getEntry(biomeRegistry, tb).ifPresentOrElse(
|
||||
terra -> {
|
||||
LOGGER.debug("{} (vanilla for {}): {}",
|
||||
vanilla.unwrapKey().orElseThrow().location(),
|
||||
terra.unwrapKey().orElseThrow().location(),
|
||||
vanilla.tags().toList());
|
||||
vanilla.tags()
|
||||
.forEach(tag -> collect
|
||||
.computeIfAbsent(tag, t -> new ArrayList<>())
|
||||
.add(terra));
|
||||
},
|
||||
() -> LOGGER.error("No such biome: {}", tb))),
|
||||
() -> LOGGER.error("No vanilla biome: {}", vb)));
|
||||
|
||||
biomeRegistry.resetTags();
|
||||
biomeRegistry.bindTags(ImmutableMap.copyOf(collect));
|
||||
|
||||
|
||||
} catch(SecurityException | IllegalArgumentException exception) {
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_20_R1;
|
||||
|
||||
import com.dfsek.terra.api.properties.Properties;
|
||||
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
|
||||
import com.dfsek.terra.api.properties.Properties;
|
||||
|
||||
|
||||
public record NMSBiomeInfo(ResourceKey<Biome> biomeKey) implements Properties {
|
||||
}
|
||||
|
||||
+26
-26
@@ -15,62 +15,62 @@ import com.dfsek.terra.bukkit.config.VanillaBiomeProperties;
|
||||
|
||||
|
||||
public class NMSBiomeInjector {
|
||||
|
||||
|
||||
public static <T> Optional<Holder<T>> getEntry(Registry<T> registry, ResourceLocation identifier) {
|
||||
return registry.getOptional(identifier)
|
||||
.flatMap(registry::getResourceKey)
|
||||
.flatMap(registry::getHolder);
|
||||
.flatMap(registry::getResourceKey)
|
||||
.flatMap(registry::getHolder);
|
||||
}
|
||||
|
||||
|
||||
public static Biome createBiome(com.dfsek.terra.api.world.biome.Biome biome, Biome vanilla)
|
||||
throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
|
||||
Biome.BiomeBuilder builder = new Biome.BiomeBuilder();
|
||||
|
||||
|
||||
builder
|
||||
.downfall(vanilla.climateSettings.downfall())
|
||||
.temperature(vanilla.getBaseTemperature())
|
||||
.mobSpawnSettings(vanilla.getMobSettings())
|
||||
.generationSettings(vanilla.getGenerationSettings());
|
||||
|
||||
|
||||
.downfall(vanilla.climateSettings.downfall())
|
||||
.temperature(vanilla.getBaseTemperature())
|
||||
.mobSpawnSettings(vanilla.getMobSettings())
|
||||
.generationSettings(vanilla.getGenerationSettings());
|
||||
|
||||
|
||||
BiomeSpecialEffects.Builder effects = new BiomeSpecialEffects.Builder();
|
||||
|
||||
|
||||
effects.grassColorModifier(vanilla.getSpecialEffects().getGrassColorModifier());
|
||||
|
||||
|
||||
VanillaBiomeProperties vanillaBiomeProperties = biome.getContext().get(VanillaBiomeProperties.class);
|
||||
|
||||
|
||||
effects.fogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getFogColor(), vanilla.getFogColor()))
|
||||
|
||||
.waterColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterColor(), vanilla.getWaterColor()))
|
||||
|
||||
.waterFogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterFogColor(), vanilla.getWaterFogColor()))
|
||||
|
||||
.skyColor(Objects.requireNonNullElse(vanillaBiomeProperties.getSkyColor(), vanilla.getSkyColor()));
|
||||
|
||||
|
||||
.waterColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterColor(), vanilla.getWaterColor()))
|
||||
|
||||
.waterFogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterFogColor(), vanilla.getWaterFogColor()))
|
||||
|
||||
.skyColor(Objects.requireNonNullElse(vanillaBiomeProperties.getSkyColor(), vanilla.getSkyColor()));
|
||||
|
||||
if(vanillaBiomeProperties.getFoliageColor() == null) {
|
||||
vanilla.getSpecialEffects().getFoliageColorOverride().ifPresent(effects::foliageColorOverride);
|
||||
} else {
|
||||
effects.foliageColorOverride(vanillaBiomeProperties.getFoliageColor());
|
||||
}
|
||||
|
||||
|
||||
if(vanillaBiomeProperties.getGrassColor() == null) {
|
||||
vanilla.getSpecialEffects().getGrassColorOverride().ifPresent(effects::grassColorOverride);
|
||||
} else {
|
||||
// grass
|
||||
effects.grassColorOverride(vanillaBiomeProperties.getGrassColor());
|
||||
}
|
||||
|
||||
|
||||
vanilla.getAmbientLoop().ifPresent(effects::ambientLoopSound);
|
||||
vanilla.getAmbientAdditions().ifPresent(effects::ambientAdditionsSound);
|
||||
vanilla.getAmbientMood().ifPresent(effects::ambientMoodSound);
|
||||
vanilla.getBackgroundMusic().ifPresent(effects::backgroundMusic);
|
||||
vanilla.getAmbientParticle().ifPresent(effects::ambientParticle);
|
||||
|
||||
|
||||
builder.specialEffects(effects.build());
|
||||
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
||||
public static String createBiomeID(ConfigPack pack, com.dfsek.terra.api.registry.key.RegistryKey biomeID) {
|
||||
return pack.getID()
|
||||
.toLowerCase() + "/" + biomeID.getNamespace().toLowerCase(Locale.ROOT) + "/" + biomeID.getID().toLowerCase(Locale.ROOT);
|
||||
|
||||
+11
-11
@@ -18,32 +18,32 @@ public class NMSBiomeProvider extends BiomeSource {
|
||||
private final BiomeProvider delegate;
|
||||
private final long seed;
|
||||
private final Registry<Biome> biomeRegistry = RegistryFetcher.biomeRegistry();
|
||||
|
||||
|
||||
public NMSBiomeProvider(BiomeProvider delegate, long seed) {
|
||||
super();
|
||||
this.delegate = delegate;
|
||||
this.seed = seed;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Stream<Holder<Biome>> collectPossibleBiomes() {
|
||||
return delegate.stream()
|
||||
.map(biome -> RegistryFetcher.biomeRegistry()
|
||||
.getHolderOrThrow(((BukkitPlatformBiome) biome.getPlatformBiome()).getContext()
|
||||
.get(NMSBiomeInfo.class)
|
||||
.biomeKey()));
|
||||
.map(biome -> RegistryFetcher.biomeRegistry()
|
||||
.getHolderOrThrow(((BukkitPlatformBiome) biome.getPlatformBiome()).getContext()
|
||||
.get(NMSBiomeInfo.class)
|
||||
.biomeKey()));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected @NotNull Codec<? extends BiomeSource> codec() {
|
||||
return BiomeSource.CODEC;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull Holder<Biome> getNoiseBiome(int x, int y, int z, @NotNull Sampler sampler) {
|
||||
return biomeRegistry.getHolderOrThrow(((BukkitPlatformBiome) delegate.getBiome(x << 2, y << 2, z << 2, seed)
|
||||
.getPlatformBiome()).getContext()
|
||||
.get(NMSBiomeInfo.class)
|
||||
.biomeKey());
|
||||
.getPlatformBiome()).getContext()
|
||||
.get(NMSBiomeInfo.class)
|
||||
.biomeKey());
|
||||
}
|
||||
}
|
||||
|
||||
+43
-39
@@ -1,16 +1,13 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_20_R1;
|
||||
|
||||
import com.dfsek.terra.api.config.ConfigPack;
|
||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
import com.dfsek.terra.api.world.info.WorldProperties;
|
||||
import com.dfsek.terra.bukkit.config.PreLoadCompatibilityOptions;
|
||||
import com.dfsek.terra.bukkit.world.BukkitWorldProperties;
|
||||
import com.dfsek.terra.bukkit.world.block.data.BukkitBlockState;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.WorldGenRegion;
|
||||
import net.minecraft.world.level.*;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.LevelHeightAccessor;
|
||||
import net.minecraft.world.level.NoiseColumn;
|
||||
import net.minecraft.world.level.StructureManager;
|
||||
import net.minecraft.world.level.WorldGenLevel;
|
||||
import net.minecraft.world.level.biome.BiomeManager;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
@@ -31,16 +28,23 @@ import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import com.dfsek.terra.api.config.ConfigPack;
|
||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
import com.dfsek.terra.api.world.info.WorldProperties;
|
||||
import com.dfsek.terra.bukkit.config.PreLoadCompatibilityOptions;
|
||||
import com.dfsek.terra.bukkit.world.BukkitWorldProperties;
|
||||
import com.dfsek.terra.bukkit.world.block.data.BukkitBlockState;
|
||||
|
||||
|
||||
public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(NMSChunkGeneratorDelegate.class);
|
||||
private final com.dfsek.terra.api.world.chunk.generation.ChunkGenerator delegate;
|
||||
|
||||
|
||||
private final ChunkGenerator vanilla;
|
||||
private final ConfigPack pack;
|
||||
|
||||
|
||||
private final long seed;
|
||||
|
||||
|
||||
public NMSChunkGeneratorDelegate(ChunkGenerator vanilla, ConfigPack pack, NMSBiomeProvider biomeProvider, long seed) {
|
||||
super(biomeProvider);
|
||||
this.delegate = pack.getGeneratorProvider().newInstance(pack);
|
||||
@@ -48,57 +52,57 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
this.pack = pack;
|
||||
this.seed = seed;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected @NotNull Codec<? extends ChunkGenerator> codec() {
|
||||
return ChunkGenerator.CODEC;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void applyCarvers(@NotNull WorldGenRegion chunkRegion, long seed, @NotNull RandomState noiseConfig, @NotNull BiomeManager world,
|
||||
@NotNull StructureManager structureAccessor, @NotNull ChunkAccess chunk, @NotNull Carving carverStep) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void buildSurface(@NotNull WorldGenRegion region, @NotNull StructureManager structures, @NotNull RandomState noiseConfig,
|
||||
@NotNull ChunkAccess chunk) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void applyBiomeDecoration(@NotNull WorldGenLevel world, @NotNull ChunkAccess chunk,
|
||||
@NotNull StructureManager structureAccessor) {
|
||||
vanilla.applyBiomeDecoration(world, chunk, structureAccessor);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void spawnOriginalMobs(@NotNull WorldGenRegion region) {
|
||||
vanilla.spawnOriginalMobs(region);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getGenDepth() {
|
||||
return vanilla.getGenDepth();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull CompletableFuture<ChunkAccess> fillFromNoise(@NotNull Executor executor, @NotNull Blender blender,
|
||||
@NotNull RandomState noiseConfig,
|
||||
@NotNull StructureManager structureAccessor, @NotNull ChunkAccess chunk) {
|
||||
return vanilla.fillFromNoise(executor, blender, noiseConfig, structureAccessor, chunk)
|
||||
.thenApply(c -> {
|
||||
LevelAccessor level = Reflection.STRUCTURE_MANAGER.getLevel(structureAccessor);
|
||||
BiomeProvider biomeProvider = pack.getBiomeProvider();
|
||||
PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class);
|
||||
if(compatibilityOptions.isBeard()) {
|
||||
beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()),
|
||||
biomeProvider, compatibilityOptions);
|
||||
}
|
||||
return c;
|
||||
});
|
||||
.thenApply(c -> {
|
||||
LevelAccessor level = Reflection.STRUCTURE_MANAGER.getLevel(structureAccessor);
|
||||
BiomeProvider biomeProvider = pack.getBiomeProvider();
|
||||
PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class);
|
||||
if(compatibilityOptions.isBeard()) {
|
||||
beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()),
|
||||
biomeProvider, compatibilityOptions);
|
||||
}
|
||||
return c;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void beard(StructureManager structureAccessor, ChunkAccess chunk, WorldProperties world, BiomeProvider biomeProvider,
|
||||
PreLoadCompatibilityOptions compatibilityOptions) {
|
||||
Beardifier structureWeightSampler = Beardifier.forStructuresInChunk(structureAccessor, chunk.getPos());
|
||||
@@ -113,8 +117,8 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
double noise = structureWeightSampler.compute(new SinglePointContext(x + xi, y, z + zi));
|
||||
if(noise > threshold) {
|
||||
chunk.setBlockState(new BlockPos(x, y, z), ((CraftBlockData) ((BukkitBlockState) delegate
|
||||
.getPalette(x + xi, y, z + zi, world, biomeProvider)
|
||||
.get(depth, x + xi, y, z + zi, world.getSeed())).getHandle()).getState(), false);
|
||||
.getPalette(x + xi, y, z + zi, world, biomeProvider)
|
||||
.get(depth, x + xi, y, z + zi, world.getSeed())).getHandle()).getState(), false);
|
||||
depth++;
|
||||
} else if(noise < airThreshold) {
|
||||
chunk.setBlockState(new BlockPos(x, y, z), Blocks.AIR.defaultBlockState(), false);
|
||||
@@ -125,29 +129,29 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getSeaLevel() {
|
||||
return vanilla.getSeaLevel();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMinY() {
|
||||
return vanilla.getMinY();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getBaseHeight(int x, int z, @NotNull Types heightmap, @NotNull LevelHeightAccessor world, @NotNull RandomState noiseConfig) {
|
||||
WorldProperties properties = new NMSWorldProperties(seed, world);
|
||||
int y = properties.getMaxHeight();
|
||||
BiomeProvider biomeProvider = pack.getBiomeProvider();
|
||||
while(y >= getMinY() && !heightmap.isOpaque().test(
|
||||
((CraftBlockData) delegate.getBlock(properties, x, y - 1, z, biomeProvider).getHandle()).getState())) {
|
||||
((CraftBlockData) delegate.getBlock(properties, x, y - 1, z, biomeProvider).getHandle()).getState())) {
|
||||
y--;
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull NoiseColumn getBaseColumn(int x, int z, @NotNull LevelHeightAccessor world, @NotNull RandomState noiseConfig) {
|
||||
BlockState[] array = new BlockState[world.getHeight()];
|
||||
@@ -155,13 +159,13 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
BiomeProvider biomeProvider = pack.getBiomeProvider();
|
||||
for(int y = properties.getMaxHeight() - 1; y >= properties.getMinHeight(); y--) {
|
||||
array[y - properties.getMinHeight()] = ((CraftBlockData) delegate.getBlock(properties, x, y, z, biomeProvider)
|
||||
.getHandle()).getState();
|
||||
.getHandle()).getState();
|
||||
}
|
||||
return new NoiseColumn(getMinY(), array);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addDebugScreenInfo(@NotNull List<String> text, @NotNull RandomState noiseConfig, @NotNull BlockPos pos) {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+6
-6
@@ -22,7 +22,7 @@ public class NMSInjectListener implements Listener {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(NMSInjectListener.class);
|
||||
private static final Set<World> INJECTED = new HashSet<>();
|
||||
private static final ReentrantLock INJECT_LOCK = new ReentrantLock();
|
||||
|
||||
|
||||
@EventHandler
|
||||
public void onWorldInit(WorldInitEvent event) {
|
||||
if(!INJECTED.contains(event.getWorld()) &&
|
||||
@@ -32,16 +32,16 @@ public class NMSInjectListener implements Listener {
|
||||
LOGGER.info("Preparing to take over the world: {}", event.getWorld().getName());
|
||||
CraftWorld craftWorld = (CraftWorld) event.getWorld();
|
||||
ServerLevel serverWorld = craftWorld.getHandle();
|
||||
|
||||
|
||||
ConfigPack pack = bukkitChunkGeneratorWrapper.getPack();
|
||||
|
||||
|
||||
ChunkGenerator vanilla = serverWorld.getChunkSource().getGenerator();
|
||||
NMSBiomeProvider provider = new NMSBiomeProvider(pack.getBiomeProvider(), craftWorld.getSeed());
|
||||
|
||||
|
||||
serverWorld.getChunkSource().chunkMap.generator = new NMSChunkGeneratorDelegate(vanilla, pack, provider, craftWorld.getSeed());
|
||||
|
||||
|
||||
LOGGER.info("Successfully injected into world.");
|
||||
|
||||
|
||||
INJECT_LOCK.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -8,27 +8,27 @@ import com.dfsek.terra.api.world.info.WorldProperties;
|
||||
public class NMSWorldProperties implements WorldProperties {
|
||||
private final long seed;
|
||||
private final LevelHeightAccessor height;
|
||||
|
||||
|
||||
public NMSWorldProperties(long seed, LevelHeightAccessor height) {
|
||||
this.seed = seed;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object getHandle() {
|
||||
return height;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long getSeed() {
|
||||
return seed;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMaxHeight() {
|
||||
return height.getMaxBuildHeight();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMinHeight() {
|
||||
return height.getMinBuildHeight();
|
||||
|
||||
+10
-10
@@ -16,34 +16,34 @@ import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies;
|
||||
public class Reflection {
|
||||
public static final MappedRegistryProxy MAPPED_REGISTRY;
|
||||
public static final StructureManagerProxy STRUCTURE_MANAGER;
|
||||
|
||||
|
||||
public static final ReferenceProxy REFERENCE;
|
||||
|
||||
|
||||
static {
|
||||
ReflectionRemapper reflectionRemapper = ReflectionRemapper.forReobfMappingsInPaperJar();
|
||||
ReflectionProxyFactory reflectionProxyFactory = ReflectionProxyFactory.create(reflectionRemapper,
|
||||
Reflection.class.getClassLoader());
|
||||
|
||||
Reflection.class.getClassLoader());
|
||||
|
||||
MAPPED_REGISTRY = reflectionProxyFactory.reflectionProxy(MappedRegistryProxy.class);
|
||||
STRUCTURE_MANAGER = reflectionProxyFactory.reflectionProxy(StructureManagerProxy.class);
|
||||
REFERENCE = reflectionProxyFactory.reflectionProxy(ReferenceProxy.class);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Proxies(MappedRegistry.class)
|
||||
public interface MappedRegistryProxy {
|
||||
@FieldSetter("frozen")
|
||||
void setFrozen(MappedRegistry<?> instance, boolean frozen);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Proxies(StructureManager.class)
|
||||
public interface StructureManagerProxy {
|
||||
@FieldGetter("level")
|
||||
LevelAccessor getLevel(StructureManager instance);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Proxies(Holder.Reference.class)
|
||||
public interface ReferenceProxy {
|
||||
@MethodName("bindValue")
|
||||
|
||||
+3
-3
@@ -14,10 +14,10 @@ public class RegistryFetcher {
|
||||
CraftServer craftserver = (CraftServer) Bukkit.getServer();
|
||||
DedicatedServer dedicatedserver = craftserver.getServer();
|
||||
return dedicatedserver
|
||||
.registryAccess()
|
||||
.registryOrThrow(key);
|
||||
.registryAccess()
|
||||
.registryOrThrow(key);
|
||||
}
|
||||
|
||||
|
||||
public static Registry<Biome> biomeRegistry() {
|
||||
return getRegistry(Registries.BIOME);
|
||||
}
|
||||
|
||||
+38
-38
@@ -27,72 +27,72 @@ import com.dfsek.terra.registry.master.ConfigRegistry;
|
||||
|
||||
public class AwfulBukkitHacks {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(AwfulBukkitHacks.class);
|
||||
|
||||
|
||||
private static final Map<ResourceLocation, List<ResourceLocation>> terraBiomeMap = new HashMap<>();
|
||||
|
||||
|
||||
public static void registerBiomes(ConfigRegistry configRegistry) {
|
||||
try {
|
||||
LOGGER.info("Hacking biome registry...");
|
||||
WritableRegistry<Biome> biomeRegistry = (WritableRegistry<Biome>) RegistryFetcher.biomeRegistry();
|
||||
|
||||
|
||||
Reflection.MAPPED_REGISTRY.setFrozen((MappedRegistry<?>) biomeRegistry, false);
|
||||
|
||||
|
||||
configRegistry.forEach(pack -> pack.getRegistry(com.dfsek.terra.api.world.biome.Biome.class).forEach((key, biome) -> {
|
||||
try {
|
||||
BukkitPlatformBiome platformBiome = (BukkitPlatformBiome) biome.getPlatformBiome();
|
||||
NamespacedKey vanillaBukkitKey = platformBiome.getHandle().getKey();
|
||||
ResourceLocation vanillaMinecraftKey = new ResourceLocation(vanillaBukkitKey.getNamespace(), vanillaBukkitKey.getKey());
|
||||
Biome platform = NMSBiomeInjector.createBiome(biome, Objects.requireNonNull(biomeRegistry.get(vanillaMinecraftKey)));
|
||||
|
||||
|
||||
ResourceKey<Biome> delegateKey = ResourceKey.create(
|
||||
Registries.BIOME,
|
||||
new ResourceLocation("terra", NMSBiomeInjector.createBiomeID(pack, key))
|
||||
);
|
||||
|
||||
Registries.BIOME,
|
||||
new ResourceLocation("terra", NMSBiomeInjector.createBiomeID(pack, key))
|
||||
);
|
||||
|
||||
Reference<Biome> holder = biomeRegistry.register(delegateKey, platform, Lifecycle.stable());
|
||||
Reflection.REFERENCE.invokeBindValue(holder, platform); // IMPORTANT: bind holder.
|
||||
|
||||
|
||||
platformBiome.getContext().put(new NMSBiomeInfo(delegateKey));
|
||||
|
||||
|
||||
terraBiomeMap.computeIfAbsent(vanillaMinecraftKey, i -> new ArrayList<>()).add(delegateKey.location());
|
||||
|
||||
|
||||
LOGGER.debug("Registered biome: " + delegateKey);
|
||||
} catch(NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
Reflection.MAPPED_REGISTRY.setFrozen((MappedRegistry<?>) biomeRegistry, true); // freeze registry again :)
|
||||
|
||||
|
||||
LOGGER.info("Doing tag garbage....");
|
||||
Map<TagKey<Biome>, List<Holder<Biome>>> collect = biomeRegistry
|
||||
.getTags() // streamKeysAndEntries
|
||||
.collect(HashMap::new,
|
||||
(map, pair) ->
|
||||
map.put(pair.getFirst(), new ArrayList<>(pair.getSecond().stream().toList())),
|
||||
HashMap::putAll);
|
||||
|
||||
.getTags() // streamKeysAndEntries
|
||||
.collect(HashMap::new,
|
||||
(map, pair) ->
|
||||
map.put(pair.getFirst(), new ArrayList<>(pair.getSecond().stream().toList())),
|
||||
HashMap::putAll);
|
||||
|
||||
terraBiomeMap
|
||||
.forEach((vb, terraBiomes) ->
|
||||
NMSBiomeInjector.getEntry(biomeRegistry, vb).ifPresentOrElse(
|
||||
vanilla -> terraBiomes.forEach(
|
||||
tb -> NMSBiomeInjector.getEntry(biomeRegistry, tb).ifPresentOrElse(
|
||||
terra -> {
|
||||
LOGGER.debug("{} (vanilla for {}): {}",
|
||||
vanilla.unwrapKey().orElseThrow().location(),
|
||||
terra.unwrapKey().orElseThrow().location(),
|
||||
vanilla.tags().toList());
|
||||
vanilla.tags()
|
||||
.forEach(tag -> collect
|
||||
.computeIfAbsent(tag, t -> new ArrayList<>())
|
||||
.add(terra));
|
||||
},
|
||||
() -> LOGGER.error("No such biome: {}", tb))),
|
||||
() -> LOGGER.error("No vanilla biome: {}", vb)));
|
||||
|
||||
.forEach((vb, terraBiomes) ->
|
||||
NMSBiomeInjector.getEntry(biomeRegistry, vb).ifPresentOrElse(
|
||||
vanilla -> terraBiomes.forEach(
|
||||
tb -> NMSBiomeInjector.getEntry(biomeRegistry, tb).ifPresentOrElse(
|
||||
terra -> {
|
||||
LOGGER.debug("{} (vanilla for {}): {}",
|
||||
vanilla.unwrapKey().orElseThrow().location(),
|
||||
terra.unwrapKey().orElseThrow().location(),
|
||||
vanilla.tags().toList());
|
||||
vanilla.tags()
|
||||
.forEach(tag -> collect
|
||||
.computeIfAbsent(tag, t -> new ArrayList<>())
|
||||
.add(terra));
|
||||
},
|
||||
() -> LOGGER.error("No such biome: {}", tb))),
|
||||
() -> LOGGER.error("No vanilla biome: {}", vb)));
|
||||
|
||||
biomeRegistry.resetTags();
|
||||
biomeRegistry.bindTags(ImmutableMap.copyOf(collect));
|
||||
|
||||
|
||||
} catch(SecurityException | IllegalArgumentException exception) {
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
|
||||
+26
-26
@@ -15,62 +15,62 @@ import com.dfsek.terra.bukkit.config.VanillaBiomeProperties;
|
||||
|
||||
|
||||
public class NMSBiomeInjector {
|
||||
|
||||
|
||||
public static <T> Optional<Holder<T>> getEntry(Registry<T> registry, ResourceLocation identifier) {
|
||||
return registry.getOptional(identifier)
|
||||
.flatMap(registry::getResourceKey)
|
||||
.flatMap(registry::getHolder);
|
||||
.flatMap(registry::getResourceKey)
|
||||
.flatMap(registry::getHolder);
|
||||
}
|
||||
|
||||
|
||||
public static Biome createBiome(com.dfsek.terra.api.world.biome.Biome biome, Biome vanilla)
|
||||
throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
|
||||
Biome.BiomeBuilder builder = new Biome.BiomeBuilder();
|
||||
|
||||
|
||||
builder
|
||||
.downfall(vanilla.climateSettings.downfall())
|
||||
.temperature(vanilla.getBaseTemperature())
|
||||
.mobSpawnSettings(vanilla.getMobSettings())
|
||||
.generationSettings(vanilla.getGenerationSettings());
|
||||
|
||||
|
||||
.downfall(vanilla.climateSettings.downfall())
|
||||
.temperature(vanilla.getBaseTemperature())
|
||||
.mobSpawnSettings(vanilla.getMobSettings())
|
||||
.generationSettings(vanilla.getGenerationSettings());
|
||||
|
||||
|
||||
BiomeSpecialEffects.Builder effects = new BiomeSpecialEffects.Builder();
|
||||
|
||||
|
||||
effects.grassColorModifier(vanilla.getSpecialEffects().getGrassColorModifier());
|
||||
|
||||
|
||||
VanillaBiomeProperties vanillaBiomeProperties = biome.getContext().get(VanillaBiomeProperties.class);
|
||||
|
||||
|
||||
effects.fogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getFogColor(), vanilla.getFogColor()))
|
||||
|
||||
.waterColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterColor(), vanilla.getWaterColor()))
|
||||
|
||||
.waterFogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterFogColor(), vanilla.getWaterFogColor()))
|
||||
|
||||
.skyColor(Objects.requireNonNullElse(vanillaBiomeProperties.getSkyColor(), vanilla.getSkyColor()));
|
||||
|
||||
|
||||
.waterColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterColor(), vanilla.getWaterColor()))
|
||||
|
||||
.waterFogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterFogColor(), vanilla.getWaterFogColor()))
|
||||
|
||||
.skyColor(Objects.requireNonNullElse(vanillaBiomeProperties.getSkyColor(), vanilla.getSkyColor()));
|
||||
|
||||
if(vanillaBiomeProperties.getFoliageColor() == null) {
|
||||
vanilla.getSpecialEffects().getFoliageColorOverride().ifPresent(effects::foliageColorOverride);
|
||||
} else {
|
||||
effects.foliageColorOverride(vanillaBiomeProperties.getFoliageColor());
|
||||
}
|
||||
|
||||
|
||||
if(vanillaBiomeProperties.getGrassColor() == null) {
|
||||
vanilla.getSpecialEffects().getGrassColorOverride().ifPresent(effects::grassColorOverride);
|
||||
} else {
|
||||
// grass
|
||||
effects.grassColorOverride(vanillaBiomeProperties.getGrassColor());
|
||||
}
|
||||
|
||||
|
||||
vanilla.getAmbientLoop().ifPresent(effects::ambientLoopSound);
|
||||
vanilla.getAmbientAdditions().ifPresent(effects::ambientAdditionsSound);
|
||||
vanilla.getAmbientMood().ifPresent(effects::ambientMoodSound);
|
||||
vanilla.getBackgroundMusic().ifPresent(effects::backgroundMusic);
|
||||
vanilla.getAmbientParticle().ifPresent(effects::ambientParticle);
|
||||
|
||||
|
||||
builder.specialEffects(effects.build());
|
||||
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
||||
public static String createBiomeID(ConfigPack pack, com.dfsek.terra.api.registry.key.RegistryKey biomeID) {
|
||||
return pack.getID()
|
||||
.toLowerCase() + "/" + biomeID.getNamespace().toLowerCase(Locale.ROOT) + "/" + biomeID.getID().toLowerCase(Locale.ROOT);
|
||||
|
||||
+11
-11
@@ -18,32 +18,32 @@ public class NMSBiomeProvider extends BiomeSource {
|
||||
private final BiomeProvider delegate;
|
||||
private final long seed;
|
||||
private final Registry<Biome> biomeRegistry = RegistryFetcher.biomeRegistry();
|
||||
|
||||
|
||||
public NMSBiomeProvider(BiomeProvider delegate, long seed) {
|
||||
super();
|
||||
this.delegate = delegate;
|
||||
this.seed = seed;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Stream<Holder<Biome>> collectPossibleBiomes() {
|
||||
return delegate.stream()
|
||||
.map(biome -> RegistryFetcher.biomeRegistry()
|
||||
.getHolderOrThrow(((BukkitPlatformBiome) biome.getPlatformBiome()).getContext()
|
||||
.get(NMSBiomeInfo.class)
|
||||
.biomeKey()));
|
||||
.map(biome -> RegistryFetcher.biomeRegistry()
|
||||
.getHolderOrThrow(((BukkitPlatformBiome) biome.getPlatformBiome()).getContext()
|
||||
.get(NMSBiomeInfo.class)
|
||||
.biomeKey()));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected @NotNull Codec<? extends BiomeSource> codec() {
|
||||
return BiomeSource.CODEC;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull Holder<Biome> getNoiseBiome(int x, int y, int z, @NotNull Sampler sampler) {
|
||||
return biomeRegistry.getHolderOrThrow(((BukkitPlatformBiome) delegate.getBiome(x << 2, y << 2, z << 2, seed)
|
||||
.getPlatformBiome()).getContext()
|
||||
.get(NMSBiomeInfo.class)
|
||||
.biomeKey());
|
||||
.getPlatformBiome()).getContext()
|
||||
.get(NMSBiomeInfo.class)
|
||||
.biomeKey());
|
||||
}
|
||||
}
|
||||
|
||||
+31
-31
@@ -39,12 +39,12 @@ import com.dfsek.terra.bukkit.world.block.data.BukkitBlockState;
|
||||
public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(NMSChunkGeneratorDelegate.class);
|
||||
private final com.dfsek.terra.api.world.chunk.generation.ChunkGenerator delegate;
|
||||
|
||||
|
||||
private final ChunkGenerator vanilla;
|
||||
private final ConfigPack pack;
|
||||
|
||||
|
||||
private final long seed;
|
||||
|
||||
|
||||
public NMSChunkGeneratorDelegate(ChunkGenerator vanilla, ConfigPack pack, NMSBiomeProvider biomeProvider, long seed) {
|
||||
super(biomeProvider);
|
||||
this.delegate = pack.getGeneratorProvider().newInstance(pack);
|
||||
@@ -52,57 +52,57 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
this.pack = pack;
|
||||
this.seed = seed;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected @NotNull Codec<? extends ChunkGenerator> codec() {
|
||||
return ChunkGenerator.CODEC;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void applyCarvers(@NotNull WorldGenRegion chunkRegion, long seed, @NotNull RandomState noiseConfig, @NotNull BiomeManager world,
|
||||
@NotNull StructureManager structureAccessor, @NotNull ChunkAccess chunk, @NotNull Carving carverStep) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void buildSurface(@NotNull WorldGenRegion region, @NotNull StructureManager structures, @NotNull RandomState noiseConfig,
|
||||
@NotNull ChunkAccess chunk) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void applyBiomeDecoration(@NotNull WorldGenLevel world, @NotNull ChunkAccess chunk,
|
||||
@NotNull StructureManager structureAccessor) {
|
||||
vanilla.applyBiomeDecoration(world, chunk, structureAccessor);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void spawnOriginalMobs(@NotNull WorldGenRegion region) {
|
||||
vanilla.spawnOriginalMobs(region);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getGenDepth() {
|
||||
return vanilla.getGenDepth();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull CompletableFuture<ChunkAccess> fillFromNoise(@NotNull Executor executor, @NotNull Blender blender,
|
||||
@NotNull RandomState noiseConfig,
|
||||
@NotNull StructureManager structureAccessor, @NotNull ChunkAccess chunk) {
|
||||
return vanilla.fillFromNoise(executor, blender, noiseConfig, structureAccessor, chunk)
|
||||
.thenApply(c -> {
|
||||
LevelAccessor level = Reflection.STRUCTURE_MANAGER.getLevel(structureAccessor);
|
||||
BiomeProvider biomeProvider = pack.getBiomeProvider();
|
||||
PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class);
|
||||
if(compatibilityOptions.isBeard()) {
|
||||
beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()),
|
||||
biomeProvider, compatibilityOptions);
|
||||
}
|
||||
return c;
|
||||
});
|
||||
.thenApply(c -> {
|
||||
LevelAccessor level = Reflection.STRUCTURE_MANAGER.getLevel(structureAccessor);
|
||||
BiomeProvider biomeProvider = pack.getBiomeProvider();
|
||||
PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class);
|
||||
if(compatibilityOptions.isBeard()) {
|
||||
beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()),
|
||||
biomeProvider, compatibilityOptions);
|
||||
}
|
||||
return c;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void beard(StructureManager structureAccessor, ChunkAccess chunk, WorldProperties world, BiomeProvider biomeProvider,
|
||||
PreLoadCompatibilityOptions compatibilityOptions) {
|
||||
Beardifier structureWeightSampler = Beardifier.forStructuresInChunk(structureAccessor, chunk.getPos());
|
||||
@@ -117,8 +117,8 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
double noise = structureWeightSampler.compute(new SinglePointContext(x + xi, y, z + zi));
|
||||
if(noise > threshold) {
|
||||
chunk.setBlockState(new BlockPos(x, y, z), ((CraftBlockData) ((BukkitBlockState) delegate
|
||||
.getPalette(x + xi, y, z + zi, world, biomeProvider)
|
||||
.get(depth, x + xi, y, z + zi, world.getSeed())).getHandle()).getState(), false);
|
||||
.getPalette(x + xi, y, z + zi, world, biomeProvider)
|
||||
.get(depth, x + xi, y, z + zi, world.getSeed())).getHandle()).getState(), false);
|
||||
depth++;
|
||||
} else if(noise < airThreshold) {
|
||||
chunk.setBlockState(new BlockPos(x, y, z), Blocks.AIR.defaultBlockState(), false);
|
||||
@@ -129,29 +129,29 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getSeaLevel() {
|
||||
return vanilla.getSeaLevel();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMinY() {
|
||||
return vanilla.getMinY();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getBaseHeight(int x, int z, @NotNull Types heightmap, @NotNull LevelHeightAccessor world, @NotNull RandomState noiseConfig) {
|
||||
WorldProperties properties = new NMSWorldProperties(seed, world);
|
||||
int y = properties.getMaxHeight();
|
||||
BiomeProvider biomeProvider = pack.getBiomeProvider();
|
||||
while(y >= getMinY() && !heightmap.isOpaque().test(
|
||||
((CraftBlockData) delegate.getBlock(properties, x, y - 1, z, biomeProvider).getHandle()).getState())) {
|
||||
((CraftBlockData) delegate.getBlock(properties, x, y - 1, z, biomeProvider).getHandle()).getState())) {
|
||||
y--;
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull NoiseColumn getBaseColumn(int x, int z, @NotNull LevelHeightAccessor world, @NotNull RandomState noiseConfig) {
|
||||
BlockState[] array = new BlockState[world.getHeight()];
|
||||
@@ -159,13 +159,13 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
BiomeProvider biomeProvider = pack.getBiomeProvider();
|
||||
for(int y = properties.getMaxHeight() - 1; y >= properties.getMinHeight(); y--) {
|
||||
array[y - properties.getMinHeight()] = ((CraftBlockData) delegate.getBlock(properties, x, y, z, biomeProvider)
|
||||
.getHandle()).getState();
|
||||
.getHandle()).getState();
|
||||
}
|
||||
return new NoiseColumn(getMinY(), array);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addDebugScreenInfo(@NotNull List<String> text, @NotNull RandomState noiseConfig, @NotNull BlockPos pos) {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+6
-6
@@ -22,7 +22,7 @@ public class NMSInjectListener implements Listener {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(NMSInjectListener.class);
|
||||
private static final Set<World> INJECTED = new HashSet<>();
|
||||
private static final ReentrantLock INJECT_LOCK = new ReentrantLock();
|
||||
|
||||
|
||||
@EventHandler
|
||||
public void onWorldInit(WorldInitEvent event) {
|
||||
if(!INJECTED.contains(event.getWorld()) &&
|
||||
@@ -32,16 +32,16 @@ public class NMSInjectListener implements Listener {
|
||||
LOGGER.info("Preparing to take over the world: {}", event.getWorld().getName());
|
||||
CraftWorld craftWorld = (CraftWorld) event.getWorld();
|
||||
ServerLevel serverWorld = craftWorld.getHandle();
|
||||
|
||||
|
||||
ConfigPack pack = bukkitChunkGeneratorWrapper.getPack();
|
||||
|
||||
|
||||
ChunkGenerator vanilla = serverWorld.getChunkSource().getGenerator();
|
||||
NMSBiomeProvider provider = new NMSBiomeProvider(pack.getBiomeProvider(), craftWorld.getSeed());
|
||||
|
||||
|
||||
serverWorld.getChunkSource().chunkMap.generator = new NMSChunkGeneratorDelegate(vanilla, pack, provider, craftWorld.getSeed());
|
||||
|
||||
|
||||
LOGGER.info("Successfully injected into world.");
|
||||
|
||||
|
||||
INJECT_LOCK.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -8,27 +8,27 @@ import com.dfsek.terra.api.world.info.WorldProperties;
|
||||
public class NMSWorldProperties implements WorldProperties {
|
||||
private final long seed;
|
||||
private final LevelHeightAccessor height;
|
||||
|
||||
|
||||
public NMSWorldProperties(long seed, LevelHeightAccessor height) {
|
||||
this.seed = seed;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object getHandle() {
|
||||
return height;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long getSeed() {
|
||||
return seed;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMaxHeight() {
|
||||
return height.getMaxBuildHeight();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMinHeight() {
|
||||
return height.getMinBuildHeight();
|
||||
|
||||
+10
-10
@@ -16,34 +16,34 @@ import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies;
|
||||
public class Reflection {
|
||||
public static final MappedRegistryProxy MAPPED_REGISTRY;
|
||||
public static final StructureManagerProxy STRUCTURE_MANAGER;
|
||||
|
||||
|
||||
public static final ReferenceProxy REFERENCE;
|
||||
|
||||
|
||||
static {
|
||||
ReflectionRemapper reflectionRemapper = ReflectionRemapper.forReobfMappingsInPaperJar();
|
||||
ReflectionProxyFactory reflectionProxyFactory = ReflectionProxyFactory.create(reflectionRemapper,
|
||||
Reflection.class.getClassLoader());
|
||||
|
||||
Reflection.class.getClassLoader());
|
||||
|
||||
MAPPED_REGISTRY = reflectionProxyFactory.reflectionProxy(MappedRegistryProxy.class);
|
||||
STRUCTURE_MANAGER = reflectionProxyFactory.reflectionProxy(StructureManagerProxy.class);
|
||||
REFERENCE = reflectionProxyFactory.reflectionProxy(ReferenceProxy.class);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Proxies(MappedRegistry.class)
|
||||
public interface MappedRegistryProxy {
|
||||
@FieldSetter("frozen")
|
||||
void setFrozen(MappedRegistry<?> instance, boolean frozen);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Proxies(StructureManager.class)
|
||||
public interface StructureManagerProxy {
|
||||
@FieldGetter("level")
|
||||
LevelAccessor getLevel(StructureManager instance);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Proxies(Holder.Reference.class)
|
||||
public interface ReferenceProxy {
|
||||
@MethodName("bindValue")
|
||||
|
||||
+3
-3
@@ -14,10 +14,10 @@ public class RegistryFetcher {
|
||||
CraftServer craftserver = (CraftServer) Bukkit.getServer();
|
||||
DedicatedServer dedicatedserver = craftserver.getServer();
|
||||
return dedicatedserver
|
||||
.registryAccess()
|
||||
.registryOrThrow(key);
|
||||
.registryAccess()
|
||||
.registryOrThrow(key);
|
||||
}
|
||||
|
||||
|
||||
public static Registry<Biome> biomeRegistry() {
|
||||
return getRegistry(Registries.BIOME);
|
||||
}
|
||||
|
||||
@@ -18,41 +18,41 @@ import com.dfsek.terra.cli.handle.CLIWorldHandle;
|
||||
|
||||
public class CLIPlatform extends AbstractPlatform {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(CLIPlatform.class);
|
||||
|
||||
|
||||
private final CLIWorldHandle worldHandle = new CLIWorldHandle();
|
||||
private final CLIItemHandle itemHandle = new CLIItemHandle();
|
||||
|
||||
|
||||
public CLIPlatform() {
|
||||
LOGGER.info("Root directory: {}", getDataFolder().getAbsoluteFile());
|
||||
load();
|
||||
LOGGER.info("Initialized Terra platform.");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean reload() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull String platformName() {
|
||||
return "CLI";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull WorldHandle getWorldHandle() {
|
||||
return worldHandle;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull File getDataFolder() {
|
||||
return new File("./");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull ItemHandle getItemHandle() {
|
||||
return itemHandle;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void register(TypeRegistry registry) {
|
||||
super.register(registry);
|
||||
|
||||
@@ -14,24 +14,24 @@ import com.dfsek.terra.cli.world.CLIWorld;
|
||||
|
||||
public final class TerraCLI {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(TerraCLI.class);
|
||||
|
||||
|
||||
public static void main(String... args) {
|
||||
LOGGER.info("Starting Terra CLI...");
|
||||
|
||||
|
||||
CLIPlatform platform = new CLIPlatform();
|
||||
platform.getEventManager().callEvent(new PlatformInitializationEvent());
|
||||
|
||||
|
||||
ConfigPack generate = platform.getConfigRegistry().getByID("OVERWORLD").orElseThrow(); // TODO: make this a cli argument
|
||||
|
||||
|
||||
CLIWorld world = new CLIWorld(2, 2, 384, -64, generate);
|
||||
|
||||
|
||||
world.generate();
|
||||
|
||||
|
||||
world.serialize().parallel().forEach(mcaFile -> {
|
||||
Vector2Int pos = mcaFile.getLeft();
|
||||
String name = MCAUtil.createNameFromRegionLocation(pos.getX(), pos.getZ());
|
||||
LOGGER.info("Writing region ({}, {}) to {}", pos.getX(), pos.getZ(), name);
|
||||
|
||||
|
||||
try {
|
||||
MCAUtil.write(mcaFile.getRight(), name);
|
||||
} catch(IOException e) {
|
||||
|
||||
@@ -12,13 +12,13 @@ public class CLIBlockState implements BlockState {
|
||||
private final CLIBlockType type;
|
||||
private final boolean isAir;
|
||||
private final CompoundTag nbt;
|
||||
|
||||
|
||||
public CLIBlockState(String value) {
|
||||
this.value = value;
|
||||
if(value.contains("[")) {
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
}
|
||||
this.isAir = value.startsWith("minecraft:air");
|
||||
this.nbt = new CompoundTag();
|
||||
@@ -30,54 +30,54 @@ public class CLIBlockState implements BlockState {
|
||||
for(String property : props) {
|
||||
String name = property.substring(0, property.indexOf('='));
|
||||
String val = property.substring(property.indexOf('=') + 1);
|
||||
|
||||
|
||||
pTag.putString(name, val);
|
||||
}
|
||||
this.nbt.put("Properties", pTag);
|
||||
} else this.type = new CLIBlockType(value);
|
||||
this.nbt.putString("Name", type.getHandle());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object getHandle() {
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean matches(BlockState other) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public <T extends Comparable<T>> boolean has(Property<T> property) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public <T extends Comparable<T>> T get(Property<T> property) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public <T extends Comparable<T>> BlockState set(Property<T> property, T value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BlockType getBlockType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getAsString(boolean properties) {
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isAir() {
|
||||
return isAir;
|
||||
}
|
||||
|
||||
|
||||
public CompoundTag getNbt() {
|
||||
return nbt;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ public class CLIBlockType implements BlockType {
|
||||
private final boolean solid;
|
||||
private final boolean water;
|
||||
private final Lazy<CLIBlockState> defaultState;
|
||||
|
||||
|
||||
public CLIBlockType(String value) {
|
||||
if(value.contains("[")) throw new IllegalArgumentException("Block Type must not contain properties");
|
||||
this.value = value;
|
||||
@@ -18,22 +18,22 @@ public class CLIBlockType implements BlockType {
|
||||
this.water = value.equals("minecraft:water");
|
||||
this.defaultState = Lazy.lazy(() -> new CLIBlockState(value));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getHandle() {
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BlockState getDefaultState() {
|
||||
return defaultState.value();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isSolid() {
|
||||
return solid;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isWater() {
|
||||
return water;
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
package com.dfsek.terra.cli.handle;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import com.dfsek.terra.api.handle.ItemHandle;
|
||||
import com.dfsek.terra.api.inventory.Item;
|
||||
import com.dfsek.terra.api.inventory.item.Enchantment;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
public class CLIItemHandle implements ItemHandle {
|
||||
@Override
|
||||
public Item createItem(String data) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Enchantment getEnchantment(String id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Set<Enchantment> getEnchantments() {
|
||||
return null;
|
||||
|
||||
@@ -10,21 +10,21 @@ import com.dfsek.terra.cli.block.CLIBlockState;
|
||||
|
||||
public class CLIWorldHandle implements WorldHandle {
|
||||
private static final CLIBlockState AIR = new CLIBlockState("minecraft:air");
|
||||
|
||||
|
||||
public static CLIBlockState getAIR() {
|
||||
return AIR;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull BlockState createBlockState(@NotNull String data) {
|
||||
return new CLIBlockState(data);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull BlockState air() {
|
||||
return AIR;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull EntityType getEntity(@NotNull String id) {
|
||||
return null;
|
||||
|
||||
@@ -44,9 +44,9 @@ public class CLIWorld implements ServerWorld, NBTSerializable<Stream<Pair<Vector
|
||||
private final BiomeProvider biomeProvider;
|
||||
private final ConfigPack pack;
|
||||
private final AtomicInteger amount = new AtomicInteger(0);
|
||||
|
||||
|
||||
private final ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() - 1);
|
||||
|
||||
|
||||
public CLIWorld(int size,
|
||||
long seed,
|
||||
int maxHeight,
|
||||
@@ -59,8 +59,8 @@ public class CLIWorld implements ServerWorld, NBTSerializable<Stream<Pair<Vector
|
||||
this.chunkGenerator = pack.getGeneratorProvider().newInstance(pack);
|
||||
this.biomeProvider = pack.getBiomeProvider();
|
||||
this.pack = pack;
|
||||
|
||||
|
||||
|
||||
|
||||
size += 1;
|
||||
this.regions = new Region[size * size];
|
||||
this.negativeRegions = new Region[size * size];
|
||||
@@ -71,7 +71,7 @@ public class CLIWorld implements ServerWorld, NBTSerializable<Stream<Pair<Vector
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void generate() {
|
||||
int sizeChunks = size * 32;
|
||||
List<Future<?>> futures = new ArrayList<>();
|
||||
@@ -101,7 +101,7 @@ public class CLIWorld implements ServerWorld, NBTSerializable<Stream<Pair<Vector
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for(Future<?> future : futures) {
|
||||
try {
|
||||
future.get();
|
||||
@@ -110,18 +110,18 @@ public class CLIWorld implements ServerWorld, NBTSerializable<Stream<Pair<Vector
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object getHandle() {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BlockState getBlockState(int x, int y, int z) {
|
||||
return getChunkAt(Math.floorDiv(x, 16), Math.floorDiv(z, 16))
|
||||
.getBlock(Math.floorMod(x, 16), y, Math.floorMod(z, 16));
|
||||
.getBlock(Math.floorMod(x, 16), y, Math.floorMod(z, 16));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BlockEntity getBlockEntity(int x, int y, int z) {
|
||||
return new BlockEntity() {
|
||||
@@ -129,176 +129,176 @@ public class CLIWorld implements ServerWorld, NBTSerializable<Stream<Pair<Vector
|
||||
public boolean update(boolean applyPhysics) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Vector3 getPosition() {
|
||||
return Vector3.of(x, y, z);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BlockState getBlockState() {
|
||||
return CLIWorld.this.getBlockState(x, y, z);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object getHandle() {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public CLIChunk getChunkAt(int x, int z) {
|
||||
return getRegion(Math.floorDiv(x, 32), Math.floorDiv(z, 32))
|
||||
.get(Math.floorMod(x, 32), Math.floorMod(z, 32));
|
||||
.get(Math.floorMod(x, 32), Math.floorMod(z, 32));
|
||||
}
|
||||
|
||||
|
||||
public Region getRegion(int x, int z) {
|
||||
int key = x + z * size;
|
||||
if(key >= 0) return regions[key];
|
||||
else return negativeRegions[-key];
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long getSeed() {
|
||||
return seed;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMaxHeight() {
|
||||
return maxHeight;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMinHeight() {
|
||||
return minHeight;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ChunkGenerator getGenerator() {
|
||||
return chunkGenerator;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BiomeProvider getBiomeProvider() {
|
||||
return biomeProvider;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ConfigPack getPack() {
|
||||
return pack;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setBlockState(int x, int y, int z, BlockState data, boolean physics) {
|
||||
getChunkAt(Math.floorDiv(x, 16), Math.floorDiv(z, 16))
|
||||
.setBlock(Math.floorMod(x, 16), y, Math.floorMod(z, 16), data, physics);
|
||||
.setBlock(Math.floorMod(x, 16), y, Math.floorMod(z, 16), data, physics);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Entity spawnEntity(double x, double y, double z, EntityType entityType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Stream<Pair<Vector2Int, MCAFile>> serialize() {
|
||||
return Streams
|
||||
.concat(Arrays.stream(regions), Arrays.stream(negativeRegions))
|
||||
.map(region -> Pair.of(Vector2Int.of(region.getX(), region.getZ()), region.serialize()));
|
||||
.concat(Arrays.stream(regions), Arrays.stream(negativeRegions))
|
||||
.map(region -> Pair.of(Vector2Int.of(region.getX(), region.getZ()), region.serialize()));
|
||||
}
|
||||
|
||||
|
||||
private static final class CLIProtoWorld implements ProtoWorld {
|
||||
private final CLIWorld delegate;
|
||||
private final BiomeProvider biomeProvider;
|
||||
private final int x, z;
|
||||
|
||||
|
||||
private CLIProtoWorld(CLIWorld delegate, BiomeProvider biomeProvider, int x, int z) {
|
||||
this.delegate = delegate;
|
||||
this.biomeProvider = biomeProvider;
|
||||
this.x = x;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object getHandle() {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BlockState getBlockState(int x, int y, int z) {
|
||||
return delegate.getBlockState(x, y, z);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BlockEntity getBlockEntity(int x, int y, int z) {
|
||||
return delegate.getBlockEntity(x, y, z);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long getSeed() {
|
||||
return delegate.seed;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMaxHeight() {
|
||||
return delegate.maxHeight;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMinHeight() {
|
||||
return delegate.minHeight;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ChunkGenerator getGenerator() {
|
||||
return delegate.chunkGenerator;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BiomeProvider getBiomeProvider() {
|
||||
return biomeProvider;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ConfigPack getPack() {
|
||||
return delegate.pack;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setBlockState(int x, int y, int z, BlockState data, boolean physics) {
|
||||
delegate.setBlockState(x, y, z, data, physics);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Entity spawnEntity(double x, double y, double z, EntityType entityType) {
|
||||
return delegate.spawnEntity(x, y, z, entityType);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int centerChunkX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int centerChunkZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ServerWorld getWorld() {
|
||||
return delegate;
|
||||
|
||||
@@ -10,14 +10,14 @@ public class Region implements NBTSerializable<MCAFile> {
|
||||
private final CLIChunk[] chunks;
|
||||
private final int x, z;
|
||||
private final CLIWorld world;
|
||||
|
||||
|
||||
public Region(CLIWorld world, int x, int z) {
|
||||
this.x = x;
|
||||
this.z = z;
|
||||
this.world = world;
|
||||
this.chunks = new CLIChunk[32 * 32];
|
||||
}
|
||||
|
||||
|
||||
public CLIChunk get(int x, int z) {
|
||||
int key = x + z * 32;
|
||||
CLIChunk chunk = chunks[key];
|
||||
@@ -27,7 +27,7 @@ public class Region implements NBTSerializable<MCAFile> {
|
||||
}
|
||||
return chunk;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public MCAFile serialize() {
|
||||
MCAFile mcaFile = new MCAFile(x, z);
|
||||
@@ -46,11 +46,11 @@ public class Region implements NBTSerializable<MCAFile> {
|
||||
}
|
||||
return mcaFile;
|
||||
}
|
||||
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
public int getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ public class CLIChunk implements Chunk, ProtoChunk, NBTSerializable<net.querz.mc
|
||||
private final int minHeight;
|
||||
private final int maxHeight;
|
||||
private final CLIWorld world;
|
||||
|
||||
|
||||
public CLIChunk(int x, int z, CLIWorld world) {
|
||||
this.x = x;
|
||||
this.z = z;
|
||||
@@ -29,39 +29,39 @@ public class CLIChunk implements Chunk, ProtoChunk, NBTSerializable<net.querz.mc
|
||||
this.world = world;
|
||||
this.blocks = new CLIBlockState[16][16][maxHeight - minHeight];
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object getHandle() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, BlockState data, boolean physics) {
|
||||
blocks[x][z][y - minHeight] = (CLIBlockState) data;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull CLIBlockState getBlock(int x, int y, int z) {
|
||||
CLIBlockState blockState = blocks[x][z][y - minHeight];
|
||||
if(blockState == null) return getAIR();
|
||||
return blockState;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ServerWorld getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public net.querz.mca.Chunk serialize() {
|
||||
net.querz.mca.Chunk chunk = net.querz.mca.Chunk.newChunk(2230);
|
||||
@@ -80,7 +80,7 @@ public class CLIChunk implements Chunk, ProtoChunk, NBTSerializable<net.querz.mc
|
||||
chunk.setStatus("features");
|
||||
return chunk;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMaxHeight() {
|
||||
return maxHeight;
|
||||
|
||||
@@ -5,11 +5,11 @@ import com.dfsek.terra.mod.ModPlatform;
|
||||
|
||||
|
||||
public class FabricAddon extends MinecraftAddon {
|
||||
|
||||
|
||||
public FabricAddon(ModPlatform modPlatform) {
|
||||
super(modPlatform);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
return "terra-fabric";
|
||||
|
||||
@@ -17,14 +17,14 @@
|
||||
|
||||
package com.dfsek.terra.fabric;
|
||||
|
||||
import com.dfsek.terra.lifecycle.LifecycleEntryPoint;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
|
||||
import com.dfsek.terra.lifecycle.LifecycleEntryPoint;
|
||||
|
||||
|
||||
public class FabricEntryPoint implements ModInitializer {
|
||||
private static final FabricPlatform TERRA_PLUGIN = new FabricPlatform();
|
||||
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
LifecycleEntryPoint.initialize("Fabric", TERRA_PLUGIN);
|
||||
|
||||
@@ -29,24 +29,24 @@ import com.dfsek.terra.lifecycle.LifecyclePlatform;
|
||||
|
||||
|
||||
public class FabricPlatform extends LifecyclePlatform {
|
||||
|
||||
|
||||
@Override
|
||||
protected Collection<BaseAddon> getPlatformMods() {
|
||||
return FabricLoader.getInstance().getAllMods().stream().flatMap(
|
||||
mod -> parseModData(mod.getMetadata().getId(), mod.getMetadata().getVersion().getFriendlyString(), "fabric")
|
||||
).collect(Collectors.toList());
|
||||
mod -> parseModData(mod.getMetadata().getId(), mod.getMetadata().getVersion().getFriendlyString(), "fabric")
|
||||
).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull String platformName() {
|
||||
return "Fabric";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull File getDataFolder() {
|
||||
return new File(FabricLoader.getInstance().getConfigDir().toFile(), "Terra");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BaseAddon getPlatformAddon() {
|
||||
return new FabricAddon(this);
|
||||
|
||||
@@ -26,7 +26,7 @@ import com.dfsek.terra.api.addon.bootstrap.BootstrapAddonClassLoader;
|
||||
*/
|
||||
public final class AwfulForgeHacks {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(AwfulForgeHacks.class);
|
||||
|
||||
|
||||
/**
|
||||
* Forge tampers with code source to make the *normal* way of getting the current JAR file useless, so this awful hack is
|
||||
* needed.
|
||||
@@ -42,114 +42,114 @@ public final class AwfulForgeHacks {
|
||||
public static JarFile getTerraJar() throws IOException {
|
||||
LOGGER.info("Scanning for Terra JAR...");
|
||||
return Files.walk(Path.of(System.getProperty("user.dir"), "mods"), 1, FileVisitOption.FOLLOW_LINKS)
|
||||
.filter(it -> it.getFileName().toString().endsWith(".jar"))
|
||||
.peek(path -> LOGGER.info("Found mod: {}", path))
|
||||
.map(Path::toFile)
|
||||
.flatMap(path -> {
|
||||
try {
|
||||
return Stream.of(new JarFile(path));
|
||||
} catch(IOException e) {
|
||||
LOGGER.error("Malformed mod JAR: {}: {}", path, e);
|
||||
return Stream.of();
|
||||
}
|
||||
})
|
||||
.filter(jar -> jar
|
||||
.stream()
|
||||
.anyMatch(entry -> entry
|
||||
.getName()
|
||||
.equals(ForgeEntryPoint.class.getName().replace('.', '/') + ".class")))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new IllegalStateException("Could not find Terra JAR"));
|
||||
.filter(it -> it.getFileName().toString().endsWith(".jar"))
|
||||
.peek(path -> LOGGER.info("Found mod: {}", path))
|
||||
.map(Path::toFile)
|
||||
.flatMap(path -> {
|
||||
try {
|
||||
return Stream.of(new JarFile(path));
|
||||
} catch(IOException e) {
|
||||
LOGGER.error("Malformed mod JAR: {}: {}", path, e);
|
||||
return Stream.of();
|
||||
}
|
||||
})
|
||||
.filter(jar -> jar
|
||||
.stream()
|
||||
.anyMatch(entry -> entry
|
||||
.getName()
|
||||
.equals(ForgeEntryPoint.class.getName().replace('.', '/') + ".class")))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new IllegalStateException("Could not find Terra JAR"));
|
||||
}
|
||||
|
||||
|
||||
public static void loadAllTerraClasses() {
|
||||
if(FMLLoader.isProduction()) {
|
||||
try(JarFile jar = getTerraJar()) {
|
||||
jar.stream()
|
||||
.forEach(jarEntry -> {
|
||||
if(jarEntry.getName().startsWith("com/dfsek/terra/forge/mixin")
|
||||
|| jarEntry.getName().startsWith("com/dfsek/terra/mod/mixin")) {
|
||||
return;
|
||||
}
|
||||
if(jarEntry.getName().endsWith(".class")) {
|
||||
String name = jarEntry.getName().replace('/', '.');
|
||||
name = name.substring(0, name.length() - 6);
|
||||
try {
|
||||
Class.forName(name);
|
||||
} catch(ClassNotFoundException | NoClassDefFoundError e) {
|
||||
LOGGER.warn("Failed to load class {}: {}", name, e);
|
||||
}
|
||||
}
|
||||
});
|
||||
.forEach(jarEntry -> {
|
||||
if(jarEntry.getName().startsWith("com/dfsek/terra/forge/mixin")
|
||||
|| jarEntry.getName().startsWith("com/dfsek/terra/mod/mixin")) {
|
||||
return;
|
||||
}
|
||||
if(jarEntry.getName().endsWith(".class")) {
|
||||
String name = jarEntry.getName().replace('/', '.');
|
||||
name = name.substring(0, name.length() - 6);
|
||||
try {
|
||||
Class.forName(name);
|
||||
} catch(ClassNotFoundException | NoClassDefFoundError e) {
|
||||
LOGGER.warn("Failed to load class {}: {}", name, e);
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch(IOException e) {
|
||||
throw new IllegalStateException("Could not load all Terra classes", e);
|
||||
}
|
||||
} else {
|
||||
// Forgive me for what I'm about to do...
|
||||
LOGGER.warn(
|
||||
"I felt a great disturbance in the JVM, as if millions of class not found exceptions suddenly cried out in terror and" +
|
||||
" were suddenly silenced.");
|
||||
"I felt a great disturbance in the JVM, as if millions of class not found exceptions suddenly cried out in terror and" +
|
||||
" were suddenly silenced.");
|
||||
ArrayList<Path> pathsToLoad = new ArrayList<>();
|
||||
|
||||
|
||||
Path terraRoot = Path.of(System.getProperty("user.dir")).getParent().getParent().getParent();
|
||||
Path commonRoot = terraRoot.resolve("common");
|
||||
Path implementationRoot = commonRoot.resolve("implementation");
|
||||
|
||||
|
||||
pathsToLoad.add(commonRoot.resolve("api"));
|
||||
pathsToLoad.add(implementationRoot.resolve("base"));
|
||||
pathsToLoad.add(implementationRoot.resolve("bootstrap-addon-loader"));
|
||||
for(Path path : pathsToLoad) {
|
||||
try {
|
||||
Path target = path.resolve("build").resolve("classes").resolve("java").resolve("main");
|
||||
|
||||
|
||||
BootstrapAddonClassLoader cl = new BootstrapAddonClassLoader(new URL[]{ path.toUri().toURL() });
|
||||
|
||||
|
||||
Classes.Loaders omegaCL = Classes.Loaders.create();
|
||||
Files.walk(target, Integer.MAX_VALUE, FileVisitOption.FOLLOW_LINKS)
|
||||
.filter(it -> it.getFileName().toString().endsWith(".class"))
|
||||
.map(Path::toFile)
|
||||
.forEach(it -> {
|
||||
String name = it.getAbsolutePath().replace(target + "/", "").replace('\\', '.').replace('/', '.');
|
||||
name = name.substring(0, name.length() - 6);
|
||||
LOGGER.info("Loading class {}", name);
|
||||
try {
|
||||
Class.forName(name);
|
||||
} catch(ClassNotFoundException e) {
|
||||
try {
|
||||
String pathToJar = cl.loadClass(name)
|
||||
.getProtectionDomain()
|
||||
.getCodeSource()
|
||||
.getLocation()
|
||||
.toURI()
|
||||
.getPath();
|
||||
|
||||
cl.addURL(new URL("jar:file:" + pathToJar + "!/"));
|
||||
Class newClassLoad = Class.forName(name, true, cl);
|
||||
omegaCL.loadOrDefine(newClassLoad, AbstractPlatform.class.getClassLoader());
|
||||
} catch(ClassNotFoundException | URISyntaxException | IOException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
.filter(it -> it.getFileName().toString().endsWith(".class"))
|
||||
.map(Path::toFile)
|
||||
.forEach(it -> {
|
||||
String name = it.getAbsolutePath().replace(target + "/", "").replace('\\', '.').replace('/', '.');
|
||||
name = name.substring(0, name.length() - 6);
|
||||
LOGGER.info("Loading class {}", name);
|
||||
try {
|
||||
Class.forName(name);
|
||||
} catch(ClassNotFoundException e) {
|
||||
try {
|
||||
String pathToJar = cl.loadClass(name)
|
||||
.getProtectionDomain()
|
||||
.getCodeSource()
|
||||
.getLocation()
|
||||
.toURI()
|
||||
.getPath();
|
||||
|
||||
cl.addURL(new URL("jar:file:" + pathToJar + "!/"));
|
||||
Class newClassLoad = Class.forName(name, true, cl);
|
||||
omegaCL.loadOrDefine(newClassLoad, AbstractPlatform.class.getClassLoader());
|
||||
} catch(ClassNotFoundException | URISyntaxException | IOException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
} catch(IOException e) {
|
||||
throw new IllegalStateException("Could not load all Terra classes", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public enum RegistryStep {
|
||||
BLOCK,
|
||||
BIOME,
|
||||
WORLD_TYPE,
|
||||
DONE
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static class RegistrySanityCheck {
|
||||
private final AtomicReference<RegistryStep> step = new AtomicReference<>(RegistryStep.BLOCK);
|
||||
|
||||
|
||||
public <T> void progress(RegistryStep expected, Runnable action) {
|
||||
step.getAndUpdate(s -> {
|
||||
if(s != expected) {
|
||||
|
||||
@@ -5,11 +5,11 @@ import com.dfsek.terra.mod.ModPlatform;
|
||||
|
||||
|
||||
public class ForgeAddon extends MinecraftAddon {
|
||||
|
||||
|
||||
public ForgeAddon(ModPlatform modPlatform) {
|
||||
super(modPlatform);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
return "terra-forge";
|
||||
|
||||
@@ -51,32 +51,32 @@ public class ForgeEntryPoint {
|
||||
TERRA_PLUGIN = new ForgePlatform();
|
||||
}
|
||||
private final RegistrySanityCheck sanityCheck = new RegistrySanityCheck();
|
||||
|
||||
|
||||
public ForgeEntryPoint() {
|
||||
IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
|
||||
modEventBus.register(this);
|
||||
}
|
||||
|
||||
|
||||
public static ForgePlatform getPlatform() {
|
||||
return TERRA_PLUGIN;
|
||||
}
|
||||
|
||||
|
||||
public static void initialize(RegisterHelper<Biome> helper) {
|
||||
getPlatform().getEventManager().callEvent(
|
||||
new PlatformInitializationEvent());
|
||||
new PlatformInitializationEvent());
|
||||
BiomeUtil.registerBiomes(helper);
|
||||
}
|
||||
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.LOWEST)
|
||||
public void registerBiomes(RegisterEvent event) {
|
||||
event.register(Keys.BLOCKS, helper -> sanityCheck.progress(RegistryStep.BLOCK, () -> logger.debug("Block registration detected.")));
|
||||
event.register(Keys.BIOMES, helper -> sanityCheck.progress(RegistryStep.BIOME, () -> initialize(helper)));
|
||||
event.register(RegistryKeys.WORLD_PRESET,
|
||||
helper -> sanityCheck.progress(RegistryStep.WORLD_TYPE, () -> TERRA_PLUGIN.registerWorldTypes(helper::register)));
|
||||
|
||||
|
||||
helper -> sanityCheck.progress(RegistryStep.WORLD_TYPE, () -> TERRA_PLUGIN.registerWorldTypes(helper::register)));
|
||||
|
||||
|
||||
event.register(RegistryKeys.CHUNK_GENERATOR,
|
||||
helper -> helper.register(new Identifier("terra:terra"), Codecs.MINECRAFT_CHUNK_GENERATOR_WRAPPER));
|
||||
helper -> helper.register(new Identifier("terra:terra"), Codecs.MINECRAFT_CHUNK_GENERATOR_WRAPPER));
|
||||
event.register(RegistryKeys.BIOME_SOURCE, helper -> helper.register(new Identifier("terra:terra"), Codecs.TERRA_BIOME_SOURCE));
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user