NeoForged for 1.20.4!
This commit is contained in:
+10
-1
@@ -75,6 +75,12 @@ forgix {
|
||||
forge {
|
||||
jarLocation = "build/libs/DistantHorizons-forge-${rootProject.versionStr}.jar"
|
||||
}
|
||||
|
||||
if (findProject(":neoforged"))
|
||||
custom {
|
||||
projectName = "neoforged"
|
||||
jarLocation = "build/libs/DistantHorizons-neoforged-${rootProject.versionStr}.jar"
|
||||
}
|
||||
|
||||
if (findProject(":fabric"))
|
||||
fabric {
|
||||
@@ -105,7 +111,10 @@ subprojects { p ->
|
||||
// apply plugin: "org.spongepowered.gradle.vanilla" // Provides minecraft libraries
|
||||
|
||||
// Apply forge's loom
|
||||
if (findProject(":forge") && p == project(":forge"))
|
||||
if (
|
||||
(findProject(":forge") && p == project(":forge")) ||
|
||||
(findProject(":neoforged") && p == project(":neoforged"))
|
||||
)
|
||||
apply plugin: "dev.architectury.loom"
|
||||
|
||||
|
||||
|
||||
+1
-1
Submodule coreSubProjects updated: fa12443cb1...1b8ee5cd48
-3
@@ -48,9 +48,6 @@ public abstract class MixinDynamicTexture implements ILightTextureMarker
|
||||
private boolean isLightTexture = false;
|
||||
|
||||
@Shadow
|
||||
#if MC_VER >= MC_1_20_4
|
||||
(remap = false)
|
||||
#endif
|
||||
@Final
|
||||
private NativeImage pixels;
|
||||
|
||||
|
||||
-3
@@ -74,9 +74,6 @@ import org.lwjgl.opengl.GL15;
|
||||
public class MixinLevelRenderer
|
||||
{
|
||||
@Shadow
|
||||
#if MC_VER >= MC_1_20_4
|
||||
(remap = false)
|
||||
#endif
|
||||
private ClientLevel level;
|
||||
@Unique
|
||||
private static float previousPartialTicks = 0;
|
||||
|
||||
-3
@@ -36,9 +36,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
public class MixinLightTexture
|
||||
{
|
||||
@Shadow
|
||||
#if MC_VER >= MC_1_20_4
|
||||
(remap = false)
|
||||
#endif
|
||||
@Final
|
||||
private DynamicTexture lightTexture;
|
||||
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
plugins {
|
||||
// Note: This is only needed for multi-loader projects
|
||||
// The main architectury loom version is set at the start of the root build.gradle
|
||||
id "architectury-plugin" version "3.4-SNAPSHOT"
|
||||
}
|
||||
|
||||
sourceCompatibility = targetCompatibility = JavaVersion.VERSION_17
|
||||
|
||||
architectury {
|
||||
platformSetupLoomIde()
|
||||
forge()
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
name "Neoforged"
|
||||
url "https://maven.neoforged.net/releases/"
|
||||
}
|
||||
}
|
||||
|
||||
//loom {
|
||||
// forge {
|
||||
// convertAccessWideners.set(true)
|
||||
// extraAccessWideners.add("lod.accesswidener")
|
||||
// mixinConfigs("DistantHorizons.mixins.json")
|
||||
// }
|
||||
//}
|
||||
|
||||
loom {
|
||||
silentMojangMappingsLicense() // Shut the licencing warning
|
||||
accessWidenerPath = project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener")
|
||||
|
||||
neoForge {
|
||||
// Access wideners are now defined in the `remapJar.atAccessWideners`
|
||||
// convertAccessWideners = true
|
||||
// extraAccessWideners.add loom.accessWidenerPath.get().asFile.name
|
||||
|
||||
// Mixins are now defined in the `mods.toml`
|
||||
// mixinConfigs = [
|
||||
// "DistantHorizons.mixins.json"
|
||||
// ]
|
||||
}
|
||||
mixin {
|
||||
useLegacyMixinAp = true
|
||||
|
||||
// Mixins are now defined in the `mods.toml`
|
||||
// mixinConfigs = [
|
||||
// "DistantHorizons.mixins.json"
|
||||
// ]
|
||||
}
|
||||
|
||||
// "runs" isn't required, but when we do need it then it can be useful
|
||||
runs {
|
||||
client {
|
||||
client()
|
||||
setConfigName("Neoforged Client")
|
||||
ideConfigGenerated(true)
|
||||
runDir("../run")
|
||||
// vmArgs("-XX:-OmitStackTraceInFastThrow", minecraftMemoryJavaArg)
|
||||
}
|
||||
server {
|
||||
server()
|
||||
setConfigName("Neoforged Server")
|
||||
ideConfigGenerated(true)
|
||||
runDir("../run")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
remapJar {
|
||||
inputFile = shadowJar.archiveFile
|
||||
dependsOn shadowJar
|
||||
// classifier null
|
||||
|
||||
atAccessWideners.add("distanthorizons.accesswidener")
|
||||
}
|
||||
|
||||
|
||||
def addMod(path, enabled) {
|
||||
if (enabled == "2")
|
||||
dependencies { implementation(path) }
|
||||
else if (enabled == "1")
|
||||
dependencies { modCompileOnly(path) }
|
||||
}
|
||||
dependencies {
|
||||
minecraft "com.mojang:minecraft:${rootProject.minecraft_version}"
|
||||
mappings loom.layered() {
|
||||
// Mojmap mappings
|
||||
officialMojangMappings()
|
||||
// Parchment mappings (it adds parameter mappings & javadoc)
|
||||
parchment("org.parchmentmc.data:parchment-${rootProject.parchment_version}@zip")
|
||||
|
||||
// Architectury hackishness
|
||||
// it.mappings "dev.architectury:yarn-mappings-patch-forge:${rootProject.mappings_patch}"
|
||||
}
|
||||
|
||||
// Neoforged
|
||||
neoForge "net.neoforged:neoforge:${rootProject.neoforged_version}"
|
||||
|
||||
// Architectury API
|
||||
// if (minecraft_version == "1.16.5") {
|
||||
// implementation("me.shedaniel:architectury-forge:${rootProject.architectury_version}")
|
||||
// } else {
|
||||
// implementation("dev.architectury:architectury-forge:${rootProject.architectury_version}")
|
||||
// }
|
||||
|
||||
// Starlight
|
||||
addMod("curse.maven:starlight-forge-526854:${rootProject.starlight_version_forge}", rootProject.enable_starlight_forge)
|
||||
// annotationProcessor "org.spongepowered:mixin:0.8.4:processor"
|
||||
|
||||
addMod("curse.maven:TerraForged-363820:${rootProject.terraforged_version}", rootProject.enable_terraforged)
|
||||
|
||||
addMod("curse.maven:TerraFirmaCraft-302973:4616004", rootProject.enable_terrafirmacraft)
|
||||
|
||||
// if (System.getProperty("idea.sync.active") != "true") {
|
||||
// annotationProcessor "org.spongepowered:mixin:0.8.4:processor"
|
||||
// }
|
||||
}
|
||||
|
||||
task deleteResources(type: Delete) {
|
||||
delete file("build/resources/main")
|
||||
}
|
||||
|
||||
tasks.register('copyAllResources') {
|
||||
dependsOn(copyCoreResources)
|
||||
dependsOn(copyCommonLoaderResources)
|
||||
}
|
||||
|
||||
processResources {
|
||||
dependsOn(tasks.named('copyAllResources'))
|
||||
}
|
||||
|
||||
tasks.named('runClient') {
|
||||
dependsOn(tasks.named('copyAllResources'))
|
||||
finalizedBy(deleteResources)
|
||||
}
|
||||
|
||||
|
||||
sourcesJar {
|
||||
def commonSources = project(":common").sourcesJar
|
||||
dependsOn commonSources
|
||||
from commonSources.archiveFile.map { zipTree(it) }
|
||||
}
|
||||
|
||||
//components.java {
|
||||
// withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) {
|
||||
// skip()
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1 @@
|
||||
loom.platform=neoForge
|
||||
@@ -0,0 +1,285 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.forge;
|
||||
|
||||
import com.seibel.distanthorizons.common.util.ProxyUtil;
|
||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
|
||||
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
//import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.neoforged.neoforge.client.event.RenderLevelStageEvent;
|
||||
import net.neoforged.neoforge.event.level.ChunkEvent;
|
||||
import net.neoforged.neoforge.event.level.LevelEvent;
|
||||
|
||||
import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
|
||||
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
|
||||
//import net.neoforged.network.NetworkRegistry;
|
||||
//import net.neoforged.network.simple.SimpleChannel;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.neoforged.neoforge.client.event.InputEvent;
|
||||
import net.neoforged.neoforge.event.TickEvent;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
/**
|
||||
* This handles all events sent to the client,
|
||||
* and is the starting point for most of the mod.
|
||||
*
|
||||
* @author James_Seibel
|
||||
* @version 2023-7-27
|
||||
*/
|
||||
public class ForgeClientProxy
|
||||
{
|
||||
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||
|
||||
// private static SimpleChannel multiversePluginChannel;
|
||||
|
||||
|
||||
private static LevelAccessor GetEventLevel(LevelEvent e) { return e.getLevel(); }
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// tick events //
|
||||
//=============//
|
||||
|
||||
@SubscribeEvent
|
||||
public void clientTickEvent(TickEvent.ClientTickEvent event)
|
||||
{
|
||||
if (event.phase == TickEvent.Phase.START)
|
||||
{
|
||||
ClientApi.INSTANCE.clientTickEvent();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==============//
|
||||
// world events //
|
||||
//==============//
|
||||
|
||||
@SubscribeEvent
|
||||
public void clientLevelLoadEvent(LevelEvent.Load event)
|
||||
{
|
||||
LOGGER.info("level load");
|
||||
|
||||
LevelAccessor level = event.getLevel();
|
||||
if (!(level instanceof ClientLevel))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ClientLevel clientLevel = (ClientLevel) level;
|
||||
IClientLevelWrapper clientLevelWrapper = ClientLevelWrapper.getWrapper(clientLevel);
|
||||
// TODO this causes a crash due to level being set to null somewhere
|
||||
ClientApi.INSTANCE.clientLevelLoadEvent(clientLevelWrapper);
|
||||
}
|
||||
@SubscribeEvent
|
||||
public void clientLevelUnloadEvent(LevelEvent.Load event)
|
||||
{
|
||||
LOGGER.info("level unload");
|
||||
|
||||
LevelAccessor level = event.getLevel();
|
||||
if (!(level instanceof ClientLevel))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ClientLevel clientLevel = (ClientLevel) level;
|
||||
IClientLevelWrapper clientLevelWrapper = ClientLevelWrapper.getWrapper(clientLevel);
|
||||
ClientApi.INSTANCE.clientLevelUnloadEvent(clientLevelWrapper);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==============//
|
||||
// chunk events //
|
||||
//==============//
|
||||
|
||||
@SubscribeEvent
|
||||
public void rightClickBlockEvent(PlayerInteractEvent.RightClickBlock event)
|
||||
{
|
||||
LOGGER.trace("interact or block place event at blockPos: " + event.getPos());
|
||||
|
||||
LevelAccessor level = event.getLevel();
|
||||
|
||||
ChunkAccess chunk = level.getChunk(event.getPos());
|
||||
this.onBlockChangeEvent(level, chunk);
|
||||
}
|
||||
@SubscribeEvent
|
||||
public void leftClickBlockEvent(PlayerInteractEvent.LeftClickBlock event)
|
||||
{
|
||||
LOGGER.trace("break or block attack at blockPos: " + event.getPos());
|
||||
|
||||
LevelAccessor level = event.getLevel();
|
||||
|
||||
ChunkAccess chunk = level.getChunk(event.getPos());
|
||||
this.onBlockChangeEvent(level, chunk);
|
||||
}
|
||||
private void onBlockChangeEvent(LevelAccessor level, ChunkAccess chunk)
|
||||
{
|
||||
ILevelWrapper wrappedLevel = ProxyUtil.getLevelWrapper(level);
|
||||
SharedApi.INSTANCE.chunkBlockChangedEvent(new ChunkWrapper(chunk, level, wrappedLevel), wrappedLevel);
|
||||
}
|
||||
|
||||
|
||||
@SubscribeEvent
|
||||
public void clientChunkLoadEvent(ChunkEvent.Load event)
|
||||
{
|
||||
ILevelWrapper wrappedLevel = ProxyUtil.getLevelWrapper(GetEventLevel(event));
|
||||
IChunkWrapper chunk = new ChunkWrapper(event.getChunk(), GetEventLevel(event), wrappedLevel);
|
||||
SharedApi.INSTANCE.chunkLoadEvent(chunk, wrappedLevel);
|
||||
}
|
||||
@SubscribeEvent
|
||||
public void clientChunkUnloadEvent(ChunkEvent.Unload event)
|
||||
{
|
||||
ILevelWrapper wrappedLevel = ProxyUtil.getLevelWrapper(GetEventLevel(event));
|
||||
IChunkWrapper chunk = new ChunkWrapper(event.getChunk(), GetEventLevel(event), wrappedLevel);
|
||||
SharedApi.INSTANCE.chunkUnloadEvent(chunk, wrappedLevel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==============//
|
||||
// key bindings //
|
||||
//==============//
|
||||
|
||||
@SubscribeEvent
|
||||
public void registerKeyBindings(InputEvent.Key event)
|
||||
{
|
||||
if (Minecraft.getInstance().player == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (event.getAction() != GLFW.GLFW_PRESS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ClientApi.INSTANCE.keyPressedEvent(event.getKey());
|
||||
}
|
||||
|
||||
|
||||
|
||||
//============//
|
||||
// networking //
|
||||
//============//
|
||||
|
||||
/** @param event this is just to ensure the event is called at the right time, if it is called outside the {@link FMLClientSetupEvent} event, the binding may fail */
|
||||
public static void setupNetworkingListeners(FMLClientSetupEvent event)
|
||||
{
|
||||
// multiversePluginChannel = NetworkRegistry.newSimpleChannel(
|
||||
// new ResourceLocation(ModInfo.NETWORKING_RESOURCE_NAMESPACE, ModInfo.MULTIVERSE_PLUGIN_NAMESPACE),
|
||||
// // network protocol version
|
||||
// () -> ModInfo.MULTIVERSE_PLUGIN_PROTOCOL_VERSION +"",
|
||||
// // client accepted versions
|
||||
// ForgeClientProxy::isReceivedProtocolVersionAcceptable,
|
||||
// // server accepted versions
|
||||
// ForgeClientProxy::isReceivedProtocolVersionAcceptable
|
||||
// );
|
||||
//
|
||||
// multiversePluginChannel.registerMessage(0/*should be incremented for each simple channel we listen to*/, ByteBuf.class,
|
||||
// // encoder
|
||||
// (pack, friendlyByteBuf) -> { },
|
||||
// // decoder
|
||||
// (friendlyByteBuf) -> friendlyByteBuf.asByteBuf(),
|
||||
// // message consumer
|
||||
// (nettyByteBuf, contextRef) ->
|
||||
// {
|
||||
// ClientApi.INSTANCE.serverMessageReceived(nettyByteBuf);
|
||||
// contextRef.get().setPacketHandled(true);
|
||||
// }
|
||||
// );
|
||||
}
|
||||
|
||||
public static boolean isReceivedProtocolVersionAcceptable(String versionString)
|
||||
{
|
||||
if (versionString.toLowerCase().contains("allowvanilla"))
|
||||
{
|
||||
// allow using networking on vanilla servers
|
||||
return true;
|
||||
}
|
||||
else if (versionString.toLowerCase().contains("absent"))
|
||||
{
|
||||
// allow using networking even if DH isn't installed on the server
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// DH is installed on the server, check if the version is valid to use
|
||||
try
|
||||
{
|
||||
int version = Integer.parseInt(versionString);
|
||||
return ModInfo.MULTIVERSE_PLUGIN_PROTOCOL_VERSION == version;
|
||||
}
|
||||
catch (NumberFormatException ignored)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//===========//
|
||||
// rendering //
|
||||
//===========//
|
||||
|
||||
@SubscribeEvent
|
||||
public void afterLevelRenderEvent(RenderLevelStageEvent event)
|
||||
{
|
||||
if (event.getStage() == RenderLevelStageEvent.Stage.AFTER_LEVEL)
|
||||
{
|
||||
try
|
||||
{
|
||||
// should generally only need to be set once per game session
|
||||
// allows DH to render directly to Optifine's level frame buffer,
|
||||
// allowing better shader support
|
||||
MinecraftRenderWrapper.INSTANCE.finalLevelFrameBufferId = GL32.glGetInteger(GL32.GL_FRAMEBUFFER_BINDING);
|
||||
}
|
||||
catch (Exception | Error e)
|
||||
{
|
||||
LOGGER.error("Unexpected error in afterLevelRenderEvent: "+e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.forge;
|
||||
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiAfterDhInitEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeDhInitEvent;
|
||||
import com.seibel.distanthorizons.common.LodCommonMain;
|
||||
import com.seibel.distanthorizons.common.forge.LodForgeMethodCaller;
|
||||
import com.seibel.distanthorizons.common.wrappers.DependencySetup;
|
||||
import com.seibel.distanthorizons.common.wrappers.gui.GetConfigScreen;
|
||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftClientWrapper;
|
||||
import com.seibel.distanthorizons.core.jar.ModJarInfo;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.AbstractOptifineAccessor;
|
||||
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
|
||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IOptifineAccessor;
|
||||
import com.seibel.distanthorizons.forge.wrappers.ForgeDependencySetup;
|
||||
|
||||
import com.seibel.distanthorizons.forge.wrappers.modAccessor.OptifineAccessor;
|
||||
|
||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.ColorResolver;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.neoforged.fml.ModLoadingContext;
|
||||
import net.neoforged.fml.common.Mod;
|
||||
import net.neoforged.fml.event.lifecycle.*;
|
||||
import net.neoforged.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
import net.neoforged.neoforge.client.ConfigScreenHandler;
|
||||
|
||||
import net.neoforged.neoforge.common.NeoForge;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.neoforged.neoforge.client.model.data.ModelData;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Initialize and setup the Mod. <br>
|
||||
* If you are looking for the real start of the mod
|
||||
* check out the ClientProxy.
|
||||
*
|
||||
* @author coolGi
|
||||
* @author Ran
|
||||
* @author James Seibel
|
||||
* @version 8-15-2022
|
||||
*/
|
||||
@Mod(ModInfo.ID)
|
||||
public class ForgeMain implements LodForgeMethodCaller
|
||||
{
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger(MethodHandles.lookup().lookupClass().getSimpleName());
|
||||
public static ForgeClientProxy client_proxy = null;
|
||||
public static ForgeServerProxy server_proxy = null;
|
||||
|
||||
public ForgeMain()
|
||||
{
|
||||
DependencySetup.createClientBindings();
|
||||
|
||||
// initDedicated(null);
|
||||
// initDedicated(null);
|
||||
// Register the mod initializer (Actual event registration is done in the different proxies)
|
||||
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::initClient);
|
||||
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::initDedicated);
|
||||
}
|
||||
|
||||
private void initClient(final FMLClientSetupEvent event)
|
||||
{
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeDhInitEvent.class, null);
|
||||
|
||||
LOGGER.info("Initializing Mod");
|
||||
LodCommonMain.startup(this);
|
||||
ForgeDependencySetup.createInitialBindings();
|
||||
LOGGER.info(ModInfo.READABLE_NAME + ", Version: " + ModInfo.VERSION);
|
||||
|
||||
// Print git info (Useful for dev builds)
|
||||
LOGGER.info("DH Branch: " + ModJarInfo.Git_Branch);
|
||||
LOGGER.info("DH Commit: " + ModJarInfo.Git_Commit);
|
||||
LOGGER.info("DH Jar Build Source: " + ModJarInfo.Build_Source);
|
||||
|
||||
client_proxy = new ForgeClientProxy();
|
||||
NeoForge.EVENT_BUS.register(client_proxy);
|
||||
server_proxy = new ForgeServerProxy(false);
|
||||
NeoForge.EVENT_BUS.register(server_proxy);
|
||||
|
||||
if (AbstractOptifineAccessor.optifinePresent())
|
||||
{
|
||||
ModAccessorInjector.INSTANCE.bind(IOptifineAccessor.class, new OptifineAccessor());
|
||||
}
|
||||
|
||||
ModLoadingContext.get().registerExtensionPoint(ConfigScreenHandler.ConfigScreenFactory.class,
|
||||
() -> new ConfigScreenHandler.ConfigScreenFactory((client, parent) -> GetConfigScreen.getScreen(parent)));
|
||||
|
||||
ForgeClientProxy.setupNetworkingListeners(event);
|
||||
|
||||
LOGGER.info(ModInfo.READABLE_NAME + " Initialized");
|
||||
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterDhInitEvent.class, null);
|
||||
|
||||
// Init config
|
||||
// The reason im initialising in this rather than the post init process is cus im using this for the auto updater
|
||||
LodCommonMain.initConfig();
|
||||
}
|
||||
|
||||
private void initDedicated(final FMLDedicatedServerSetupEvent event)
|
||||
{
|
||||
// DependencySetup.createServerBindings();
|
||||
// initCommon();
|
||||
|
||||
// server_proxy = new ForgeServerProxy(true);
|
||||
// MinecraftForge.EVENT_BUS.register(server_proxy);
|
||||
//
|
||||
postInitCommon();
|
||||
}
|
||||
|
||||
private void postInitCommon()
|
||||
{
|
||||
LOGGER.info("Post-Initializing Mod");
|
||||
ForgeDependencySetup.runDelayedSetup();
|
||||
|
||||
LOGGER.info("Mod Post-Initialized");
|
||||
}
|
||||
|
||||
private final ModelData modelData = ModelData.EMPTY;
|
||||
|
||||
@Override
|
||||
public List<BakedQuad> getQuads(MinecraftClientWrapper mc, Block block, BlockState blockState, Direction direction, RandomSource random)
|
||||
{
|
||||
return mc.getModelManager().getBlockModelShaper().getBlockModel(block.defaultBlockState()).getQuads(blockState, direction, random, modelData, RenderType.solid() );
|
||||
}
|
||||
|
||||
@Override //TODO: Check this if its still needed
|
||||
public int colorResolverGetColor(ColorResolver resolver, Biome biome, double x, double z)
|
||||
{
|
||||
return resolver.getColor(biome, x, z);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
package com.seibel.distanthorizons.forge;
|
||||
|
||||
import com.seibel.distanthorizons.common.util.ProxyUtil;
|
||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
||||
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
|
||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
||||
import com.seibel.distanthorizons.core.api.internal.ServerApi;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.neoforged.neoforge.event.TickEvent;
|
||||
import net.neoforged.neoforge.event.level.ChunkEvent;
|
||||
import net.neoforged.neoforge.event.level.LevelEvent;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
|
||||
import net.neoforged.neoforge.event.server.ServerAboutToStartEvent;
|
||||
import net.neoforged.neoforge.event.server.ServerStoppingEvent;
|
||||
|
||||
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ForgeServerProxy
|
||||
{
|
||||
private static LevelAccessor GetEventLevel(LevelEvent e) { return e.getLevel(); }
|
||||
|
||||
private final ServerApi serverApi = ServerApi.INSTANCE;
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||
private final boolean isDedicated;
|
||||
public static Supplier<Boolean> isGenerationThreadChecker = null;
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
|
||||
public ForgeServerProxy(boolean isDedicated)
|
||||
{
|
||||
this.isDedicated = isDedicated;
|
||||
isGenerationThreadChecker = BatchGenerationEnvironment::isCurrentThreadDistantGeneratorThread;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//========//
|
||||
// events //
|
||||
//========//
|
||||
|
||||
// ServerTickEvent (at end)
|
||||
@SubscribeEvent
|
||||
public void serverTickEvent(TickEvent.ServerTickEvent event)
|
||||
{
|
||||
if (event.phase == TickEvent.Phase.END)
|
||||
{
|
||||
this.serverApi.serverTickEvent();
|
||||
}
|
||||
}
|
||||
|
||||
// ServerWorldLoadEvent
|
||||
@SubscribeEvent
|
||||
public void dedicatedWorldLoadEvent(ServerAboutToStartEvent event)
|
||||
{
|
||||
this.serverApi.serverLoadEvent(this.isDedicated);
|
||||
}
|
||||
|
||||
// ServerWorldUnloadEvent
|
||||
@SubscribeEvent
|
||||
public void serverWorldUnloadEvent(ServerStoppingEvent event)
|
||||
{
|
||||
this.serverApi.serverUnloadEvent();
|
||||
}
|
||||
|
||||
// ServerLevelLoadEvent
|
||||
@SubscribeEvent
|
||||
public void serverLevelLoadEvent(LevelEvent.Load event)
|
||||
{
|
||||
if (GetEventLevel(event) instanceof ServerLevel)
|
||||
{
|
||||
this.serverApi.serverLevelLoadEvent(this.getServerLevelWrapper((ServerLevel) GetEventLevel(event)));
|
||||
}
|
||||
}
|
||||
|
||||
// ServerLevelUnloadEvent
|
||||
@SubscribeEvent
|
||||
public void serverLevelUnloadEvent(LevelEvent.Unload event)
|
||||
{
|
||||
if (GetEventLevel(event) instanceof ServerLevel)
|
||||
{
|
||||
this.serverApi.serverLevelUnloadEvent(this.getServerLevelWrapper((ServerLevel) GetEventLevel(event)));
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void serverChunkLoadEvent(ChunkEvent.Load event)
|
||||
{
|
||||
ILevelWrapper levelWrapper = ProxyUtil.getLevelWrapper(GetEventLevel(event));
|
||||
|
||||
IChunkWrapper chunk = new ChunkWrapper(event.getChunk(), GetEventLevel(event), levelWrapper);
|
||||
this.serverApi.serverChunkLoadEvent(chunk, levelWrapper);
|
||||
}
|
||||
@SubscribeEvent
|
||||
public void serverChunkSaveEvent(ChunkEvent.Unload event)
|
||||
{
|
||||
ILevelWrapper levelWrapper = ProxyUtil.getLevelWrapper(GetEventLevel(event));
|
||||
|
||||
IChunkWrapper chunk = new ChunkWrapper(event.getChunk(), GetEventLevel(event), levelWrapper);
|
||||
this.serverApi.serverChunkSaveEvent(chunk, levelWrapper);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
// helper methods //
|
||||
//================//
|
||||
|
||||
private static ServerLevelWrapper getServerLevelWrapper(ServerLevel level) { return ServerLevelWrapper.getWrapper(level); }
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package com.seibel.distanthorizons.forge.mixins;
|
||||
|
||||
import net.neoforged.fml.ModList;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
|
||||
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author coolGi
|
||||
* @author cortex
|
||||
*/
|
||||
public class ForgeMixinPlugin implements IMixinConfigPlugin
|
||||
{
|
||||
|
||||
@Override
|
||||
public boolean shouldApplyMixin(String targetClassName, String mixinClassName)
|
||||
{
|
||||
if (mixinClassName.contains(".mods."))
|
||||
{ // If the mixin wants to go into a mod then we check if that mod is loaded or not
|
||||
return ModList.get().isLoaded(
|
||||
mixinClassName
|
||||
// What these 2 regex's do is get the mod name that we are checking out of the mixinClassName
|
||||
// Eg. "com.seibel.distanthorizons.mixins.mods.sodium.MixinSodiumChunkRenderer" turns into "sodium"
|
||||
.replaceAll("^.*mods.", "") // Replaces everything before the mods
|
||||
.replaceAll("\\..*$", "") // Replaces everything after the mod name
|
||||
);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onLoad(String mixinPackage)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRefMapperConfig()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMixins()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package com.seibel.distanthorizons.forge.mixins.client;
|
||||
|
||||
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||
import net.minecraft.client.multiplayer.ClientPacketListener;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(ClientPacketListener.class)
|
||||
public class MixinClientPacketListener
|
||||
{
|
||||
// TODO update fabric version as well
|
||||
|
||||
@Inject(method = "handleLogin", at = @At("RETURN"))
|
||||
void onHandleLoginEnd(CallbackInfo ci) { ClientApi.INSTANCE.onClientOnlyConnected(); }
|
||||
|
||||
#if MC_VER < MC_1_19_4
|
||||
@Inject(method = "cleanup", at = @At("HEAD"))
|
||||
#else
|
||||
@Inject(method = "close", at = @At("HEAD"))
|
||||
#endif
|
||||
void onCleanupStart(CallbackInfo ci)
|
||||
{
|
||||
ClientApi.INSTANCE.onClientOnlyDisconnected();
|
||||
}
|
||||
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package com.seibel.distanthorizons.forge.mixins.client;
|
||||
|
||||
import com.seibel.distanthorizons.core.logging.f3.F3Screen;
|
||||
import net.minecraft.client.gui.components.DebugScreenOverlay;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(DebugScreenOverlay.class)
|
||||
public class MixinDebugScreenOverlay
|
||||
{
|
||||
|
||||
@Inject(method = "getSystemInformation", at = @At("RETURN"))
|
||||
private void addCustomF3(CallbackInfoReturnable<List<String>> cir)
|
||||
{
|
||||
List<String> messages = cir.getReturnValue();
|
||||
F3Screen.addStringToDisplay(messages);
|
||||
}
|
||||
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.forge.mixins.client;
|
||||
|
||||
|
||||
import com.mojang.blaze3d.platform.NativeImage;
|
||||
|
||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||
import com.seibel.distanthorizons.common.util.ILightTextureMarker;
|
||||
|
||||
import net.minecraft.client.renderer.texture.DynamicTexture;
|
||||
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@Mixin(DynamicTexture.class)
|
||||
public abstract class MixinDynamicTexture implements ILightTextureMarker
|
||||
{
|
||||
/** Used to prevent accidentally using other dynamic textures as a lightmap */
|
||||
@Unique
|
||||
private boolean isLightTexture = false;
|
||||
|
||||
@Shadow
|
||||
#if MC_VER >= MC_1_20_4
|
||||
(remap = false)
|
||||
#endif
|
||||
@Final
|
||||
private NativeImage pixels;
|
||||
|
||||
@Inject(method = "upload()V", at = @At("HEAD"))
|
||||
public void updateLightTexture(CallbackInfo ci)
|
||||
{
|
||||
// since the light map is always updated on the client render thread we should be able to access the client level at the same time
|
||||
IMinecraftClientWrapper mc = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||
if (!this.isLightTexture
|
||||
|| mc == null
|
||||
|| mc.getWrappedClientLevel() == null
|
||||
)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//ApiShared.LOGGER.info("Lightmap update");
|
||||
IClientLevelWrapper clientLevel = mc.getWrappedClientLevel();
|
||||
MinecraftRenderWrapper.INSTANCE.updateLightmap(this.pixels, clientLevel);
|
||||
}
|
||||
|
||||
public void markLightTexture() { this.isLightTexture = true; }
|
||||
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.forge.mixins.client;
|
||||
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.renderer.FogRenderer;
|
||||
import net.minecraft.client.renderer.FogRenderer.FogMode;
|
||||
import net.minecraft.world.effect.MobEffects;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
#if MC_VER < MC_1_17_1
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
#else
|
||||
import net.minecraft.world.level.material.FogType;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@Mixin(FogRenderer.class)
|
||||
public class MixinFogRenderer
|
||||
{
|
||||
|
||||
// Using this instead of Float.MAX_VALUE because Sodium don't like it.
|
||||
private static final float A_REALLY_REALLY_BIG_VALUE = 420694206942069.F;
|
||||
private static final float A_EVEN_LARGER_VALUE = 42069420694206942069.F;
|
||||
|
||||
@Inject(at = @At("RETURN"),
|
||||
method = "setupFog(Lnet/minecraft/client/Camera;Lnet/minecraft/client/renderer/FogRenderer$FogMode;FZF)V",
|
||||
remap = #if MC_VER == MC_1_17_1 || MC_VER == MC_1_18_2 false #else true #endif ) // Remap messiness due to this being weird in forge
|
||||
private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, float partTick, CallbackInfo callback)
|
||||
{
|
||||
#if MC_VER < MC_1_17_1
|
||||
FluidState fluidState = camera.getFluidInCamera();
|
||||
boolean cameraNotInFluid = fluidState.isEmpty();
|
||||
#else
|
||||
FogType fogTypes = camera.getFluidInCamera();
|
||||
boolean cameraNotInFluid = fogTypes == FogType.NONE;
|
||||
#endif
|
||||
|
||||
|
||||
Entity entity = camera.getEntity();
|
||||
boolean isSpecialFog = (entity instanceof LivingEntity) && ((LivingEntity) entity).hasEffect(MobEffects.BLINDNESS);
|
||||
if (!isSpecialFog && cameraNotInFluid && fogMode == FogMode.FOG_TERRAIN
|
||||
&& !SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class).isFogStateSpecial()
|
||||
&& Config.Client.Advanced.Graphics.Fog.disableVanillaFog.get())
|
||||
{
|
||||
#if MC_VER < MC_1_17_1
|
||||
RenderSystem.fogStart(A_REALLY_REALLY_BIG_VALUE);
|
||||
RenderSystem.fogEnd(A_EVEN_LARGER_VALUE);
|
||||
#else
|
||||
RenderSystem.setShaderFogStart(A_REALLY_REALLY_BIG_VALUE);
|
||||
RenderSystem.setShaderFogEnd(A_EVEN_LARGER_VALUE);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
package com.seibel.distanthorizons.forge.mixins.client;
|
||||
|
||||
import com.seibel.distanthorizons.common.wrappers.DependencySetupDoneCheck;
|
||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
// TODO: Check if this port from fabric works
|
||||
@Mixin(GameRenderer.class)
|
||||
public class MixinGameRenderer
|
||||
{
|
||||
private static final Logger LOGGER = LogManager.getLogger(MixinGameRenderer.class.getSimpleName());
|
||||
|
||||
#if MC_VER >= MC_1_17_1
|
||||
// FIXME: This I think will dup multiple renderStartupEvent calls...
|
||||
@Inject(method = {"reloadShaders", "preloadUiShader"}, at = @At("TAIL"))
|
||||
public void onStartupShaders(CallbackInfo ci)
|
||||
{
|
||||
LOGGER.info("Starting up renderer (forge)");
|
||||
if (!DependencySetupDoneCheck.isDone)
|
||||
{
|
||||
LOGGER.warn("Dependency setup is not done yet, skipping renderer this startup event!");
|
||||
return;
|
||||
}
|
||||
ClientApi.INSTANCE.rendererStartupEvent();
|
||||
}
|
||||
|
||||
@Inject(method = "shutdownShaders", at = @At("HEAD"))
|
||||
public void onShutdownShaders(CallbackInfo ci)
|
||||
{
|
||||
LOGGER.info("Shutting down renderer (forge)");
|
||||
if (!DependencySetupDoneCheck.isDone)
|
||||
{
|
||||
LOGGER.warn("Dependency setup is not done yet, skipping renderer this shutdown event!");
|
||||
return;
|
||||
}
|
||||
ClientApi.INSTANCE.rendererShutdownEvent();
|
||||
}
|
||||
#else
|
||||
|
||||
|
||||
@Inject(method = {"loadEffect"}, at = @At("TAIL"))
|
||||
public void onStartupShaders(CallbackInfo ci) {
|
||||
ClientApi.INSTANCE.rendererStartupEvent();
|
||||
}
|
||||
|
||||
@Inject(method = "shutdownEffect", at = @At("HEAD"))
|
||||
public void onShutdownShaders(CallbackInfo ci) {
|
||||
ClientApi.INSTANCE.rendererShutdownEvent();
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
+185
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.forge.mixins.client;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
#if MC_VER < MC_1_19_4
|
||||
import com.mojang.math.Matrix4f;
|
||||
#else
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.client.renderer.LightTexture;
|
||||
import org.joml.Matrix4f;
|
||||
#endif
|
||||
import com.seibel.distanthorizons.common.rendering.SeamlessOverdraw;
|
||||
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.client.renderer.LevelRenderer;
|
||||
import net.minecraft.client.renderer.LightTexture;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.world.level.lighting.LevelLightEngine;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
#if MC_VER < MC_1_17_1
|
||||
import org.lwjgl.opengl.GL15;
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* This class is used to mix in my rendering code
|
||||
* before Minecraft starts rendering blocks.
|
||||
* If this wasn't done, and we used Forge's
|
||||
* render last event, the LODs would render on top
|
||||
* of the normal terrain. <br><br>
|
||||
*
|
||||
* This is also the mixin for rendering the clouds
|
||||
*
|
||||
* @author coolGi
|
||||
* @author James Seibel
|
||||
* @version 12-31-2021
|
||||
*/
|
||||
@Mixin(LevelRenderer.class)
|
||||
public class MixinLevelRenderer
|
||||
{
|
||||
@Shadow
|
||||
#if MC_VER >= MC_1_20_4
|
||||
(remap = false)
|
||||
#endif
|
||||
private ClientLevel level;
|
||||
@Unique
|
||||
private static float previousPartialTicks = 0;
|
||||
|
||||
// TODO: Is there any reason why this is here? Can it be deleted?
|
||||
public MixinLevelRenderer()
|
||||
{
|
||||
throw new NullPointerException("Null cannot be cast to non-null type.");
|
||||
}
|
||||
|
||||
#if MC_VER < MC_1_17_1
|
||||
@Inject(at = @At("RETURN"), method = "renderSky(Lcom/mojang/blaze3d/vertex/PoseStack;F)V")
|
||||
private void renderSky(PoseStack matrixStackIn, float partialTicks, CallbackInfo callback)
|
||||
#else
|
||||
@Inject(method = "renderClouds", at = @At("HEAD"), cancellable = true)
|
||||
public void renderClouds(PoseStack poseStack, Matrix4f projectionMatrix, float partialTicks, double cameraX, double cameraY, double cameraZ, CallbackInfo ci)
|
||||
#endif
|
||||
{
|
||||
// get the partial ticks since renderBlockLayer doesn't
|
||||
// have access to them
|
||||
previousPartialTicks = partialTicks;
|
||||
}
|
||||
|
||||
|
||||
// TODO: Can we move this to forge's client proxy similarly to how fabric does it
|
||||
#if MC_VER < MC_1_17_1
|
||||
@Inject(at = @At("HEAD"),
|
||||
method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDD)V",
|
||||
cancellable = true)
|
||||
private void renderChunkLayer(RenderType renderType, PoseStack matrixStackIn, double xIn, double yIn, double zIn, CallbackInfo callback)
|
||||
#elif MC_VER < MC_1_19_4
|
||||
@Inject(at = @At("HEAD"),
|
||||
method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLcom/mojang/math/Matrix4f;)V",
|
||||
cancellable = true)
|
||||
private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double cameraXBlockPos, double cameraYBlockPos, double cameraZBlockPos, Matrix4f projectionMatrix, CallbackInfo callback)
|
||||
#elif MC_VER < MC_1_20_2
|
||||
@Inject(at = @At("HEAD"),
|
||||
method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLorg/joml/Matrix4f;)V",
|
||||
cancellable = true)
|
||||
private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double cameraXBlockPos, double cameraYBlockPos, double cameraZBlockPos, Matrix4f projectionMatrix, CallbackInfo callback)
|
||||
#else
|
||||
@Inject(at = @At("HEAD"),
|
||||
method = "Lnet/minecraft/client/renderer/LevelRenderer;renderSectionLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLorg/joml/Matrix4f;)V",
|
||||
cancellable = true)
|
||||
private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double camX, double camY, double camZ, Matrix4f projectionMatrix, CallbackInfo callback)
|
||||
#endif
|
||||
{
|
||||
// get MC's model view and projection matrices
|
||||
#if MC_VER == MC_1_16_5
|
||||
// get the matrices from the OpenGL fixed pipeline
|
||||
float[] mcProjMatrixRaw = new float[16];
|
||||
GL15.glGetFloatv(GL15.GL_PROJECTION_MATRIX, mcProjMatrixRaw);
|
||||
Mat4f mcProjectionMatrix = new Mat4f(mcProjMatrixRaw);
|
||||
mcProjectionMatrix.transpose();
|
||||
|
||||
Mat4f mcModelViewMatrix = McObjectConverter.Convert(matrixStackIn.last().pose());
|
||||
|
||||
#else
|
||||
// get the matrices directly from MC
|
||||
Mat4f mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrixStack.last().pose());
|
||||
Mat4f mcProjectionMatrix = McObjectConverter.Convert(projectionMatrix);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// only render before solid blocks
|
||||
if (renderType.equals(RenderType.solid()))
|
||||
{
|
||||
ClientApi.INSTANCE.renderLods(ClientLevelWrapper.getWrapper(level), mcModelViewMatrix, mcProjectionMatrix, previousPartialTicks);
|
||||
|
||||
// experimental proof-of-concept option
|
||||
if (Config.Client.Advanced.Graphics.AdvancedGraphics.seamlessOverdraw.get())
|
||||
{
|
||||
float[] matrixFloatArray = SeamlessOverdraw.overwriteMinecraftNearFarClipPlanes(mcProjectionMatrix, previousPartialTicks);
|
||||
|
||||
#if MC_VER == MC_1_16_5
|
||||
SeamlessOverdraw.applyLegacyProjectionMatrix(matrixFloatArray);
|
||||
#elif MC_VER < MC_1_19_4
|
||||
projectionMatrix.load(FloatBuffer.wrap(matrixFloatArray));
|
||||
#else
|
||||
projectionMatrix.set(matrixFloatArray);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (Config.Client.Advanced.Debugging.lodOnlyMode.get())
|
||||
{
|
||||
callback.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
#if MC_VER < MC_1_19_4
|
||||
@Inject(at = @At(value = "TAIL", target = "Lnet/minecraft/world/level/lighting/LevelLightEngine;runUpdates(IZZ)I"), method = "renderLevel")
|
||||
public void callAfterRunUpdates(PoseStack poseStack, float partialTick, long finishNanoTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f projectionMatrix, CallbackInfo ci)
|
||||
#elif MC_VER < MC_1_20_1
|
||||
@Inject(at = @At(value = "TAIL", target = "Lnet/minecraft/world/level/lighting/LevelLightEngine;runUpdates(IZZ)I"), method = "renderLevel")
|
||||
public void callAfterRunUpdates(PoseStack poseStack, float partialTick, long finishNanoTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f projectionMatrix, CallbackInfo ci)
|
||||
#else
|
||||
@Inject(at = @At(value = "TAIL", target = "Lnet/minecraft/world/level/lighting/LevelLightEngine;runLightUpdates()I"), method = "renderLevel")
|
||||
private void callAfterRunUpdates(PoseStack poseStack, float partialTick, long finishNanoTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f projectionMatrix, CallbackInfo ci)
|
||||
#endif
|
||||
{
|
||||
ChunkWrapper.syncedUpdateClientLightStatus();
|
||||
}
|
||||
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.forge.mixins.client;
|
||||
|
||||
|
||||
import com.seibel.distanthorizons.common.util.ILightTextureMarker;
|
||||
|
||||
import net.minecraft.client.renderer.LightTexture;
|
||||
import net.minecraft.client.renderer.texture.DynamicTexture;
|
||||
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(LightTexture.class)
|
||||
public class MixinLightTexture
|
||||
{
|
||||
@Shadow
|
||||
#if MC_VER >= MC_1_20_4
|
||||
(remap = false)
|
||||
#endif
|
||||
@Final
|
||||
private DynamicTexture lightTexture;
|
||||
|
||||
@Inject(method = "<init>", at = @At("RETURN"))
|
||||
public void markLightTexture(CallbackInfo ci) { ((ILightTextureMarker) this.lightTexture).markLightTexture(); }
|
||||
|
||||
}
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
package com.seibel.distanthorizons.forge.mixins.client;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.config.EUpdateBranch;
|
||||
import com.seibel.distanthorizons.common.wrappers.gui.updater.UpdateModScreen;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.jar.installer.GitlabGetter;
|
||||
import com.seibel.distanthorizons.core.jar.installer.ModrinthGetter;
|
||||
import com.seibel.distanthorizons.core.jar.updater.SelfUpdater;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.IVersionConstants;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.gui.screens.TitleScreen;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
/**
|
||||
* At the moment this is only used for the auto updater
|
||||
*
|
||||
* @author coolGi
|
||||
*/
|
||||
@Mixin(Minecraft.class)
|
||||
public class MixinMinecraft
|
||||
{
|
||||
#if MC_VER < MC_1_20_2
|
||||
#if MC_VER == MC_1_20_1
|
||||
@Redirect(
|
||||
method = "Lnet/minecraft/client/Minecraft;setInitialScreen(Lcom/mojang/realmsclient/client/RealmsClient;Lnet/minecraft/server/packs/resources/ReloadInstance;Lnet/minecraft/client/main/GameConfig$QuickPlayData;)V",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;setScreen(Lnet/minecraft/client/gui/screens/Screen;)V")
|
||||
)
|
||||
public void onOpenScreen(Minecraft instance, Screen guiScreen)
|
||||
{
|
||||
#else
|
||||
@Redirect(
|
||||
method = "<init>(Lnet/minecraft/client/main/GameConfig;)V",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;setScreen(Lnet/minecraft/client/gui/screens/Screen;)V")
|
||||
)
|
||||
public void onOpenScreen(Minecraft instance, Screen guiScreen)
|
||||
{
|
||||
#endif
|
||||
if (!Config.Client.Advanced.AutoUpdater.enableAutoUpdater.get()) // Don't do anything if the user doesn't want it
|
||||
{
|
||||
instance.setScreen(guiScreen); // Sets the screen back to the vanilla screen as if nothing ever happened
|
||||
return;
|
||||
}
|
||||
|
||||
if (SelfUpdater.onStart())
|
||||
{
|
||||
instance.setScreen(new UpdateModScreen(
|
||||
new TitleScreen(false), // We don't want to use the vanilla title screen as it would fade the buttons
|
||||
(Config.Client.Advanced.AutoUpdater.updateBranch.get() == EUpdateBranch.STABLE ? ModrinthGetter.getLatestIDForVersion(SingletonInjector.INSTANCE.get(IVersionConstants.class).getMinecraftVersion()): GitlabGetter.INSTANCE.projectPipelines.get(0).get("sha"))
|
||||
));
|
||||
}
|
||||
else
|
||||
{
|
||||
instance.setScreen(guiScreen); // Sets the screen back to the vanilla screen as if nothing ever happened
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MC_VER >= MC_1_20_2
|
||||
@Redirect(
|
||||
method = "Lnet/minecraft/client/Minecraft;onGameLoadFinished(Lnet/minecraft/client/Minecraft$GameLoadCookie;)V",
|
||||
at = @At(value = "INVOKE", target = "Ljava/lang/Runnable;run()V")
|
||||
)
|
||||
private void buildInitialScreens(Runnable runnable)
|
||||
{
|
||||
if (
|
||||
Config.Client.Advanced.AutoUpdater.enableAutoUpdater.get() // Don't do anything if the user doesn't want it
|
||||
&& SelfUpdater.onStart()
|
||||
)
|
||||
{
|
||||
runnable = () -> {
|
||||
Minecraft.getInstance().setScreen(new UpdateModScreen(
|
||||
// TODO: Change to runnable, instead of tittle screen
|
||||
new TitleScreen(false), // We don't want to use the vanilla title screen as it would fade the buttons
|
||||
(Config.Client.Advanced.AutoUpdater.updateBranch.get() == EUpdateBranch.STABLE ? ModrinthGetter.getLatestIDForVersion(SingletonInjector.INSTANCE.get(IVersionConstants.class).getMinecraftVersion()) : GitlabGetter.INSTANCE.projectPipelines.get(0).get("sha"))
|
||||
));
|
||||
};
|
||||
}
|
||||
|
||||
runnable.run();
|
||||
}
|
||||
#endif
|
||||
|
||||
@Inject(at = @At("HEAD"), method = "close()V", remap = false)
|
||||
public void close(CallbackInfo ci)
|
||||
{
|
||||
SelfUpdater.onClose();
|
||||
}
|
||||
|
||||
}
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.forge.mixins.client;
|
||||
|
||||
import com.seibel.distanthorizons.common.wrappers.gui.GetConfigScreen;
|
||||
import com.seibel.distanthorizons.common.wrappers.gui.TexturedButtonWidget;
|
||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import net.minecraft.client.gui.screens.OptionsScreen;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.Component;
|
||||
#if MC_VER < MC_1_19_2
|
||||
import net.minecraft.network.chat.TranslatableComponent;
|
||||
#endif
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Adds a button to the menu to goto the config
|
||||
*
|
||||
* @author coolGi
|
||||
* @version 12-02-2021
|
||||
*/
|
||||
@Mixin(OptionsScreen.class)
|
||||
public class MixinOptionsScreen extends Screen
|
||||
{
|
||||
// Get the texture for the button
|
||||
private static final ResourceLocation ICON_TEXTURE = new ResourceLocation(ModInfo.ID, "textures/gui/button.png");
|
||||
protected MixinOptionsScreen(Component title)
|
||||
{
|
||||
super(title);
|
||||
}
|
||||
|
||||
@Inject(at = @At("HEAD"), method = "init")
|
||||
private void lodconfig$init(CallbackInfo ci)
|
||||
{
|
||||
if (Config.Client.optionsButton.get())
|
||||
this. #if MC_VER < MC_1_17_1 addButton #else addRenderableWidget #endif
|
||||
(new TexturedButtonWidget(
|
||||
// Where the button is on the screen
|
||||
this.width / 2 - 180, this.height / 6 - 12,
|
||||
// Width and height of the button
|
||||
20, 20,
|
||||
// Offset
|
||||
0, 0,
|
||||
// Some textuary stuff
|
||||
20, ICON_TEXTURE, 20, 40,
|
||||
// Create the button and tell it where to go
|
||||
// For now it goes to the client option by default
|
||||
(buttonWidget) -> Objects.requireNonNull(minecraft).setScreen(GetConfigScreen.getScreen(this)),
|
||||
// Add a title to the button
|
||||
#if MC_VER < MC_1_19_2
|
||||
new TranslatableComponent(ModInfo.ID + ".title")));
|
||||
#else
|
||||
Component.translatable(ModInfo.ID + ".title")));
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package com.seibel.distanthorizons.forge.mixins.client;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.platform.TextureUtil;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
/**
|
||||
* Sets Minecraft's LOD Bias (looks similar to mipmaps)
|
||||
*
|
||||
* @author coolGi
|
||||
*/
|
||||
@Mixin(TextureUtil.class)
|
||||
public class MixinTextureUtil
|
||||
{
|
||||
@Redirect(method = "prepareImage(Lcom/mojang/blaze3d/platform/NativeImage$InternalGlFormat;IIII)V",
|
||||
at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/platform/GlStateManager;_texParameter(IIF)V"), remap = false)
|
||||
private static void setLodBias(int target, int pname, float param)
|
||||
{
|
||||
float biasValue = Config.Client.Advanced.Graphics.AdvancedGraphics.lodBias.get().floatValue();
|
||||
if (biasValue != 0)
|
||||
{
|
||||
// The target is GL11.GL_TEXTURE_2D
|
||||
// And the pname is GL14.GL_TEXTURE_LOD_BIAS
|
||||
GlStateManager._texParameter(target, pname, biasValue);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
package com.seibel.distanthorizons.forge.mixins.client;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiLevelType;
|
||||
import com.seibel.distanthorizons.api.interfaces.world.IDhApiDimensionTypeWrapper;
|
||||
import com.seibel.distanthorizons.common.wrappers.block.BlockStateWrapper;
|
||||
import com.seibel.distanthorizons.common.wrappers.world.DimensionTypeWrapper;
|
||||
import com.seibel.distanthorizons.core.file.structure.LocalSaveStructure;
|
||||
import com.seibel.distanthorizons.core.level.DhServerLevel;
|
||||
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.util.worldupdate.WorldUpgrader;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.dimension.DimensionType;
|
||||
import net.minecraft.world.level.dimension.LevelStem;
|
||||
import net.minecraft.world.level.levelgen.WorldGenSettings;
|
||||
import net.minecraft.world.level.storage.DimensionDataStorage;
|
||||
import net.minecraft.world.level.storage.LevelStorageSource;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
|
||||
#if FALSE
|
||||
@Mixin(WorldUpgrader.class)
|
||||
public class MixinWorldUpgrader {
|
||||
static class FakeLevelWrapper implements IServerLevelWrapper {
|
||||
private Path saveFolder;
|
||||
private LevelStem stem;
|
||||
private DimensionType dimension;
|
||||
private DimensionTypeWrapper dimensionTypeWrapper;
|
||||
|
||||
public FakeLevelWrapper(LevelStorageSource.LevelStorageAccess storage, WorldGenSettings gen, ResourceKey<Level> dim) {
|
||||
saveFolder = storage.getDimensionPath(dim);
|
||||
stem = gen.dimensions().getOrThrow(WorldGenSettings.levelToLevelStem(dim));
|
||||
dimension = stem.typeHolder().value();
|
||||
dimensionTypeWrapper = DimensionTypeWrapper.getDimensionTypeWrapper(dimension);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EDhApiLevelType getLevelType() {
|
||||
return EDhApiLevelType.SERVER_LEVEL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IDhApiDimensionTypeWrapper getDimensionType() {
|
||||
return dimensionTypeWrapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBlockLight(int x, int y, int z) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSkyLight(int x, int y, int z) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasCeiling() {
|
||||
return dimension.hasCeiling();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSkyLight() {
|
||||
return dimension.hasSkyLight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return dimension.height();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinHeight() {
|
||||
return dimension.minY();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasChunkLoaded(int chunkX, int chunkZ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockStateWrapper getBlockState(DhBlockPos pos) {
|
||||
return BlockStateWrapper.AIR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBiomeWrapper getBiome(DhBlockPos pos) {
|
||||
throw new UnsupportedOperationException("Not implemented yet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getWrappedMcObject() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public IClientLevelWrapper tryGetClientLevelWrapper() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getSaveFolder() {
|
||||
return saveFolder.toFile();
|
||||
}
|
||||
}
|
||||
|
||||
@Unique
|
||||
private DhServerLevel dhServerLevel;
|
||||
@Unique
|
||||
private FakeLevelWrapper fakeLevelWrapper;
|
||||
@Unique
|
||||
public LocalSaveStructure saveStructure;
|
||||
|
||||
@Shadow @Final
|
||||
private DimensionDataStorage overworldDataStorage;
|
||||
@Shadow @Final
|
||||
private LevelStorageSource.LevelStorageAccess levelStorage;
|
||||
@Shadow @Final
|
||||
private WorldGenSettings worldGenSettings;
|
||||
|
||||
@Inject(method = "Lnet/minecraft/util/worldupdate/WorldUpgrader;work()V",
|
||||
at = @At(value = "INVOKE")
|
||||
)
|
||||
private void initWorldUpgrade() {
|
||||
saveStructure = new LocalSaveStructure();
|
||||
}
|
||||
|
||||
@Inject(method = "Lnet/minecraft/util/worldupdate/WorldUpgrader;work()V",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/util/worldupdate/WorldUpgrader;getAllChunkPos(Lnet/minecraft/resources/ResourceKey;)Ljava/util/List;", shift = At.Shift.AFTER),
|
||||
locals = LocalCapture.CAPTURE_FAILSOFT
|
||||
)
|
||||
private void startWorldUpgrade(CallbackInfo info, ResourceKey resourceKey) {
|
||||
ResourceKey<Level> key = resourceKey;
|
||||
fakeLevelWrapper = new FakeLevelWrapper(levelStorage, worldGenSettings, key);
|
||||
dhServerLevel = new DhServerLevel(saveStructure, fakeLevelWrapper);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.forge.mixins.server;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
|
||||
#if MC_VER < MC_1_18_2
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.WorldGenRegion;
|
||||
import net.minecraft.world.level.StructureFeatureManager;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.levelgen.WorldgenRandom;
|
||||
|
||||
@Mixin(ChunkGenerator.class)
|
||||
public class MixinChunkGenerator
|
||||
{
|
||||
@Redirect(method = "applyBiomeDecoration", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/level/biome/Biome;generate(Lnet/minecraft/world/level/StructureFeatureManager;"
|
||||
+ "Lnet/minecraft/world/level/chunk/ChunkGenerator;Lnet/minecraft/server/level/WorldGenRegion;J"
|
||||
+ "Lnet/minecraft/world/level/levelgen/WorldgenRandom;Lnet/minecraft/core/BlockPos;)V"
|
||||
|
||||
))
|
||||
private void wrapBiomeGenerateCall(
|
||||
Biome biome, StructureFeatureManager structFeatManager, ChunkGenerator generator,
|
||||
WorldGenRegion genRegion, long l, WorldgenRandom random, BlockPos pos)
|
||||
{
|
||||
synchronized (ChunkGenerator.class)
|
||||
{
|
||||
//ApiShared.LOGGER.info("Generating Biome {} and acquired lock.", biome.getRegistryName());
|
||||
biome.generate(structFeatManager, (ChunkGenerator) (Object) this, genRegion, l, random, pos);
|
||||
}
|
||||
//ApiShared.LOGGER.info("Released lock. Biome {} generated.", biome.getRegistryName());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
@Mixin(ChunkGenerator.class)
|
||||
public class MixinChunkGenerator { }
|
||||
#endif
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
package com.seibel.distanthorizons.forge.mixins.server;
|
||||
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
#if MC_VER == MC_1_16_5
|
||||
@Mixin(ChunkGenerator.class)
|
||||
class MixinTFChunkGenerator
|
||||
{
|
||||
// not currently implemented, attempting to run with the mod enabled in the IDE causes the game to lock up
|
||||
}
|
||||
#elif MC_VER < MC_1_17_1
|
||||
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
import com.terraforged.mod.chunk.generator.FeatureGenerator;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.WorldGenLevel;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
||||
|
||||
@Mixin(FeatureGenerator.class)
|
||||
public class MixinTFChunkGenerator
|
||||
{
|
||||
|
||||
@Redirect(method = "decorate("
|
||||
+ "Lnet/minecraft/world/level/StructureFeatureManager;"
|
||||
+ "Lnet/minecraft/world/level/WorldGenLevel;"
|
||||
+ "Lnet/minecraft/world/level/chunk/ChunkAccess;"
|
||||
+ "Lnet/minecraft/world/level/biome/Biome;"
|
||||
+ "Lnet/minecraft/core/BlockPos;"
|
||||
+ "Lcom/terraforged/mod/profiler/watchdog/WatchdogContext;)V",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/level/levelgen/feature/ConfiguredFeature;place("
|
||||
+ "Lnet/minecraft/world/level/WorldGenLevel;"
|
||||
+ "Lnet/minecraft/world/level/chunk/ChunkGenerator;"
|
||||
+ "Ljava/util/Random;Lnet/minecraft/core/BlockPos;)Z"
|
||||
))
|
||||
private boolean wrapDecorate$FeaturePlace(ConfiguredFeature<?, ?> feature, WorldGenLevel arg,
|
||||
ChunkGenerator arg2, Random random, BlockPos arg3) {
|
||||
synchronized(FeatureGenerator.class) {
|
||||
//ClientApi.LOGGER.info("wrapDecorate FeaturePlace triggered");
|
||||
return feature.place(arg, arg2, random, arg3);
|
||||
}
|
||||
}
|
||||
|
||||
//METHOD: com.terraforged.mod.chunk.generator.FeatureGenerator.decorate(StructureFeatureManager manager,
|
||||
// WorldGenLevel region, ChunkAccess chunk, Biome biome, BlockPos pos, WatchdogContext context)
|
||||
|
||||
//TARGET: boolean net.minecraft.world.level.levelgen.feature.ConfiguredFeature.place
|
||||
// (WorldGenLevel arg, ChunkGenerator arg2, Random random, BlockPos arg3)
|
||||
}
|
||||
|
||||
#else
|
||||
@Mixin(ChunkGenerator.class)
|
||||
class MixinTFChunkGenerator { }
|
||||
#endif
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.forge.mixins.server;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import com.seibel.distanthorizons.common.wrappers.DependencySetupDoneCheck;
|
||||
import com.seibel.distanthorizons.core.util.objects.DummyRunExecutorService;
|
||||
|
||||
import net.minecraft.Util;
|
||||
|
||||
@Mixin(Util.class)
|
||||
public class MixinUtilBackgroundThread
|
||||
{
|
||||
private static boolean shouldApplyOverride()
|
||||
{
|
||||
return DependencySetupDoneCheck.isDone && DependencySetupDoneCheck.getIsCurrentThreadDistantGeneratorThread.get();
|
||||
}
|
||||
|
||||
@Inject(method = "backgroundExecutor", at = @At("HEAD"), cancellable = true)
|
||||
private static void overrideUtil$backgroundExecutor(CallbackInfoReturnable<ExecutorService> ci)
|
||||
{
|
||||
if (shouldApplyOverride())
|
||||
{
|
||||
//ApiShared.LOGGER.info("util backgroundExecutor triggered");
|
||||
ci.setReturnValue(new DummyRunExecutorService());
|
||||
}
|
||||
}
|
||||
|
||||
#if MC_VER >= MC_1_17_1
|
||||
@Inject(method = "wrapThreadWithTaskName(Ljava/lang/String;Ljava/lang/Runnable;)Ljava/lang/Runnable;",
|
||||
at = @At("HEAD"), cancellable = true)
|
||||
private static void overrideUtil$wrapThreadWithTaskName(String string, Runnable r, CallbackInfoReturnable<Runnable> ci)
|
||||
{
|
||||
if (shouldApplyOverride())
|
||||
{
|
||||
//ApiShared.LOGGER.info("util wrapThreadWithTaskName(Runnable) triggered");
|
||||
ci.setReturnValue(r);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if MC_VER >= MC_1_18_2
|
||||
@Inject(method = "wrapThreadWithTaskName(Ljava/lang/String;Ljava/util/function/Supplier;)Ljava/util/function/Supplier;",
|
||||
at = @At("HEAD"), cancellable = true)
|
||||
private static void overrideUtil$wrapThreadWithTaskNameForSupplier(String string, Supplier<?> r, CallbackInfoReturnable<Supplier<?>> ci)
|
||||
{
|
||||
if (shouldApplyOverride())
|
||||
{
|
||||
//ApiShared.LOGGER.info("util wrapThreadWithTaskName(Supplier) triggered");
|
||||
ci.setReturnValue(r);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.forge.mixins.server.unsafe;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
#if MC_VER >= MC_1_18_2
|
||||
|
||||
import net.minecraft.util.ThreadingDetector;
|
||||
import org.spongepowered.asm.mixin.Mutable;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
/**
|
||||
* Why does this exist? But okay! (Will be probably removed when the experimental generator is done)
|
||||
* FIXME: Recheck this // STILL check this
|
||||
*/
|
||||
@Mixin(ThreadingDetector.class)
|
||||
public class MixinThreadingDetector
|
||||
{
|
||||
@Mutable
|
||||
@Shadow
|
||||
private Semaphore lock;
|
||||
|
||||
@Inject(method = "<init>", at = @At("RETURN"))
|
||||
private void setSemaphore(CallbackInfo ci)
|
||||
{
|
||||
this.lock = new Semaphore(2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
|
||||
@Mixin(ChunkGenerator.class)
|
||||
public class MixinThreadingDetector { }
|
||||
#endif
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.forge.wrappers;
|
||||
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IModChecker;
|
||||
import com.seibel.distanthorizons.forge.wrappers.modAccessor.ModChecker;
|
||||
|
||||
/**
|
||||
* Binds all necessary dependencies so we
|
||||
* can access them in Core. <br>
|
||||
* This needs to be called before any Core classes
|
||||
* are loaded.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @author Ran
|
||||
* @version 12-1-2021
|
||||
*/
|
||||
public class ForgeDependencySetup
|
||||
{
|
||||
public static void createInitialBindings()
|
||||
{
|
||||
SingletonInjector.INSTANCE.bind(IModChecker.class, ModChecker.INSTANCE);
|
||||
}
|
||||
|
||||
public static void runDelayedSetup()
|
||||
{
|
||||
SingletonInjector.INSTANCE.runDelayedSetup();
|
||||
}
|
||||
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.forge.wrappers.modAccessor;
|
||||
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IModChecker;
|
||||
import net.neoforged.fml.ModList;
|
||||
|
||||
public class ModChecker implements IModChecker
|
||||
{
|
||||
public static final ModChecker INSTANCE = new ModChecker();
|
||||
|
||||
@Override
|
||||
public boolean isModLoaded(String modid)
|
||||
{
|
||||
return ModList.get().isLoaded(modid);
|
||||
}
|
||||
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.forge.wrappers.modAccessor;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.AbstractOptifineAccessor;
|
||||
|
||||
public class OptifineAccessor extends AbstractOptifineAccessor
|
||||
{
|
||||
|
||||
@Override
|
||||
public String getModName()
|
||||
{
|
||||
return "Optifine-Forge-1.18.X";
|
||||
}
|
||||
|
||||
@Override
|
||||
public HashSet<DhChunkPos> getNormalRenderedChunks()
|
||||
{
|
||||
// TODO: Impl proper methods here
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"required": true,
|
||||
"minVersion": "0.8",
|
||||
"package": "com.seibel.distanthorizons.forge.mixins",
|
||||
"mixins": [
|
||||
"server.unsafe.MixinThreadingDetector",
|
||||
"server.MixinUtilBackgroundThread",
|
||||
"server.MixinChunkGenerator",
|
||||
"server.MixinTFChunkGenerator"
|
||||
],
|
||||
"client": [
|
||||
"client.MixinClientPacketListener",
|
||||
"client.MixinDebugScreenOverlay",
|
||||
"client.MixinFogRenderer",
|
||||
"client.MixinGameRenderer",
|
||||
"client.MixinLevelRenderer",
|
||||
"client.MixinDynamicTexture",
|
||||
"client.MixinLightTexture",
|
||||
"client.MixinOptionsScreen",
|
||||
"client.MixinTextureUtil"
|
||||
],
|
||||
"server": [],
|
||||
"plugin": "com.seibel.distanthorizons.forge.mixins.ForgeMixinPlugin"
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
modLoader = "javafml" #//mandatory
|
||||
loaderVersion = "*" # // mandatory. Allow all forge versions as we are definding what Minecraft versions we requre later on
|
||||
license = "LGPL"
|
||||
issueTrackerURL = "${issues}"
|
||||
|
||||
|
||||
[[mods]] #//mandatory
|
||||
modId = "distanthorizons" #//mandatory
|
||||
version = "${version}" #//mandatory, gets the version number from jar populated by the build.gradle script
|
||||
displayName = "${mod_name}" #//mandatory
|
||||
authors = ["James Seibel", "Leonardo Amato", "Cola", "coolGi", "Ran", "Leetom"] # Should be done with `$authors`, but architectury complains
|
||||
#//updateJSONURL="https://change.me.example.invalid/updates.json" # A URL to query for updates for this mod. See the JSON update specification https://mcforge.readthedocs.io/en/latest/gettingstarted/autoupdate/
|
||||
displayURL = "${homepage}"
|
||||
description = "${description}" #//mandatory. The description text for the mod
|
||||
logoFile = "logo.png"
|
||||
catalogueImageIcon = "icon.png"
|
||||
credits = "Massive thanks to: Leonardo, Cola, Ran, CoolGi, and Leetom. For their hard work to bring Distant Horizons to where it is today. - James"
|
||||
#// if not set defaults to "false"
|
||||
clientSideOnly = "true"
|
||||
#// if not set side defaults to "BOTH"
|
||||
#// TODO change to "BOTH" when we add server support
|
||||
side = "CLIENT"
|
||||
#// Allow any version to be present (or not) on the server
|
||||
acceptableRemoteVersions = "*"
|
||||
|
||||
[[mixins]]
|
||||
config = "DistantHorizons.mixins.json"
|
||||
|
||||
[[dependencies.distanthorizons]]
|
||||
modId = "minecraft"
|
||||
type = "required"
|
||||
versionRange = "${compatible_forgemc_versions}" # Where we set what version of mc it is avalible for
|
||||
ordering = "NONE"
|
||||
side = "BOTH"
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"pack": {
|
||||
"pack_format": 7,
|
||||
"supported_formats": {
|
||||
"min_inclusive": 16,
|
||||
"max_inclusive": 90000
|
||||
},
|
||||
"description": "Distant Horizons"
|
||||
}
|
||||
}
|
||||
+5
-1
@@ -4,11 +4,15 @@ pluginManagement {
|
||||
name "Fabric"
|
||||
url "https://maven.fabricmc.net/"
|
||||
}
|
||||
// TODO: Stop using Forge for versions with NeoForge
|
||||
// TODO: Stop using Forge for versions with NeoForged
|
||||
maven {
|
||||
name "Forge"
|
||||
url "https://maven.minecraftforge.net/"
|
||||
}
|
||||
maven {
|
||||
name "Neoforged"
|
||||
url "https://maven.neoforged.net/releases/"
|
||||
}
|
||||
maven {
|
||||
name "Architectury (Better Forge because regular Forge is annoying)" // TODO: Once we switch to NeoForge, would it's gradle work better? or will it have Forge's problems in it
|
||||
url "https://maven.architectury.dev/"
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# 1.20.4 version
|
||||
java_version=17
|
||||
minecraft_version=1.20.4
|
||||
parchment_version=1.20.1:2023.09.03
|
||||
parchment_version=1.20.2:2023.12.10
|
||||
compatible_minecraft_versions=["1.20.3", "1.20.4"]
|
||||
accessWidenerVersion=1_20_2
|
||||
builds_for=fabric,forge
|
||||
builds_for=fabric,neoforged
|
||||
|
||||
# Fabric loader
|
||||
fabric_loader_version=0.15.1
|
||||
@@ -36,13 +36,13 @@ fabric_api_version=0.91.2+1.20.4
|
||||
enable_immersive_portals=0
|
||||
enable_canvas=0
|
||||
|
||||
# Forge loader
|
||||
forge_version=49.0.3
|
||||
# Forge mod versions
|
||||
# Neoforged loader
|
||||
neoforged_version=20.4.49-beta
|
||||
# Neoforged mod versions
|
||||
starlight_version_forge=
|
||||
terraforged_version=
|
||||
|
||||
# Forge mod run
|
||||
# Neoforged mod run
|
||||
# 0 = Don't enable and don't run
|
||||
# 1 = Can be referenced in code but doesn't run
|
||||
# 2 = Can be referenced in code and runs in client
|
||||
|
||||
Reference in New Issue
Block a user