mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-14 09:05:17 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
211d3aa692 | ||
|
|
88bb2217e5 | ||
|
|
278bdfc132 | ||
|
|
66d4d888eb | ||
|
|
ee1e695124 | ||
|
|
6435274d1e | ||
|
|
6c3729d6e9 | ||
|
|
6a702686db |
No files matched your search
@@ -2,7 +2,7 @@ name: Publish
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ '26.3' ]
|
||||
branches: [ '26.1.2' ]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
@@ -38,7 +38,6 @@ src/minecraft
|
||||
/projects/**/run/
|
||||
/projects/**/*.launch
|
||||
/repo/
|
||||
/rejects-*/
|
||||
src/*/generated/**/.cache/
|
||||
|
||||
# Generated by gradle every import
|
||||
|
||||
+28
-34
@@ -29,9 +29,6 @@ jarSigner.autoDetect('forge')
|
||||
|
||||
// We have to tell ForgeDev to use the exact versions of tools we ship in the installer
|
||||
fdtools {
|
||||
configure('mavenizer') {
|
||||
version = '0.5.22'
|
||||
}
|
||||
configure('binpatcher') {
|
||||
version = buildLibs.binarypatcher.get().version
|
||||
}
|
||||
@@ -185,12 +182,17 @@ forgedev.runs {
|
||||
|
||||
mainClass = 'net.minecraftforge.bootstrap.ForgeBootstrap'
|
||||
args '--gameDir', '.'
|
||||
jvmArgs '-Djava.net.preferIPv6Addresses=system', '-XX:+UseCompactObjectHeaders', '-XX:StackShadowPages=32'
|
||||
jvmArgs '-Djava.net.preferIPv6Addresses=system', '-XX:+UseCompactObjectHeaders'
|
||||
|
||||
systemProperty 'bsl.debug', 'true'
|
||||
systemProperty 'terminal.jline', 'true'
|
||||
with(sourceSets.test) {
|
||||
systemProperty 'forge.enableGameTest', 'true'
|
||||
systemProperty 'forgedev.enableTestMods', 'true'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
create('client') {
|
||||
options {
|
||||
systemProperty 'eventbus.api.strictRuntimeChecks', 'true'
|
||||
@@ -204,11 +206,6 @@ forgedev.runs {
|
||||
'--versionType', 'release',
|
||||
'--assetsDir', '{assets_root}',
|
||||
'--assetIndex', '{asset_index}'
|
||||
|
||||
with(sourceSets.test) {
|
||||
systemProperty 'forge.enableGameTest', 'true'
|
||||
systemProperty 'forgedev.enableTestMods', 'true'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,13 +217,8 @@ forgedev.runs {
|
||||
|
||||
create('gameTestServer') {
|
||||
options {
|
||||
systemProperty 'forge.enableGameTest', 'true'
|
||||
args '--launchTarget', 'forge_dev_server_gametest'
|
||||
args '--uniqueWorld' // Unique world is used so that the world regenerates, as well as the world config isn't influenced by other runs
|
||||
|
||||
with(sourceSets.test) {
|
||||
systemProperty 'forgedev.enableTestMods', 'true'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,8 +236,6 @@ forgedev.runs {
|
||||
}
|
||||
|
||||
with(sourceSets.test) {
|
||||
systemProperty 'forge.enableGameTest', 'true'
|
||||
systemProperty 'forgedev.enableTestMods', 'true'
|
||||
args '--mod', '.+',
|
||||
'--existing', sourceSets.test.resources.srcDirs[0],
|
||||
'--output', rootProject.file('src/test/generated/')
|
||||
@@ -255,20 +245,23 @@ forgedev.runs {
|
||||
|
||||
create('clientData') {
|
||||
options {
|
||||
args '--launchTarget', 'forge_dev_client_data',
|
||||
'--all',
|
||||
'--existing', sourceSets.main.resources.srcDirs[0],
|
||||
'--assetsDir', '{assets_root}',
|
||||
'--assetIndex', '{asset_index}'
|
||||
args '--all',
|
||||
'--existing', sourceSets.main.resources.srcDirs[0],
|
||||
'--assetsDir', '{assets_root}',
|
||||
'--assetIndex', '{asset_index}'
|
||||
|
||||
with(sourceSets.main) {
|
||||
args '--mod', 'forge',
|
||||
'--output', rootProject.file('src/main/generated/')
|
||||
args '--launchTarget', 'forge_dev_client_data',
|
||||
'--mod', 'forge',
|
||||
'--output', rootProject.file('src/main/generated/'),
|
||||
'--mod', 'forge'
|
||||
}
|
||||
|
||||
with(sourceSets.test) {
|
||||
systemProperty 'forgedev.enableTestMods', 'true'
|
||||
args '--mod', '.+',
|
||||
args '--launchTarget', 'forge_dev',
|
||||
'--launchEntry', 'minecraft/net.minecraft.client.data.Main',
|
||||
'--launchData',
|
||||
'--mod', '.+',
|
||||
'--existing', sourceSets.test.resources.srcDirs[0],
|
||||
'--output', rootProject.file('src/test/generated/')
|
||||
}
|
||||
@@ -407,7 +400,7 @@ forgedev.userDev {
|
||||
parents = []
|
||||
main = 'net.minecraftforge.bootstrap.ForgeBootstrap'
|
||||
args '--gameDir', '.'
|
||||
jvmArgs '-Djava.net.preferIPv6Addresses=system', '-XX:+UseCompactObjectHeaders', '-XX:StackShadowPages=32'
|
||||
jvmArgs '-Djava.net.preferIPv6Addresses=system', '-XX:+UseCompactObjectHeaders'
|
||||
client = it.name.containsIgnoreCase('client')
|
||||
environment 'MCP_MAPPINGS', '{mcp_mappings}'
|
||||
}
|
||||
@@ -461,8 +454,8 @@ forgedev.userdevCompatibility(minecraftVersion) {
|
||||
final clientBinPatches = forgedev.binaryPatches('client') {
|
||||
clean = minecraftFiles.client
|
||||
// Workaround for 3rd party launcher issues, marker needed to locate MC, store needed to fix zlib-ng issues
|
||||
apply {
|
||||
store = true
|
||||
apply {
|
||||
store = true
|
||||
marker = '.forge_patched_minecraft'
|
||||
}
|
||||
}
|
||||
@@ -602,12 +595,12 @@ forgedev.installer {
|
||||
inheritsFrom = minecraftVersion
|
||||
mainClass = 'net.minecraftforge.bootstrap.ForgeBootstrap'
|
||||
gameArgs = [ '--launchTarget', 'forge_client' ]
|
||||
jvmArgs = [ '-Djava.net.preferIPv6Addresses=system', '-XX:+UseCompactObjectHeaders', '-XX:StackShadowPages=32' ]
|
||||
jvmArgs = [ '-Djava.net.preferIPv6Addresses=system', '-XX:+UseCompactObjectHeaders' ]
|
||||
}
|
||||
}
|
||||
|
||||
final mdkGradleWrapper = tasks.register('mdkGradleWrapper', Wrapper) {
|
||||
gradleVersion = '9.7.1'
|
||||
gradleVersion = '9.5.0'
|
||||
scriptFile = layout.buildDirectory.dir("wrapper/" + gradleVersion + "/gradlew")
|
||||
jarFile = layout.buildDirectory.dir("wrapper/" + gradleVersion + "/gradle/wrapper/gradle-wrapper.jar")
|
||||
}
|
||||
@@ -766,16 +759,16 @@ publishing {
|
||||
def all = tasks.register('all') {}
|
||||
afterEvaluate {
|
||||
if (gradle.startParameter.taskNames.contains('all')) {
|
||||
tasks.forEach { task -> // This forces everything to be realized, which is why we have the startParameter check
|
||||
if (!gradle.startParameter.isTaskGraph() && task.name.startsWith('run')) return
|
||||
tasks.forEach { task -> // This forces everything to be realized, which is why we have the startParameter check
|
||||
if (!gradle.startParameter.isTaskGraph() && task.name.startsWith('run')) return
|
||||
if (task.name in [all.name, 'dependencyInsight', 'dependencies', 'dependencyUpdates', 'init', 'buildEnvironment', 'idea',
|
||||
'eclipse', 'javaToolchains', 'outgoingVariants', 'projects', 'properties', 'resolvableConfigurations', 'tasks', 'updateDaemonJvm',
|
||||
'generateActionsWorkflow'
|
||||
]) return
|
||||
if (task.name.startsWith('clean')) return
|
||||
if (task.name == 'checkJarCompatibility') return // This doesn't work in FG6 dev, I think it's cuz we check vs srg names. Will need to look at later
|
||||
all.configure { dependsOn(task) }
|
||||
}
|
||||
all.configure { dependsOn(task) }
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
@@ -792,6 +785,7 @@ forgedev.runs.configureEach {
|
||||
run.configure { dependsOn finalizeSpawn}
|
||||
runTest.configure { dependsOn finalizeSpawn}
|
||||
}
|
||||
|
||||
// run gradlew dependencyUpdates --no-parallel
|
||||
//noinspection UnnecessaryQualifiedReference
|
||||
tasks.named('dependencyUpdates', com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask) {
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
MinecraftForge
|
||||
=============
|
||||
[][Download]
|
||||
[][Download]
|
||||
[][Download] [][Discord] [][Patreon]
|
||||
|
||||
Forge is a free, open-source modding API all of your favourite mods use!
|
||||
|
||||
@@ -16,7 +16,7 @@ import java.util.function.Supplier;
|
||||
/**
|
||||
* Used to allow access to certain things from the game layer
|
||||
*/
|
||||
public final class Bindings {
|
||||
public class Bindings {
|
||||
private Bindings() {}
|
||||
|
||||
/**
|
||||
@@ -27,7 +27,7 @@ public final class Bindings {
|
||||
.findFirst().orElseThrow(() -> new IllegalStateException("Could not find bindings provider"));
|
||||
|
||||
/**
|
||||
* @return A supplier of {@link BusGroup#DEFAULT}
|
||||
* @return A supplier of net.minecraftforge.common.MinecraftForge#EVENT_BUS
|
||||
*/
|
||||
public static Supplier<BusGroup> getForgeBus() {
|
||||
return PROVIDER.getForgeBusSupplier();
|
||||
|
||||
@@ -14,14 +14,16 @@ import java.util.List;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class CrashReportCallables {
|
||||
public class CrashReportCallables
|
||||
{
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final List<ISystemReportExtender> crashCallables = Collections.synchronizedList(new ArrayList<>());
|
||||
|
||||
/**
|
||||
* Register a custom {@link ISystemReportExtender}
|
||||
*/
|
||||
public static void registerCrashCallable(ISystemReportExtender callable) {
|
||||
public static void registerCrashCallable(ISystemReportExtender callable)
|
||||
{
|
||||
crashCallables.add(callable);
|
||||
}
|
||||
|
||||
@@ -31,15 +33,19 @@ public class CrashReportCallables {
|
||||
* @param headerName The name of the system report entry
|
||||
* @param reportGenerator The report generator to be called when a crash report is built
|
||||
*/
|
||||
public static void registerCrashCallable(String headerName, Supplier<String> reportGenerator) {
|
||||
registerCrashCallable(new ISystemReportExtender() {
|
||||
public static void registerCrashCallable(String headerName, Supplier<String> reportGenerator)
|
||||
{
|
||||
registerCrashCallable(new ISystemReportExtender()
|
||||
{
|
||||
@Override
|
||||
public String getLabel() {
|
||||
public String getLabel()
|
||||
{
|
||||
return headerName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String get() {
|
||||
public String get()
|
||||
{
|
||||
return reportGenerator.get();
|
||||
}
|
||||
});
|
||||
@@ -52,23 +58,31 @@ public class CrashReportCallables {
|
||||
* @param reportGenerator The report generator to be called when a crash report is built
|
||||
* @param active The supplier of the flag to be checked when a crash report is built
|
||||
*/
|
||||
public static void registerCrashCallable(String headerName, Supplier<String> reportGenerator, BooleanSupplier active) {
|
||||
registerCrashCallable(new ISystemReportExtender() {
|
||||
public static void registerCrashCallable(String headerName, Supplier<String> reportGenerator, BooleanSupplier active)
|
||||
{
|
||||
registerCrashCallable(new ISystemReportExtender()
|
||||
{
|
||||
@Override
|
||||
public String getLabel() {
|
||||
public String getLabel()
|
||||
{
|
||||
return headerName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String get() {
|
||||
public String get()
|
||||
{
|
||||
return reportGenerator.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
try {
|
||||
public boolean isActive()
|
||||
{
|
||||
try
|
||||
{
|
||||
return active.getAsBoolean();
|
||||
} catch (Throwable t) {
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
LOGGER.warn("CrashCallable '{}' threw an exception while checking the active flag, disabling", headerName, t);
|
||||
return false;
|
||||
}
|
||||
@@ -76,7 +90,8 @@ public class CrashReportCallables {
|
||||
});
|
||||
}
|
||||
|
||||
public static List<ISystemReportExtender> allCrashCallables() {
|
||||
public static List<ISystemReportExtender> allCrashCallables()
|
||||
{
|
||||
return List.copyOf(crashCallables);
|
||||
}
|
||||
}
|
||||
@@ -7,10 +7,12 @@ package net.minecraftforge.fml;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public interface ISystemReportExtender extends Supplier<String> {
|
||||
public interface ISystemReportExtender extends Supplier<String>
|
||||
{
|
||||
String getLabel();
|
||||
|
||||
default boolean isActive() {
|
||||
default boolean isActive()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -53,7 +53,7 @@ public abstract class ModContainer {
|
||||
Supplier<IExtensionPoint.DisplayTest> displayTestSupplier = switch (displayTestString) {
|
||||
case "MATCH_VERSION" -> // default displaytest checks for version string match
|
||||
() -> new IExtensionPoint.DisplayTest(() -> this.modInfo.getVersion().toString(),
|
||||
(incoming, _) -> Objects.equals(incoming, this.modInfo.getVersion().toString()));
|
||||
(incoming, isNetwork) -> Objects.equals(incoming, this.modInfo.getVersion().toString()));
|
||||
case "IGNORE_SERVER_VERSION" -> // Ignores any version information coming from the server - use for server only mods
|
||||
IExtensionPoint.DisplayTest.IGNORE_SERVER_VERSION;
|
||||
case "IGNORE_ALL_VERSION" -> // Ignores all information and provides no information
|
||||
|
||||
@@ -101,7 +101,7 @@ public final class ModList {
|
||||
}
|
||||
|
||||
public static Optional<? extends ModContainer> getModContainerById(String modId) {
|
||||
return Optional.ofNullable(indexedMods == null ? null : indexedMods.get(modId));
|
||||
return Optional.ofNullable(indexedMods.get(modId));
|
||||
}
|
||||
|
||||
public static Optional<? extends ModContainer> getModContainerByObject(Object obj) {
|
||||
|
||||
@@ -379,8 +379,8 @@ public final class ModLoader {
|
||||
@SuppressWarnings("removal")
|
||||
public static <T extends IModBusEvent> void postEventWrapContainerInModOrder(T event) {
|
||||
postEventWithWrapInModOrder(event,
|
||||
(mc, _) -> ModLoadingContext.get().setActiveContainer(mc),
|
||||
(_, _) -> ModLoadingContext.get().setActiveContainer(null)
|
||||
(mc, e) -> ModLoadingContext.get().setActiveContainer(mc),
|
||||
(mc, e) -> ModLoadingContext.get().setActiveContainer(null)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.minecraftforge.fml.loading.progress.ProgressMeter;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.function.Function;
|
||||
|
||||
@@ -99,7 +99,7 @@ final class ModStateTransitionHelper {
|
||||
results[i] = raw.whenComplete((result, exception) -> list.set(i, new FutureResult<>(result, exception)));
|
||||
}
|
||||
|
||||
return CompletableFuture.allOf(results).handle((_, _)->null).thenApply(_ -> list);
|
||||
return CompletableFuture.allOf(results).handle((r, th)->null).thenApply(res -> list);
|
||||
}
|
||||
|
||||
private static <T extends IModBusEvent> CompletableFuture<Void> addCompletableFutureTaskForModDispatch(
|
||||
@@ -135,7 +135,7 @@ final class ModStateTransitionHelper {
|
||||
handler.run();
|
||||
mod.acceptEvent(eventGenerator.apply(mod));
|
||||
}, executor)
|
||||
.whenComplete((_, exception) -> {
|
||||
.whenComplete((mc, exception) -> {
|
||||
mod.modLoadingStage = nextState.apply(mod.modLoadingStage, exception);
|
||||
progressBar.increment();
|
||||
ModLoadingContext.get().setActiveContainer(null);
|
||||
|
||||
@@ -9,8 +9,8 @@ import java.util.concurrent.Executor;
|
||||
import java.util.function.BinaryOperator;
|
||||
|
||||
public enum ThreadSelector implements BinaryOperator<Executor> {
|
||||
SYNC((sync, _) -> sync),
|
||||
PARALLEL((_, parallel) -> parallel);
|
||||
SYNC((sync, parallel) -> sync),
|
||||
PARALLEL((sync, parallel) -> parallel);
|
||||
|
||||
private final BinaryOperator<Executor> selector;
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@ import net.minecraftforge.fml.loading.StringUtils;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class ModConfig
|
||||
{
|
||||
|
||||
@@ -55,9 +55,9 @@ dependencies {
|
||||
// We are making the list of providers first BEFORE mapping them to a provider of the resolved objects so that they can be finalized after configuration.
|
||||
var lwjglTestLibs = [
|
||||
dependencies.variantOf(earlyDisplayTestLibs.lwjgl) { classifier lwjglNatives },
|
||||
dependencies.variantOf(earlyDisplayTestLibs.lwjgl.glfw) { classifier lwjglNatives },
|
||||
dependencies.variantOf(earlyDisplayTestLibs.lwjgl.opengl) { classifier lwjglNatives },
|
||||
dependencies.variantOf(earlyDisplayTestLibs.lwjgl.stb) { classifier lwjglNatives },
|
||||
dependencies.variantOf(earlyDisplayTestLibs.lwjgl.sdl) { classifier lwjglNatives }
|
||||
dependencies.variantOf(earlyDisplayTestLibs.lwjgl.stb) { classifier lwjglNatives }
|
||||
].with { list ->
|
||||
provider { list.collect { it.get() } }
|
||||
}
|
||||
|
||||
+179
-227
@@ -13,12 +13,10 @@ import net.minecraftforge.fml.loading.ImmediateWindowHandler;
|
||||
import net.minecraftforge.fml.loading.ImmediateWindowProvider;
|
||||
import net.minecraftforge.fml.loading.progress.StartupNotificationManager;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.lwjgl.opengl.GL;
|
||||
import org.lwjgl.sdl.SDLError;
|
||||
import org.lwjgl.sdl.SDLVideo;
|
||||
import org.lwjgl.sdl.SDL_Event;
|
||||
import org.lwjgl.sdl.SDL_Rect;
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.glfw.GLFWVidMode;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.lwjgl.util.tinyfd.TinyFileDialogs;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -31,10 +29,12 @@ import java.net.URI;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
@@ -43,18 +43,17 @@ import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.IntConsumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collector;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.lwjgl.glfw.GLFW.*;
|
||||
import static org.lwjgl.opengl.GL.createCapabilities;
|
||||
import static org.lwjgl.opengl.GL32C.*;
|
||||
|
||||
import static org.lwjgl.sdl.SDLError.*;
|
||||
import static org.lwjgl.sdl.SDLEvents.*;
|
||||
import static org.lwjgl.sdl.SDLHints.*;
|
||||
import static org.lwjgl.sdl.SDLInit.*;
|
||||
import static org.lwjgl.sdl.SDLVideo.*;
|
||||
|
||||
/**
|
||||
* The Loading Window that is opened Immediately after Forge starts.
|
||||
* It is called from the ModDirTransformerDiscoverer, the soonest method that ModLauncher calls into Forge code.
|
||||
@@ -84,10 +83,10 @@ public class DisplayWindow implements ImmediateWindowProvider {
|
||||
private ScheduledFuture<?> initializationFuture;
|
||||
|
||||
private PerformanceInfo performanceInfo;
|
||||
@SuppressWarnings("unused")
|
||||
private ScheduledFuture<?> performanceTick;
|
||||
// The GL ID of the window. Used for all operations
|
||||
private long window;
|
||||
// The SDL Context we use for switching between threads
|
||||
private long sdlContext;
|
||||
// The thread that contains and ticks the window while Forge is loading mods
|
||||
private static final ScheduledExecutorService renderScheduler = Executors.newSingleThreadScheduledExecutor(r -> {
|
||||
final var thread = Executors.defaultThreadFactory().newThread(r);
|
||||
@@ -114,14 +113,6 @@ public class DisplayWindow implements ImmediateWindowProvider {
|
||||
return "fmlearlywindow";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImmediateWindowProvider selectBackend(String backend) {
|
||||
// We only support opengl
|
||||
//if ("default".equals(backend) || "opengl".equals(backend))
|
||||
// return this;
|
||||
return ImmediateWindowProvider.getFallbackHandler();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Runnable initialize(String[] arguments) {
|
||||
String mcVersion = FMLLoader.versionInfo().mcVersion();
|
||||
@@ -146,7 +137,7 @@ public class DisplayWindow implements ImmediateWindowProvider {
|
||||
this.colourScheme = ColourScheme.BLACK;
|
||||
} else {
|
||||
try {
|
||||
// check the options file for the color scheme
|
||||
// check the options file for the colour scheme
|
||||
var optionLines = Files.readAllLines(FMLPaths.GAMEDIR.get().resolve(Path.of("options.txt")));
|
||||
var keyName = "darkMojangStudiosBackground:";
|
||||
for (String line : optionLines) {
|
||||
@@ -185,7 +176,7 @@ public class DisplayWindow implements ImmediateWindowProvider {
|
||||
return;
|
||||
}
|
||||
nextFrameTime = nt + MINFRAMETIME;
|
||||
SDL_GL_MakeCurrent(window, sdlContext);
|
||||
glfwMakeContextCurrent(window);
|
||||
framebuffer.activate();
|
||||
glViewport(0, 0, this.context.scaledWidth(), this.context.scaledHeight());
|
||||
this.context.elementShader().activate();
|
||||
@@ -197,12 +188,11 @@ public class DisplayWindow implements ImmediateWindowProvider {
|
||||
glViewport(0, 0, fbWidth, fbHeight);
|
||||
framebuffer.draw(this.fbWidth, this.fbHeight);
|
||||
// Swap buffers; we're done
|
||||
SDL_GL_SwapWindow(window);
|
||||
glfwSwapBuffers(window);
|
||||
} catch (Throwable t) {
|
||||
LOGGER.error("BARF", t);
|
||||
} finally {
|
||||
if (this.windowTick != null)
|
||||
SDL_GL_MakeCurrent(window, 0); // we release the gl context IF we're running off the main thread
|
||||
if (this.windowTick != null) glfwMakeContextCurrent(0); // we release the gl context IF we're running off the main thread
|
||||
renderLock.release();
|
||||
}
|
||||
}
|
||||
@@ -214,18 +204,12 @@ public class DisplayWindow implements ImmediateWindowProvider {
|
||||
* Nothing fancy, we just want to draw and render text.
|
||||
*/
|
||||
private void initRender(final @Nullable String mcVersion, final String forgeVersion) {
|
||||
this.sdlContext = SDL_GL_CreateContext(window);
|
||||
if (sdlContext == 0)
|
||||
throw new IllegalStateException("Failed to create OpenGL context: " + SDL_GetError());
|
||||
|
||||
// This thread owns the GL render context now. We should make a note of that.
|
||||
bindGlContext();
|
||||
GL.createCapabilities();
|
||||
|
||||
glfwMakeContextCurrent(window);
|
||||
// Wait for one frame to be complete before swapping; enable vsync in other words.
|
||||
SDL_GL_SetSwapInterval(1);
|
||||
|
||||
LOGGER.info("GL info: " + glGetString(GL_RENDERER) + " GL version " + glGetString(GL_VERSION) + ", " + glGetString(GL_VENDOR));
|
||||
glfwSwapInterval(1);
|
||||
createCapabilities();
|
||||
LOGGER.info("GL info: "+ glGetString(GL_RENDERER) + " GL version " + glGetString(GL_VERSION) + ", " + glGetString(GL_VENDOR));
|
||||
|
||||
elementShader = new ElementShader();
|
||||
try {
|
||||
@@ -235,7 +219,7 @@ public class DisplayWindow implements ImmediateWindowProvider {
|
||||
crashElegantly("An error occurred initializing shaders.");
|
||||
}
|
||||
|
||||
// Set the clear color based on the color scheme
|
||||
// Set the clear color based on the colour scheme
|
||||
glClearColor(colourScheme.background().redf(), colourScheme.background().greenf(), colourScheme.background().bluef(), 1f);
|
||||
|
||||
// we always render to an 854x480 texture and then fit that to the screen - with a scale factor
|
||||
@@ -261,15 +245,11 @@ public class DisplayWindow implements ImmediateWindowProvider {
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
releaseGlContext();
|
||||
|
||||
glfwMakeContextCurrent(0);
|
||||
this.windowTick = renderScheduler.scheduleAtFixedRate(this::renderThreadFunc, 50, 50, TimeUnit.MILLISECONDS);
|
||||
|
||||
// Update the performance information every 1/2 second
|
||||
renderScheduler.scheduleAtFixedRate(performanceInfo::update, 0, 500, TimeUnit.MILLISECONDS);
|
||||
this.performanceTick = renderScheduler.scheduleAtFixedRate(performanceInfo::update, 0, 500, TimeUnit.MILLISECONDS);
|
||||
// schedule a 50 ms ticker to try and smooth out the rendering
|
||||
//renderScheduler.scheduleAtFixedRate(() -> animationTimerTrigger.set(true), 1, 50, TimeUnit.MILLISECONDS);
|
||||
renderScheduler.scheduleAtFixedRate(()-> animationTimerTrigger.set(true), 1, 50, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -306,7 +286,6 @@ public class DisplayWindow implements ImmediateWindowProvider {
|
||||
glBindVertexArray(currentVAO);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, currentFB);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the window and Render Thread; we're ready to go.
|
||||
*/
|
||||
@@ -355,65 +334,71 @@ public class DisplayWindow implements ImmediateWindowProvider {
|
||||
* As long as we can verify that, then GL (and things like OS X) have no complaints with doing this.
|
||||
*
|
||||
* @param mcVersion Minecraft Version
|
||||
* @return The selected GL profile as an integer pair
|
||||
*/
|
||||
public void initWindow(@Nullable String mcVersion) {
|
||||
// Initialize a time guard, in case something goes wrong
|
||||
long initBegin = System.nanoTime();
|
||||
if (!SDL_Init(SDL_INIT_VIDEO)) {
|
||||
crashElegantly("We are unable to initialize the graphics system.\nSDL_Init failed.\n");
|
||||
throw new IllegalStateException("Unable to initialize SDL");
|
||||
// Initialize GLFW with a time guard, in case something goes wrong
|
||||
long glfwInitBegin = System.nanoTime();
|
||||
if (!glfwInit()) {
|
||||
crashElegantly("We are unable to initialize the graphics system.\nglfwInit failed.\n");
|
||||
throw new IllegalStateException("Unable to initialize GLFW");
|
||||
}
|
||||
long initEnd = System.nanoTime();
|
||||
long glfwInitEnd = System.nanoTime();
|
||||
|
||||
if (initEnd - initBegin > 1e9)
|
||||
LOGGER.error("WARNING : Window init took {} seconds to start.", (initEnd - initBegin) / 1.0e9);
|
||||
if (glfwInitEnd - glfwInitBegin > 1e9) {
|
||||
LOGGER.error("WARNING : glfwInit took {} seconds to start.", (glfwInitEnd - glfwInitBegin) / 1.0e9);
|
||||
}
|
||||
|
||||
// Clear the Last Exception (#7285 - Prevent Vanilla throwing an IllegalStateException due to invalid controller mappings)
|
||||
handleLastGLFWError((error, description) -> LOGGER.error(String.format("Suppressing Last GLFW error: [0x%X]%s", error, description)));
|
||||
|
||||
// Set window hints for the new window we're gonna create.
|
||||
SDL_ResetHints();
|
||||
glfwDefaultWindowHints();
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
|
||||
glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_NATIVE_CONTEXT_API);
|
||||
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
|
||||
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
|
||||
|
||||
String vanillaWindowTitle = "Minecraft* ";
|
||||
if (mcVersion != null)
|
||||
vanillaWindowTitle += mcVersion;
|
||||
if (mcVersion != null) vanillaWindowTitle += mcVersion;
|
||||
|
||||
var primaryMonitor = SDL_GetPrimaryDisplay();
|
||||
// this emulates what we would get without early progress window
|
||||
// as vanilla never sets these, so GLFW uses the first window title
|
||||
// set them explicitly to avoid it using "FML early loading progress" as the class
|
||||
glfwWindowHintString(GLFW_X11_CLASS_NAME, vanillaWindowTitle);
|
||||
glfwWindowHintString(GLFW_X11_INSTANCE_NAME, vanillaWindowTitle);
|
||||
|
||||
long primaryMonitor = glfwGetPrimaryMonitor();
|
||||
if (primaryMonitor == 0) {
|
||||
LOGGER.error("Failed to find a primary monitor - this means LWJGL isn't working properly");
|
||||
crashElegantly("Failed to locate a primary monitor.\nSDL_GetPrimaryDisplay failed.\n");
|
||||
crashElegantly("Failed to locate a primary monitor.\nglfwGetPrimaryMonitor failed.\n");
|
||||
throw new IllegalStateException("Can't find a primary monitor");
|
||||
}
|
||||
GLFWVidMode vidmode = glfwGetVideoMode(primaryMonitor);
|
||||
|
||||
var vidmode = SDL_GetDesktopDisplayMode(primaryMonitor);
|
||||
if (vidmode == null) {
|
||||
LOGGER.error("Failed to get the current display video mode.");
|
||||
crashElegantly("Failed to get current display resolution.\nSDL_GetDesktopDisplayMode failed.\n");
|
||||
crashElegantly("Failed to get current display resolution.\nglfwGetVideoMode failed.\n");
|
||||
throw new IllegalStateException("Can't get a resolution");
|
||||
}
|
||||
|
||||
long window = 0;
|
||||
var successfulWindow = new AtomicBoolean(false);
|
||||
var windowFailFuture = renderScheduler.schedule(() -> {
|
||||
if (!successfulWindow.get())
|
||||
crashElegantly("Timed out trying to setup the Game Window.");
|
||||
var windowFailFuture = renderScheduler.schedule(()->{
|
||||
if (!successfulWindow.get()) crashElegantly("Timed out trying to setup the Game Window.");
|
||||
}, 10, TimeUnit.SECONDS);
|
||||
|
||||
int versidx = 0;
|
||||
var skipVersions = FMLConfig.<String>getListConfigValue(FMLConfig.ConfigValue.EARLY_WINDOW_SKIP_GL_VERSIONS);
|
||||
boolean showHelpLog = FMLConfig.getBoolConfigValue(FMLConfig.ConfigValue.EARLY_WINDOW_LOG_HELP_MSG);
|
||||
|
||||
record Attempt(String vesion, String error) {}
|
||||
final List<Attempt> attempts = new ArrayList<>();
|
||||
String requestedVersion = null;
|
||||
|
||||
for (int x = 0; x < GL_VERSIONS.length; x++) {
|
||||
var version = GL_VERSIONS[x];
|
||||
requestedVersion = version[0] + "." + version[1];
|
||||
|
||||
if (skipVersions.contains(requestedVersion)) {
|
||||
LOGGER.info("Skipping GL version " + requestedVersion + " because of configuration");
|
||||
final String[] lastGLError = new String[GL_VERSIONS.length];
|
||||
do {
|
||||
final var glVersionToTry = GL_VERSIONS[versidx][0] + "." + GL_VERSIONS[versidx][1];
|
||||
if (skipVersions.contains(glVersionToTry)) {
|
||||
LOGGER.info("Skipping GL version "+ glVersionToTry+" because of configuration");
|
||||
versidx++;
|
||||
continue;
|
||||
}
|
||||
|
||||
LOGGER.info("Trying GL version " + requestedVersion);
|
||||
if (showHelpLog && x == 0) {
|
||||
LOGGER.info("Trying GL version " + glVersionToTry);
|
||||
if (showHelpLog && versidx == 0) {
|
||||
LOGGER.info("""
|
||||
If this message is the only thing at the bottom of your log before a crash, you probably have a driver issue.
|
||||
|
||||
@@ -425,105 +410,132 @@ public class DisplayWindow implements ImmediateWindowProvider {
|
||||
|
||||
You can safely ignore this message if the game starts up successfully.""");
|
||||
}
|
||||
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, version[0]);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, version[1]);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);
|
||||
SDL_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, GL_TRUE);
|
||||
window = SDL_CreateWindow(vanillaWindowTitle, winWidth, winHeight,
|
||||
SDL_WINDOW_OPENGL
|
||||
| SDL_WINDOW_RESIZABLE
|
||||
| SDL_WINDOW_HIGH_PIXEL_DENSITY
|
||||
);
|
||||
|
||||
if (window == 0) {
|
||||
var error = Objects.requireNonNullElse(SDLError.SDL_GetError(), "<no error>");
|
||||
attempts.add(new Attempt(requestedVersion, error));
|
||||
LOGGER.trace("Failed to create window using %d.%d: %s", version[0], version[1], error);
|
||||
} else {
|
||||
SDLVideo.SDL_SetWindowMinimumSize(window, 320, 240);
|
||||
LOGGER.info("Created window using SDL video driver: {}", SDLVideo.SDL_GetCurrentVideoDriver());
|
||||
break; // We got a valid window!
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, GL_VERSIONS[versidx][0]); // we try our versions one at a time
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, GL_VERSIONS[versidx][1]);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
||||
window = glfwCreateWindow(winWidth, winHeight, vanillaWindowTitle, 0L, 0L);
|
||||
var erridx = versidx;
|
||||
handleLastGLFWError((error, description) -> lastGLError[erridx] = String.format("Trying %d.%d: GLFW error: [0x%X]%s", GL_VERSIONS[erridx][0], GL_VERSIONS[erridx][1], error, description));
|
||||
if (lastGLError[versidx] != null) {
|
||||
LOGGER.trace(lastGLError[versidx]);
|
||||
}
|
||||
}
|
||||
versidx++;
|
||||
} while (window == 0 && versidx < GL_VERSIONS.length);
|
||||
// LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(12));
|
||||
if (versidx== GL_VERSIONS.length && window == 0) {
|
||||
LOGGER.error("Failed to find any valid GLFW profile. "+lastGLError[0]);
|
||||
|
||||
if (window == 0) {
|
||||
LOGGER.error("Failed to find any valid GLFW profile.");
|
||||
var message = new StringBuilder()
|
||||
.append("Failed to find a valid GLFW profile.\n");
|
||||
|
||||
if (attempts.isEmpty()) {
|
||||
message.append("All GL Versions were skipped");
|
||||
} else {
|
||||
message.append("We tried:");
|
||||
for (var attempt : attempts)
|
||||
message.append("\n\t").append(attempt.vesion).append(':').append(attempt.error);
|
||||
}
|
||||
|
||||
crashElegantly(message.toString());
|
||||
crashElegantly("Failed to find a valid GLFW profile.\nWe tried "+
|
||||
Arrays.stream(GL_VERSIONS).map(p->p[0]+"."+p[1]).filter(o -> !skipVersions.contains(o))
|
||||
.collect(Collector.of(()->new StringJoiner(", ").setEmptyValue("no versions"), StringJoiner::add, StringJoiner::merge, StringJoiner::toString))+
|
||||
" but none of them worked.\n"+ Arrays.stream(lastGLError).filter(Objects::nonNull).collect(Collectors.joining("\n")));
|
||||
throw new IllegalStateException("Failed to create a GLFW window with any profile");
|
||||
}
|
||||
|
||||
successfulWindow.set(true);
|
||||
if (!windowFailFuture.cancel(true))
|
||||
throw new IllegalStateException("We died but didn't somehow?");
|
||||
|
||||
try (var stack = org.lwjgl.system.MemoryStack.stackPush()) {
|
||||
var majBuf = stack.mallocInt(1);
|
||||
var minBuf = stack.mallocInt(1);
|
||||
SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, majBuf);
|
||||
SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, minBuf);
|
||||
this.glVersion = majBuf.get(0) + "." + minBuf.get(0);
|
||||
}
|
||||
|
||||
LOGGER.info("Requested GL version " + requestedVersion + " got version " + this.glVersion);
|
||||
if (!windowFailFuture.cancel(true)) throw new IllegalStateException("We died but didn't somehow?");
|
||||
var requestedVersion = GL_VERSIONS[versidx-1][0]+"."+GL_VERSIONS[versidx-1][1];
|
||||
var maj = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MAJOR);
|
||||
var min = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MINOR);
|
||||
var gotVersion = maj+"."+min;
|
||||
LOGGER.info("Requested GL version "+requestedVersion+" got version "+gotVersion);
|
||||
this.glVersion = gotVersion;
|
||||
this.window = window;
|
||||
|
||||
if (showHelpLog)
|
||||
FMLConfig.updateConfig(FMLConfig.ConfigValue.EARLY_WINDOW_LOG_HELP_MSG, false);
|
||||
|
||||
if (this.maximized)
|
||||
SDL_MaximizeWindow(window);
|
||||
int[] x = new int[1];
|
||||
int[] y = new int[1];
|
||||
glfwGetMonitorPos(primaryMonitor, x, y);
|
||||
int monitorX = x[0];
|
||||
int monitorY = y[0];
|
||||
// glfwSetWindowSizeLimits(window, 854, 480, GLFW_DONT_CARE, GLFW_DONT_CARE);
|
||||
if (this.maximized) {
|
||||
glfwMaximizeWindow(window);
|
||||
}
|
||||
|
||||
var size = getWindowSize(window);
|
||||
this.onWindowResize(size.x, size.y);
|
||||
glfwGetWindowSize(window, x, y);
|
||||
this.winWidth = x[0];
|
||||
this.winHeight = y[0];
|
||||
|
||||
var monitor = getMonitorSize(primaryMonitor);
|
||||
if (monitor != null)
|
||||
SDL_SetWindowPosition(window, (monitor.width - size.x) / 2 + monitor.x, (monitor.height - size.y) / 2 + monitor.y);
|
||||
// Setting the window position isn't supported on wayland, so check the error here
|
||||
glfwSetWindowPos(window, (vidmode.width() - this.winWidth) / 2 + monitorX, (vidmode.height() - this.winHeight) / 2 + monitorY);
|
||||
handleLastGLFWError();
|
||||
|
||||
pollEvents();
|
||||
// Attempt setting the icon
|
||||
// int[] channels = new int[1];
|
||||
// try (var glfwImgBuffer = GLFWImage.create(MemoryUtil.getAllocator().malloc(GLFWImage.SIZEOF), 1)) {
|
||||
// final ByteBuffer imgBuffer;
|
||||
// try (GLFWImage glfwImages = GLFWImage.malloc()) {
|
||||
// imgBuffer = STBHelper.loadImageFromClasspath("forge_logo.png", 20000, x, y, channels);
|
||||
// glfwImgBuffer.put(glfwImages.set(x[0], y[0], imgBuffer));
|
||||
// glfwSetWindowIcon(window, glfwImgBuffer);
|
||||
// STBImage.stbi_image_free(imgBuffer);
|
||||
// }
|
||||
// } catch (NullPointerException e) {
|
||||
// System.err.println("Failed to load forge logo");
|
||||
// }
|
||||
// handleLastGLFWError((error, description) -> LOGGER.debug(String.format("Suppressing GLFW icon error: [0x%X]%s", error, description)));
|
||||
|
||||
SDL_ShowWindow(window);
|
||||
glfwSetFramebufferSizeCallback(window, this::fbResize);
|
||||
glfwSetWindowPosCallback(window, this::winMove);
|
||||
glfwSetWindowSizeCallback(window, this::winResize);
|
||||
|
||||
// Show the window
|
||||
glfwShowWindow(window);
|
||||
// Getting the window position isn't supported on wayland, so check the error here
|
||||
glfwGetWindowPos(window, x, y);
|
||||
handleLastGLFWError();
|
||||
|
||||
this.winX = x[0];
|
||||
this.winY = y[0];
|
||||
glfwGetFramebufferSize(window, x, y);
|
||||
this.fbWidth = x[0];
|
||||
this.fbHeight = y[0];
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
private record Point(int x, int y) {}
|
||||
private record Rect(int x, int y, int width, int height) {}
|
||||
|
||||
private static @Nullable Rect getMonitorSize(int monitor) {
|
||||
try (var bounds = SDL_Rect.malloc()) {
|
||||
// Fetch the display bounds for the current index
|
||||
if (SDL_GetDisplayBounds(monitor, bounds)) {
|
||||
int x = bounds.x();
|
||||
int y = bounds.y();
|
||||
int width = bounds.w();
|
||||
int height = bounds.h();
|
||||
LOGGER.info("Display {} Bounds -> X: {}, Y: {}, Width: {}, Height: {}", monitor, x, y, width, height);
|
||||
return new Rect(x, y, width, height);
|
||||
} else {
|
||||
LOGGER.warn("Could not get bounds for display: " + SDL_GetError());
|
||||
return null;
|
||||
private static void handleLastGLFWError() {
|
||||
handleLastGLFWError((error, description) -> {
|
||||
if (error == GLFW_FEATURE_UNAVAILABLE) {
|
||||
// suppress window pos errors for unsupported platforms (wayland)
|
||||
LOGGER.debug(String.format("Suppressing GLFW error: [0x%X]%s", error, description));
|
||||
return;
|
||||
}
|
||||
|
||||
throw new IllegalStateException(String.format("GLFW error: [0x%X]%s", error, description));
|
||||
});
|
||||
}
|
||||
|
||||
private void winResize(long window, int width, int height) {
|
||||
if (window == this.window && width != 0 && height != 0) {
|
||||
this.winWidth = width;
|
||||
this.winHeight = height;
|
||||
}
|
||||
}
|
||||
private void fbResize(long window, int width, int height) {
|
||||
if (window == this.window && width != 0 && height != 0) {
|
||||
this.fbWidth = width;
|
||||
this.fbHeight = height;
|
||||
}
|
||||
}
|
||||
|
||||
private static Point getWindowSize(long window) {
|
||||
try (var stack = MemoryStack.stackPush()) {
|
||||
var width = stack.mallocInt(1);
|
||||
var height = stack.mallocInt(1);
|
||||
SDL_GetWindowSize(window, width, height);
|
||||
return new Point(width.get(0), height.get(0));
|
||||
private void winMove(long window, int x, int y) {
|
||||
if (window == this.window) {
|
||||
this.winX = x;
|
||||
this.winY = y;
|
||||
}
|
||||
}
|
||||
private static void handleLastGLFWError(BiConsumer<Integer, String> handler) {
|
||||
try (MemoryStack memorystack = MemoryStack.stackPush()) {
|
||||
PointerBuffer pointerbuffer = memorystack.mallocPointer(1);
|
||||
int error = glfwGetError(pointerbuffer);
|
||||
if (error != GLFW_NO_ERROR) {
|
||||
long pDescription = pointerbuffer.get();
|
||||
String description = pDescription == 0L ? "" : MemoryUtil.memUTF8(pDescription);
|
||||
handler.accept(error, description);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -533,8 +545,7 @@ public class DisplayWindow implements ImmediateWindowProvider {
|
||||
*
|
||||
* @return the Window we own.
|
||||
*/
|
||||
@Override
|
||||
public long setupMinecraftWindow(final int width, final int height, final String title, final Supplier<Object> backend) {
|
||||
public long setupMinecraftWindow(final int width, final int height, final String title, final long monitorSupplier, final Supplier<Object> backend) {
|
||||
// wait for the window to actually be initialized
|
||||
try {
|
||||
this.initializationFuture.get(30, TimeUnit.SECONDS);
|
||||
@@ -566,10 +577,14 @@ public class DisplayWindow implements ImmediateWindowProvider {
|
||||
// we don't want the lock, just making sure it's back on the main thread
|
||||
renderLock.release();
|
||||
|
||||
SDL_GL_MakeCurrent(window, sdlContext);
|
||||
glfwMakeContextCurrent(window);
|
||||
// Set the title to what the game wants
|
||||
SDL_SetWindowTitle(window, title);
|
||||
SDL_GL_SetSwapInterval(0); // Disable vsync, let Minecraft control it
|
||||
glfwSetWindowTitle(window, title);
|
||||
glfwSwapInterval(0);
|
||||
// Clean up our hooks
|
||||
glfwSetFramebufferSizeCallback(window, null).free();
|
||||
glfwSetWindowPosCallback(window, null).free();
|
||||
glfwSetWindowSizeCallback(window, null).free();
|
||||
this.repaintTick = this::renderThreadFunc; // the repaint will continue to be called until the overlay takes over
|
||||
this.windowTick = null; // this tells the render thread that the async ticker is done
|
||||
return window;
|
||||
@@ -635,7 +650,7 @@ public class DisplayWindow implements ImmediateWindowProvider {
|
||||
|
||||
@Override
|
||||
public void periodicTick() {
|
||||
pollEvents();
|
||||
glfwPollEvents();
|
||||
repaintTick.run();
|
||||
}
|
||||
|
||||
@@ -650,67 +665,4 @@ public class DisplayWindow implements ImmediateWindowProvider {
|
||||
this.context.elementShader().close();
|
||||
SimpleBufferBuilder.destroy();
|
||||
}
|
||||
|
||||
private void bindGlContext() {
|
||||
SDL_GL_MakeCurrent(window, sdlContext);
|
||||
//if (!SDL_GL_MakeCurrent(window, sdlContext))
|
||||
// throw new IllegalStateException("Failed to make OpenGL context current: " + SDL_GetError());
|
||||
}
|
||||
|
||||
private void releaseGlContext() {
|
||||
SDL_GL_MakeCurrent(window, 0);
|
||||
}
|
||||
|
||||
|
||||
private void pollEvents() {
|
||||
try (var event = SDL_Event.malloc()) {
|
||||
while (SDL_PollEvent(event)) {
|
||||
switch (event.type()) {
|
||||
case SDL_EVENT_WINDOW_MOVED:
|
||||
this.onWindowMove(event.window().data1(), event.window().data2());
|
||||
break;
|
||||
case SDL_EVENT_WINDOW_RESIZED:
|
||||
this.onWindowResize(event.window().data1(), event.window().data2());
|
||||
break;
|
||||
case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:
|
||||
this.onFrameBufferResize(event.window().data1(), event.window().data2());
|
||||
break;
|
||||
|
||||
/*
|
||||
We were told to quit for some reason, find a way to abort?
|
||||
case SDL_EVENT_QUIT:
|
||||
case SDL_EVENT_WINDOW_CLOSE_REQUESTED:
|
||||
case SDL_EVENT_TERMINATING:
|
||||
|
||||
Window was minimized or restored, maybe stop rendering?
|
||||
case SDL_EVENT_WINDOW_MINIMIZED:
|
||||
case SDL_EVENT_WINDOW_MAXIMIZED:
|
||||
case SDL_EVENT_WINDOW_RESTORED:
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void onWindowResize(int width, int height) {
|
||||
if (width == 0 || height == 0)
|
||||
return;
|
||||
|
||||
this.winWidth = width;
|
||||
this.winHeight = height;
|
||||
}
|
||||
|
||||
private void onFrameBufferResize(int width, int height) {
|
||||
if (width == 0 || height == 0)
|
||||
return;
|
||||
|
||||
this.fbWidth = width;
|
||||
this.fbHeight = height;
|
||||
}
|
||||
|
||||
private void onWindowMove(int x, int y) {
|
||||
this.winX = x;
|
||||
this.winY = y;
|
||||
}
|
||||
|
||||
}
|
||||
+22
-8
@@ -11,6 +11,8 @@ import net.minecraftforge.fml.loading.progress.StartupNotificationManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static org.lwjgl.opengl.GL32C.*;
|
||||
|
||||
public class RenderElement {
|
||||
@@ -37,6 +39,11 @@ public class RenderElement {
|
||||
void accept(SimpleBufferBuilder bb, DisplayContext context, int[] size, int frame);
|
||||
}
|
||||
|
||||
/** @deprecated Use {@link Renderer} directly. This was always eagerly resolved, making it an unnecessary wrapper. */
|
||||
@Deprecated(since = "1.21.5", forRemoval = true)
|
||||
@FunctionalInterface
|
||||
interface Initializer extends Supplier<Renderer> {}
|
||||
|
||||
@FunctionalInterface
|
||||
interface TextGenerator {
|
||||
void accept(SimpleBufferBuilder bb, SimpleFont fh, DisplayContext ctx);
|
||||
@@ -52,6 +59,13 @@ public class RenderElement {
|
||||
}
|
||||
}
|
||||
|
||||
/** @deprecated Use {@link RenderElement#RenderElement(Renderer)} instead */
|
||||
@Deprecated(since = "1.21.5", forRemoval = true)
|
||||
public RenderElement(final Initializer rendererInitializer) {
|
||||
this.bb = new SimpleBufferBuilder(1);
|
||||
this.renderer = rendererInitializer.get();
|
||||
}
|
||||
|
||||
public RenderElement(Renderer renderer) {
|
||||
this.bb = new SimpleBufferBuilder(1);
|
||||
this.renderer = renderer;
|
||||
@@ -102,7 +116,7 @@ public class RenderElement {
|
||||
}
|
||||
|
||||
public static RenderElement forgeVersionOverlay(SimpleFont font, String version) {
|
||||
return new RenderElement(RenderElement.initializeText(font, (bb, _, ctx)->
|
||||
return new RenderElement(RenderElement.initializeText(font, (bb, fnt, ctx)->
|
||||
font.generateVerticesForTexts(ctx.scaledWidth() - font.stringWidth(version) - 10,
|
||||
ctx.scaledHeight() - font.lineSpacing() + font.descent() - 10, bb,
|
||||
new SimpleFont.DisplayText(version, ctx.colourScheme.foreground().packedint(RenderElement.globalAlpha)))));
|
||||
@@ -164,11 +178,11 @@ public class RenderElement {
|
||||
var colour = (alpha << 24) | 0xFFFFFF;
|
||||
Renderer bar;
|
||||
if (pm.steps() == 0) {
|
||||
bar = progressBar(ctx->new int[] {(ctx.scaledWidth() - BAR_WIDTH * ctx.scale()) / 2, y + font.lineSpacing() - font.descent(), BAR_WIDTH * ctx.scale()}, _->colour, frame -> indeterminateBar(frame, cnt == 0));
|
||||
bar = progressBar(ctx->new int[] {(ctx.scaledWidth() - BAR_WIDTH * ctx.scale()) / 2, y + font.lineSpacing() - font.descent(), BAR_WIDTH * ctx.scale()}, f->colour, frame -> indeterminateBar(frame, cnt == 0));
|
||||
} else {
|
||||
bar = progressBar(ctx -> new int[]{(ctx.scaledWidth() - BAR_WIDTH * ctx.scale()) / 2, y + font.lineSpacing() - font.descent(), BAR_WIDTH * ctx.scale()}, _ -> colour, _ -> new float[]{0f, pm.progress()});
|
||||
bar = progressBar(ctx -> new int[]{(ctx.scaledWidth() - BAR_WIDTH * ctx.scale()) / 2, y + font.lineSpacing() - font.descent(), BAR_WIDTH * ctx.scale()}, f -> colour, f -> new float[]{0f, pm.progress()});
|
||||
}
|
||||
Renderer label = (bb, ctx, _) -> renderText(font, text((ctx.scaledWidth() - BAR_WIDTH * ctx.scale()) / 2, y, pm.label().getText(), colour), bb, ctx);
|
||||
Renderer label = (bb, ctx, frame) -> renderText(font, text((ctx.scaledWidth() - BAR_WIDTH * ctx.scale()) / 2, y, pm.label().getText(), colour), bb, ctx);
|
||||
return bar.then(label);
|
||||
}
|
||||
private static float[] indeterminateBar(int frame, boolean isActive) {
|
||||
@@ -184,9 +198,9 @@ public class RenderElement {
|
||||
var y = 10 * context.scale();
|
||||
PerformanceInfo pi = context.performance();
|
||||
final int colour = hsvToRGB((1.0f - (float)Math.pow(pi.memory(), 1.5f)) / 3f, 1.0f, 0.5f);
|
||||
var bar = progressBar(ctx -> new int[]{(ctx.scaledWidth() - BAR_WIDTH * ctx.scale()) / 2, y, BAR_WIDTH * ctx.scale()}, _ -> colour, _ -> new float[]{0f, pi.memory()});
|
||||
var bar = progressBar(ctx -> new int[]{(ctx.scaledWidth() - BAR_WIDTH * ctx.scale()) / 2, y, BAR_WIDTH * ctx.scale()}, f -> colour, f -> new float[]{0f, pi.memory()});
|
||||
var width = font.stringWidth(pi.text());
|
||||
Renderer label = (bb, ctx, _) -> renderText(font, text(ctx.scaledWidth() / 2 - width / 2, y + 18, pi.text(), context.colourScheme.foreground().packedint(globalAlpha)), bb, ctx);
|
||||
Renderer label = (bb, ctx, frame) -> renderText(font, text(ctx.scaledWidth() / 2 - width / 2, y + 18, pi.text(), context.colourScheme.foreground().packedint(globalAlpha)), bb, ctx);
|
||||
bar.then(label).accept(buffer, context, frameNumber);
|
||||
}
|
||||
|
||||
@@ -236,7 +250,7 @@ public class RenderElement {
|
||||
}
|
||||
|
||||
private static Renderer initializeText(SimpleFont font, TextGenerator textGenerator) {
|
||||
return (bb, context, _) -> renderText(font, textGenerator, bb, context);
|
||||
return (bb, context, frame) -> renderText(font, textGenerator, bb, context);
|
||||
}
|
||||
|
||||
private static void renderText(final SimpleFont font, final TextGenerator textGenerator, final SimpleBufferBuilder bb, final DisplayContext context) {
|
||||
@@ -248,7 +262,7 @@ public class RenderElement {
|
||||
}
|
||||
|
||||
private static TextGenerator text(int x, int y, String text, int colour) {
|
||||
return (bb, font, _) -> font.generateVerticesForTexts(x, y, bb, new SimpleFont.DisplayText(text, colour));
|
||||
return (bb, font, context) -> font.generateVerticesForTexts(x, y, bb, new SimpleFont.DisplayText(text, colour));
|
||||
}
|
||||
|
||||
private static Renderer initializeTexture(final String textureFileName, int size, int textureNumber, TextureRenderer positionAndColour) {
|
||||
|
||||
@@ -136,7 +136,7 @@ public class RuntimeEnumExtender implements ILaunchPluginService {
|
||||
classNode.methods.stream().filter(m -> m.name.equals("<init>")).forEach(m -> sb.append(" : ").append(m.desc).append("\n"));
|
||||
LOGGER.error(LogUtils.FATAL_MARKER, sb.toString());
|
||||
}
|
||||
throw new IllegalStateException("Enum has create method with no matching constructor: " + classType.getClassName() + " " + desc);
|
||||
throw new IllegalStateException("Enum has create method with no matching constructor: " + desc);
|
||||
}
|
||||
|
||||
if (values == null)
|
||||
|
||||
@@ -109,7 +109,7 @@ public class FMLConfig
|
||||
}
|
||||
if (!configSpec.isCorrect(configData)) {
|
||||
LOGGER.warn(CORE, "Configuration file {} is not correct. Correcting", configFile);
|
||||
configSpec.correct(configData, (_, path, incorrectValue, correctedValue) ->
|
||||
configSpec.correct(configData, (action, path, incorrectValue, correctedValue) ->
|
||||
LOGGER.info(CORE, "Incorrect key {} was corrected from {} to {}", path, incorrectValue, correctedValue));
|
||||
}
|
||||
configData.putAllComments(configComments);
|
||||
|
||||
@@ -20,8 +20,8 @@ public class FMLEnvironment
|
||||
public static final boolean secureJarsEnabled = FMLLoader.isSecureJarEnabled();
|
||||
|
||||
static void setupInteropEnvironment(IEnvironment environment) {
|
||||
environment.computePropertyIfAbsent(IEnvironment.Keys.NAMING.get(), _->naming);
|
||||
environment.computePropertyIfAbsent(Environment.Keys.DIST.get(), _->dist);
|
||||
environment.computePropertyIfAbsent(IEnvironment.Keys.NAMING.get(), v->naming);
|
||||
environment.computePropertyIfAbsent(Environment.Keys.DIST.get(), v->dist);
|
||||
}
|
||||
|
||||
public static class Keys {
|
||||
|
||||
@@ -12,6 +12,7 @@ import net.minecraftforge.forgespi.Environment;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
@@ -41,7 +42,7 @@ public class FMLServiceProvider implements ITransformationService {
|
||||
LOGGER.debug(CORE, "Loading configuration");
|
||||
FMLConfig.load();
|
||||
LOGGER.debug(CORE, "Preparing ModFile");
|
||||
environment.computePropertyIfAbsent(Environment.Keys.MODFILEFACTORY.get(), _->ModFile::new);
|
||||
environment.computePropertyIfAbsent(Environment.Keys.MODFILEFACTORY.get(), k->ModFile::new);
|
||||
LOGGER.debug(CORE, "Preparing launch handler");
|
||||
FMLLoader.setupLaunchHandler(environment, arguments);
|
||||
FMLEnvironment.setupInteropEnvironment(environment);
|
||||
|
||||
@@ -10,13 +10,8 @@ import net.minecraftforge.fml.loading.progress.StartupNotificationManager;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import joptsimple.OptionParser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.function.*;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -46,64 +41,18 @@ public class ImmediateWindowHandler {
|
||||
if (provider == null) {
|
||||
LOGGER.info("Failed to find ImmediateWindowProvider {}, disabling", providername);
|
||||
provider = new DummyProvider();
|
||||
} else {
|
||||
var backend = findBackend(arguments);
|
||||
var newProvider = provider.selectBackend(backend);
|
||||
if (provider != newProvider) {
|
||||
if (newProvider == null)
|
||||
newProvider = new DummyProvider();
|
||||
|
||||
LOGGER.info("ImmediateWindowProvider {} does not support {}, switching to {}", provider.name(), backend, newProvider.name());
|
||||
provider = newProvider;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Only update config if the provider isn't the dummy provider
|
||||
if (!Objects.equals(provider.name(), "dummyprovider"))
|
||||
FMLConfig.updateConfig(FMLConfig.ConfigValue.EARLY_WINDOW_PROVIDER, provider.name());
|
||||
|
||||
FMLLoader.progressWindowTick = provider.initialize(arguments);
|
||||
earlyProgress = StartupNotificationManager.addProgressBar("EARLY", 0);
|
||||
earlyProgress.label("Bootstrapping Minecraft");
|
||||
}
|
||||
|
||||
private static String findBackend(String[] arguments) {
|
||||
// Try and parse from the command line arguments
|
||||
var parser = new OptionParser();
|
||||
var backendOption = parser.accepts("graphicsBackend").withRequiredArg();
|
||||
parser.allowsUnrecognizedOptions();
|
||||
var parsed = parser.parse(arguments);
|
||||
|
||||
if (parsed.has(backendOption))
|
||||
return parsed.valueOf(backendOption).toLowerCase(Locale.ENGLISH);
|
||||
|
||||
|
||||
// Read the options.txt if it exists.
|
||||
var optionsFile = FMLPaths.GAMEDIR.get().resolve(Path.of("options.txt"));
|
||||
if (!Files.exists(optionsFile)) // Default is OpenGL first
|
||||
return "default";
|
||||
|
||||
List<String> lines = null;
|
||||
try {
|
||||
lines = Files.readAllLines(optionsFile);
|
||||
} catch (IOException e) {
|
||||
return "default"; // We failed to read for some reason, assume we're using the default.
|
||||
}
|
||||
|
||||
final String key = "preferredGraphicsBackend:";
|
||||
for (var line : lines) {
|
||||
if (line.startsWith(key)) {
|
||||
var backend = line.substring(key.length() + 1, line.length() - 1);
|
||||
return backend.toLowerCase(Locale.ENGLISH);
|
||||
}
|
||||
}
|
||||
|
||||
return "default";
|
||||
}
|
||||
|
||||
public static long setupMinecraftWindow(final int width, final int height, final String title, final Supplier<Object> backend) {
|
||||
return provider.setupMinecraftWindow(width, height, title, backend);
|
||||
public static long setupMinecraftWindow(final int width, final int height, final String title, final long monitor, final Supplier<Object> backend) {
|
||||
return provider.setupMinecraftWindow(width, height, title, monitor, backend);
|
||||
}
|
||||
|
||||
public static boolean positionWindow(Optional<Object> monitor,IntConsumer widthSetter, IntConsumer heightSetter, IntConsumer xSetter, IntConsumer ySetter) {
|
||||
@@ -134,7 +83,7 @@ public class ImmediateWindowHandler {
|
||||
earlyProgress.label(message);
|
||||
}
|
||||
|
||||
record DummyProvider() implements ImmediateWindowProvider {
|
||||
private record DummyProvider() implements ImmediateWindowProvider {
|
||||
private static Method NV_HANDOFF;
|
||||
private static Method NV_POSITION;
|
||||
private static Method NV_OVERLAY;
|
||||
@@ -155,9 +104,9 @@ public class ImmediateWindowHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long setupMinecraftWindow(final int width, final int height, final String title, final Supplier<Object> backend) {
|
||||
public long setupMinecraftWindow(final int width, final int height, final String title, final long monitor, final Supplier<Object> backend) {
|
||||
try {
|
||||
var longsupplier = (LongSupplier)NV_HANDOFF.invoke(null, width, height, title, backend);
|
||||
var longsupplier = (LongSupplier)NV_HANDOFF.invoke(null, width, height, title, monitor, backend);
|
||||
return longsupplier.getAsLong();
|
||||
} catch (Throwable e) {
|
||||
throw new IllegalStateException("How did you get here?", e);
|
||||
|
||||
+2
-26
@@ -24,36 +24,11 @@ import java.util.function.Supplier;
|
||||
* No doubt many more things can be said here.
|
||||
*/
|
||||
public interface ImmediateWindowProvider {
|
||||
/**
|
||||
* Returns a new instance of ImmediateWindowProvider which just bounces to the vanilla code.
|
||||
* This can be useful when you want to disable your provider and defer to vanilla behavior for some reason.
|
||||
*/
|
||||
public static ImmediateWindowProvider getFallbackHandler() {
|
||||
return new ImmediateWindowHandler.DummyProvider();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The name of this window provider. Do NOT use fmlearlywindow.
|
||||
*/
|
||||
String name();
|
||||
|
||||
/**
|
||||
* This is called before initialize, but after reading the preferred graphics backend config value from the user's
|
||||
* options.txt or command line.
|
||||
*
|
||||
* If you do not support the requested backend, you can return a new ImmediateWindowProvider that does.
|
||||
* {@link #getFallbackHandler()} can be used to get an instance that falls back to Vanilla's code effectively
|
||||
* disabling the early loading screen.
|
||||
*
|
||||
* @param backend - The backend the user has selected, known values: "default", "opengl", and "vulkan". However this
|
||||
* is read from the config file, or command line arguments so could be anything.
|
||||
* Default and OpenGL are treated the same, attempting to load OpenGL first, then Vulkan.
|
||||
* Vulkan attempts to load Vulkan first then OpenGL
|
||||
*/
|
||||
default ImmediateWindowProvider selectBackend(String backend) {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called very early on to initialize ourselves. Use this to initialize the window and other GL core resources.
|
||||
*
|
||||
@@ -86,9 +61,10 @@ public interface ImmediateWindowProvider {
|
||||
* @param width This is the width of the window Mojang expects
|
||||
* @param height This is the height of the Window Mojang expects.
|
||||
* @param title This is the title for the window.
|
||||
* @param monitor This is the monitor it should appear on.
|
||||
* @return The window id
|
||||
*/
|
||||
long setupMinecraftWindow(final int width, final int height, final String title, final Supplier<Object> backend);
|
||||
long setupMinecraftWindow(final int width, final int height, final String title, final long monitor, final Supplier<Object> backend);
|
||||
|
||||
/**
|
||||
* This is called after window handoff to allow us to tell Mojang about our window's position. This might give a
|
||||
|
||||
@@ -7,6 +7,7 @@ package net.minecraftforge.fml.loading;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import cpw.mods.modlauncher.api.INameMappingService;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
package net.minecraftforge.fml.loading;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
/**
|
||||
* Convert a maven coordinate into a Path.
|
||||
|
||||
@@ -26,7 +26,6 @@ public class StringUtils {
|
||||
return java.util.stream.Stream.of(endings).anyMatch(lowerSearch::endsWith);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static URL toURL(final String string) {
|
||||
if (string == null || string.trim().isEmpty() || string.contains("myurl.me") || string.contains("example.invalid"))
|
||||
return null;
|
||||
|
||||
@@ -13,6 +13,7 @@ import org.jetbrains.annotations.ApiStatus;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiPredicate;
|
||||
|
||||
@ApiStatus.Internal // since 1.21.1, will be made non-public in a later MC version
|
||||
public class VersionSupportMatrix {
|
||||
|
||||
+2
-1
@@ -7,6 +7,7 @@ package net.minecraftforge.fml.loading.moddiscovery;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import net.minecraftforge.fml.loading.ImmediateWindowHandler;
|
||||
import net.minecraftforge.fml.loading.LoadingModList;
|
||||
import net.minecraftforge.fml.loading.LogMarkers;
|
||||
import net.minecraftforge.forgespi.language.ModFileScanData;
|
||||
import org.slf4j.Logger;
|
||||
@@ -55,7 +56,7 @@ public final class BackgroundScanHandler {
|
||||
ImmediateWindowHandler.updateProgress("Scanning mod candidates");
|
||||
CompletableFuture<ModFileScanData> future = CompletableFuture.supplyAsync(file::compileContent, modContentScanner)
|
||||
.whenComplete(file::setScanResult);
|
||||
if (DEBUG) future = future.whenComplete((_, t) -> addCompletedFile(file, t));
|
||||
if (DEBUG) future = future.whenComplete((r, t) -> addCompletedFile(file, t));
|
||||
file.setFutureScanResult(future);
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -24,7 +24,7 @@ public enum InvalidModIdentifier {
|
||||
LITELOADER(filePresent("litemod.json")),
|
||||
OPTIFINE(filePresent("optifine/Installer.class")),
|
||||
BUKKIT(filePresent("plugin.yml")),
|
||||
INVALIDZIP((_,zf) -> zf.isEmpty()); // note: only this one INVALIDZIP check is ran until the todo on this class is fixed
|
||||
INVALIDZIP((f,zf) -> zf.isEmpty()); // note: only this one INVALIDZIP check is ran until the todo on this class is fixed
|
||||
|
||||
private final BiPredicate<Path, Optional<ZipFile>> ident;
|
||||
|
||||
@@ -51,7 +51,7 @@ public enum InvalidModIdentifier {
|
||||
|
||||
private static BiPredicate<Path, Optional<ZipFile>> filePresent(String filename)
|
||||
{
|
||||
return (_, zfo) -> zfo.map(zf -> zf.getEntry(filename) != null).orElse(false);
|
||||
return (f, zfo) -> zfo.map(zf -> zf.getEntry(filename) != null).orElse(false);
|
||||
}
|
||||
|
||||
private static <T> Optional<T> optionalFromException(Supplier_WithExceptions<T, ? extends Exception> supp)
|
||||
|
||||
+1
-1
@@ -145,7 +145,7 @@ public class JarInJarDependencyLocator extends AbstractModProvider implements ID
|
||||
var ids = new TreeMap<String, List<Entry>>();
|
||||
for (var entry : selector.entries.values()) {
|
||||
if (entry != FAILED && entry.coord != null)
|
||||
ids.computeIfAbsent(entry.coord, _ -> new ArrayList<>()).add(entry);
|
||||
ids.computeIfAbsent(entry.coord, id -> new ArrayList<>()).add(entry);
|
||||
}
|
||||
|
||||
for (var entry : ids.entrySet()) {
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ public final class MinecraftLocator extends AbstractModProvider implements IModL
|
||||
|
||||
// Minecraft itself.
|
||||
var meta = new ModJarMetadata();
|
||||
var mcjar = SecureJar.from(_ -> meta, paths);
|
||||
var mcjar = SecureJar.from(jar -> meta, paths);
|
||||
var mc = ModFileFactory.FACTORY.build(mcjar, this, MinecraftLocator::buildMinecraftTOML);
|
||||
meta.setModFile(mc);
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ package net.minecraftforge.fml.loading.moddiscovery;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import cpw.mods.jarhandling.SecureJar;
|
||||
import net.minecraftforge.fml.loading.FMLLoader;
|
||||
import net.minecraftforge.fml.loading.LanguageLoadingProvider;
|
||||
import net.minecraftforge.fml.loading.LogMarkers;
|
||||
import net.minecraftforge.forgespi.language.IModFileInfo;
|
||||
@@ -25,6 +26,7 @@ import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
+3
-5
@@ -35,18 +35,16 @@ public class ModFileParser {
|
||||
LOGGER.warn(LogMarkers.LOADING, "Mod file {} is missing mods.toml file", modFile.getFilePath());
|
||||
return null;
|
||||
}
|
||||
|
||||
final FileConfig fileConfig = FileConfig.builder(modsjson).build();
|
||||
try {
|
||||
final FileConfig fileConfig = FileConfig.builder(modsjson).build();
|
||||
fileConfig.load();
|
||||
fileConfig.close();
|
||||
final NightConfigWrapper configWrapper = new NightConfigWrapper(fileConfig);
|
||||
return new ModFileInfo(modFile, configWrapper, configWrapper::setFile);
|
||||
} catch (ParsingException e) { // Handle landmine toml errors, e.g. incorrectly ported mods.
|
||||
} catch (ParsingException e) {
|
||||
LOGGER.error("Mod candidate {} contains a corrupt or misconfigured toml.", modFile.getFileName());
|
||||
throw new ModFileLoadingException("Mod candidate " + modFile.getFileName() + " contains a corrupt or misconfigured toml.");
|
||||
} catch (Exception other) { // Otherwise this is just someone who (probably) forgot a comma or something.
|
||||
LOGGER.error("Mod candidate {}'s toml .", modFile.getFileName());
|
||||
throw new ModFileLoadingException("Mod candidate " + modFile.getFileName() + " contains broken toml, likely due to a typo.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -56,7 +56,7 @@ public class StartupNotificationManager {
|
||||
private synchronized static void addMessage(Message.MessageType type, String message, int maxSize)
|
||||
{
|
||||
EnumMap<Message.MessageType, List<Message>> newMessages = new EnumMap<>(messages);
|
||||
newMessages.compute(type, (_, existingList) -> {
|
||||
newMessages.compute(type, (key, existingList) -> {
|
||||
List<Message> newList = new ArrayList<>();
|
||||
if (existingList != null)
|
||||
{
|
||||
|
||||
+1
-1
@@ -141,7 +141,7 @@ abstract class CommonDevLaunchHandler extends CommonLaunchHandler {
|
||||
protected static Path getForgeOnly(Path forge) {
|
||||
var packages = getPackages(); // Pulled out so it is passed to the lambda as value
|
||||
// We need to separate out our resources/code so that we can show up as a different data pack.
|
||||
var modJar = SecureJar.from((path, _) -> {
|
||||
var modJar = SecureJar.from((path, base) -> {
|
||||
if (!path.endsWith(".class")) return true;
|
||||
for (var pkg : packages)
|
||||
if (path.startsWith(pkg)) return true;
|
||||
|
||||
@@ -112,7 +112,7 @@ public final class ForgeDevLocator extends AbstractModProvider implements IModLo
|
||||
|
||||
// We want just the class files from the root of the input paths. So make a new union with a filter.
|
||||
var classes = UnionHelper.newFileSystem(
|
||||
(name, _) -> {
|
||||
(name, base) -> {
|
||||
if (name.endsWith("/")) {
|
||||
if (name.startsWith("/"))
|
||||
name = name.substring(1);
|
||||
@@ -164,7 +164,7 @@ public final class ForgeDevLocator extends AbstractModProvider implements IModLo
|
||||
if ("value".equals(key)) {
|
||||
int idx = clsName.lastIndexOf('/');
|
||||
var pkg = clsName.substring(0, idx);
|
||||
mods.computeIfAbsent(pkg, _ -> new HashSet<>()).add((String)value);
|
||||
mods.computeIfAbsent(pkg, k -> new HashSet<>()).add((String)value);
|
||||
|
||||
idx = pkg.lastIndexOf('/');
|
||||
while (idx != -1) {
|
||||
|
||||
+7
-1
@@ -32,6 +32,12 @@ record FieldToMethodTransformer(String className, Map<String, String> fields) im
|
||||
// TODO [Forge][Transformer] Make this properly data driven or configurable.
|
||||
// It was hard-coded like this before when using JS CoreMods, though.
|
||||
static final Map<String, Map<String, String>> TARGETS = Map.of(
|
||||
"net.minecraft.world.level.biome.Biome",
|
||||
Map.of(
|
||||
"climateSettings", "getModifiedClimateSettings",
|
||||
"specialEffects", "getModifiedSpecialEffects"
|
||||
),
|
||||
|
||||
"net.minecraft.world.effect.MobEffectInstance",
|
||||
Map.of(
|
||||
"effect", "getEffect"
|
||||
@@ -120,7 +126,7 @@ record FieldToMethodTransformer(String className, Map<String, String> fields) im
|
||||
throw new IllegalStateException("No field with name " + fieldName + " found");
|
||||
|
||||
if (!Modifier.isPrivate(foundField.access) || Modifier.isStatic(foundField.access))
|
||||
throw new IllegalStateException("Field " + classNode.name + '.' + fieldName + " is not private and an instance field");
|
||||
throw new IllegalStateException("Field " + fieldName + " is not private and an instance field");
|
||||
|
||||
var methodSignature = "()" + foundField.desc;
|
||||
var foundMethod = findMethod(classNode, methodName, methodSignature);
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ record MethodRedirector() implements ITransformer<ClassNode> {
|
||||
"finalizeSpawn",
|
||||
"(Lnet/minecraft/world/level/ServerLevelAccessor;Lnet/minecraft/world/DifficultyInstance;Lnet/minecraft/world/entity/EntitySpawnReason;Lnet/minecraft/world/entity/SpawnGroupData;)Lnet/minecraft/world/entity/SpawnGroupData;",
|
||||
GSON.fromJson(new InputStreamReader(sneak(() -> MethodRedirector.class.getModule().getResourceAsStream("coremods/finalize_spawn_targets.json"))), Target[].class),
|
||||
_ -> new MethodInsnNode(
|
||||
insn -> new MethodInsnNode(
|
||||
Opcodes.INVOKESTATIC,
|
||||
"net/minecraftforge/event/ForgeEventFactory",
|
||||
"onFinalizeSpawn",
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
[
|
||||
{
|
||||
"class": "net/minecraft/gametest/framework/GameTestEntityBuilder",
|
||||
"class": "net/minecraft/gametest/framework/GameTestHelper",
|
||||
"methods": [
|
||||
"spawn()Lnet/minecraft/world/entity/Entity;"
|
||||
"spawn(Lnet/minecraft/world/entity/EntityType;Lnet/minecraft/world/phys/Vec3;Lnet/minecraft/world/entity/EntitySpawnReason;)Lnet/minecraft/world/entity/Entity;"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -20,7 +20,7 @@
|
||||
{
|
||||
"class": "net/minecraft/world/entity/EntityType",
|
||||
"methods": [
|
||||
"create(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/entity/PostSpawnProcessor;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/EntitySpawnReason;ZZ)Lnet/minecraft/world/entity/Entity;"
|
||||
"create(Lnet/minecraft/server/level/ServerLevel;Ljava/util/function/Consumer;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/EntitySpawnReason;ZZ)Lnet/minecraft/world/entity/Entity;"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -95,7 +95,7 @@
|
||||
"class": "net/minecraft/world/level/NaturalSpawner",
|
||||
"methods": [
|
||||
"spawnCategoryForPosition(Lnet/minecraft/world/entity/MobCategory;Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/level/chunk/ChunkAccess;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/NaturalSpawner$SpawnPredicate;Lnet/minecraft/world/level/NaturalSpawner$AfterSpawnCallback;)V",
|
||||
"spawnMobsForChunkGeneration(Lnet/minecraft/world/level/ServerLevelAccessor;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/ChunkPos;Lnet/minecraft/util/RandomSource;)V"
|
||||
"spawnMobsForChunkGeneration(Lnet/minecraft/world/level/ServerLevelAccessor;Lnet/minecraft/core/Holder;Lnet/minecraft/world/level/ChunkPos;Lnet/minecraft/util/RandomSource;)V"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -37,7 +37,8 @@ public @interface Mod {
|
||||
|
||||
/**
|
||||
* Annotate a class which will be subscribed to an Event Bus at mod construction time.
|
||||
* Defaults to subscribing the current modid to the {@link Bus#BOTH} on both sides.
|
||||
* Defaults to subscribing the current modid to the {@code MinecraftForge#EVENT_BUS}
|
||||
* on both sides.
|
||||
*
|
||||
* @see Bus
|
||||
*/
|
||||
|
||||
+1
-1
@@ -45,7 +45,7 @@ import java.util.stream.Collectors;
|
||||
/**
|
||||
* Automatic eventbus subscriber - reads {@link EventBusSubscriber}
|
||||
* annotations and passes the class instances to the {@link Bus}
|
||||
* defined by the annotation. Defaults to {@code Bus.BOTH} if not specified.
|
||||
* defined by the annotation. Defaults to {@code MinecraftForge#EVENT_BUS}
|
||||
*/
|
||||
public final class AutomaticEventSubscriber {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
+1
-1
@@ -81,7 +81,7 @@ public class FMLJavaModLanguageProvider implements IModLanguageProvider
|
||||
.filter(ad -> ad.annotationType().equals(MODANNOTATION))
|
||||
.peek(ad -> LOGGER.debug(SCAN, "Found @Mod class {} with id {}", ad.clazz().getClassName(), ad.annotationData().get("value")))
|
||||
.map(ad -> new FMLModTarget(ad.clazz().getClassName(), (String)ad.annotationData().get("value")))
|
||||
.collect(Collectors.toMap(FMLModTarget::modId, Function.identity(), (a, _) -> a));
|
||||
.collect(Collectors.toMap(FMLModTarget::modId, Function.identity(), (a,b)->a));
|
||||
scanResult.addLanguageLoader(modTargetMap);
|
||||
};
|
||||
}
|
||||
|
||||
+1
-1
@@ -74,7 +74,7 @@ public class LowCodeModLanguageProvider implements IModLanguageProvider
|
||||
.flatMap(fi->fi.getMods().stream())
|
||||
.map(IModInfo::getModId)
|
||||
.map(LowCodeModTarget::new)
|
||||
.collect(Collectors.toMap(LowCodeModTarget::modId, Function.identity(), (a, _)->a));
|
||||
.collect(Collectors.toMap(LowCodeModTarget::modId, Function.identity(), (a, b)->a));
|
||||
scanResult.addLanguageLoader(modTargetMap);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[versions]
|
||||
java = "25"
|
||||
minecraft = "26.3"
|
||||
minecraft-next = "26.4"
|
||||
mcp = "20260918.230105"
|
||||
changelog-base = "66.0"
|
||||
minecraft = "26.1.2"
|
||||
minecraft-next = "26.2"
|
||||
mcp = "20260409.101008"
|
||||
changelog-base = "64.0"
|
||||
+5
-5
@@ -1,8 +1,8 @@
|
||||
--- a/com/mojang/renderpearl/backend/opengl/GlCommandEncoder.java
|
||||
+++ b/com/mojang/renderpearl/backend/opengl/GlCommandEncoder.java
|
||||
@@ -208,6 +_,9 @@
|
||||
}
|
||||
|
||||
--- a/com/mojang/blaze3d/opengl/GlCommandEncoder.java
|
||||
+++ b/com/mojang/blaze3d/opengl/GlCommandEncoder.java
|
||||
@@ -111,6 +_,9 @@
|
||||
GlStateManager._colorMask(15);
|
||||
GlStateManager._clear(16384);
|
||||
GlStateManager._glFramebufferTexture2D(36160, 36064, 3553, 0, 0);
|
||||
+ // Forge: if using stencil, clear it as well (3553 = GlConst.GL_TEXTURE_2D)
|
||||
+ if (colorTexture.isStencilEnabled())
|
||||
@@ -0,0 +1,35 @@
|
||||
--- a/com/mojang/blaze3d/opengl/GlConst.java
|
||||
+++ b/com/mojang/blaze3d/opengl/GlConst.java
|
||||
@@ -249,6 +_,10 @@
|
||||
}
|
||||
|
||||
public static int toGlInternalId(final TextureFormat textureFormat) {
|
||||
+ return toGlInternalId(textureFormat, false);
|
||||
+ }
|
||||
+ public static int toGlInternalId(final TextureFormat textureFormat, final boolean stencil) {
|
||||
+ if (stencil && textureFormat.hasDepthAspect()) return org.lwjgl.opengl.GL30.GL_DEPTH32F_STENCIL8;
|
||||
return switch (textureFormat) {
|
||||
case RGBA8 -> 32856;
|
||||
case RED8 -> 33321;
|
||||
@@ -258,6 +_,10 @@
|
||||
}
|
||||
|
||||
public static int toGlExternalId(final TextureFormat textureFormat) {
|
||||
+ return toGlExternalId(textureFormat, false);
|
||||
+ }
|
||||
+ public static int toGlExternalId(final TextureFormat textureFormat, final boolean stencil) {
|
||||
+ if (stencil && textureFormat.hasDepthAspect()) return org.lwjgl.opengl.GL30.GL_DEPTH_STENCIL;
|
||||
return switch (textureFormat) {
|
||||
case RGBA8 -> 6408;
|
||||
case RED8 -> 6403;
|
||||
@@ -267,6 +_,10 @@
|
||||
}
|
||||
|
||||
public static int toGlType(final TextureFormat textureFormat) {
|
||||
+ return toGlType(textureFormat, false);
|
||||
+ }
|
||||
+ public static int toGlType(final TextureFormat textureFormat, boolean stencil) {
|
||||
+ if (stencil && textureFormat.hasDepthAspect()) return org.lwjgl.opengl.GL30.GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
|
||||
return switch (textureFormat) {
|
||||
case RGBA8 -> 5121;
|
||||
case RED8 -> 5121;
|
||||
+19
-19
@@ -1,5 +1,5 @@
|
||||
--- a/com/mojang/renderpearl/backend/opengl/GlDebug.java
|
||||
+++ b/com/mojang/renderpearl/backend/opengl/GlDebug.java
|
||||
--- a/com/mojang/blaze3d/opengl/GlDebug.java
|
||||
+++ b/com/mojang/blaze3d/opengl/GlDebug.java
|
||||
@@ -22,6 +_,14 @@
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
@@ -15,7 +15,7 @@
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final int CIRCULAR_LOG_SIZE = 10;
|
||||
private final Queue<GlDebug.LogEntry> MESSAGE_BUFFER = EvictingQueue.create(10);
|
||||
@@ -83,6 +_,8 @@
|
||||
@@ -103,6 +_,8 @@
|
||||
}
|
||||
|
||||
LOGGER.info("OpenGL debug message: {}", entry);
|
||||
@@ -24,21 +24,21 @@
|
||||
}
|
||||
|
||||
public List<String> getLastOpenGlDebugMessages() {
|
||||
@@ -107,7 +_,7 @@
|
||||
GlDebug debug = new GlDebug();
|
||||
enabledExtensions.add("GL_KHR_debug");
|
||||
GL33C.glEnable(37600);
|
||||
- if (debugSynchronousGlLogs) {
|
||||
+ if (debugSynchronousGlLogs | PRINT_STACKTRACE_ON_ERROR) {
|
||||
GL33C.glEnable(33346);
|
||||
}
|
||||
@@ -126,7 +_,7 @@
|
||||
GlDebug debug = new GlDebug();
|
||||
enabledExtensions.add("GL_KHR_debug");
|
||||
GL11.glEnable(37600);
|
||||
- if (debugSynchronousGlLogs) {
|
||||
+ if (debugSynchronousGlLogs | PRINT_STACKTRACE_ON_ERROR) {
|
||||
GL11.glEnable(33346);
|
||||
}
|
||||
|
||||
@@ -121,7 +_,7 @@
|
||||
} else if (caps.GL_ARB_debug_output && GlDevice.USE_GL_ARB_debug_output) {
|
||||
GlDebug debug = new GlDebug();
|
||||
enabledExtensions.add("GL_ARB_debug_output");
|
||||
- if (debugSynchronousGlLogs) {
|
||||
+ if (debugSynchronousGlLogs | PRINT_STACKTRACE_ON_ERROR) {
|
||||
GL33C.glEnable(33346);
|
||||
}
|
||||
@@ -140,7 +_,7 @@
|
||||
} else if (caps.GL_ARB_debug_output && GlDevice.USE_GL_ARB_debug_output) {
|
||||
GlDebug debug = new GlDebug();
|
||||
enabledExtensions.add("GL_ARB_debug_output");
|
||||
- if (debugSynchronousGlLogs) {
|
||||
+ if (debugSynchronousGlLogs | PRINT_STACKTRACE_ON_ERROR) {
|
||||
GL11.glEnable(33346);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
--- a/com/mojang/blaze3d/opengl/GlDevice.java
|
||||
+++ b/com/mojang/blaze3d/opengl/GlDevice.java
|
||||
@@ -129,7 +_,12 @@
|
||||
final int depthOrLayers,
|
||||
final int mipLevels
|
||||
) {
|
||||
- return this.createTexture(this.debugLabels.exists() && label != null ? label.get() : null, usage, format, width, height, depthOrLayers, mipLevels);
|
||||
+ return this.createTexture(label, usage, format, width, height, depthOrLayers, mipLevels, false);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public GpuTexture createTexture(final @Nullable Supplier<String> label, @GpuTexture.Usage final int usage, final TextureFormat format, final int width, final int height, final int depthOrLayers, final int mipLevels, final boolean stencil ) {
|
||||
+ return this.createTexture(this.debugLabels.exists() && label != null ? label.get() : null, usage, format, width, height, depthOrLayers, mipLevels, stencil);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -142,6 +_,11 @@
|
||||
final int depthOrLayers,
|
||||
final int mipLevels
|
||||
) {
|
||||
+ return this.createTexture(label, usage, format, width, height, depthOrLayers, mipLevels, false);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public GpuTexture createTexture(@Nullable String label, @GpuTexture.Usage final int usage, final TextureFormat format, final int width, final int height, final int depthOrLayers, final int mipLevels, boolean stencil) {
|
||||
GlStateManager.clearGlErrors();
|
||||
int id = GlStateManager._genTexture();
|
||||
if (label == null) {
|
||||
@@ -171,12 +_,12 @@
|
||||
GlStateManager._texImage2D(
|
||||
cubeTarget,
|
||||
i,
|
||||
- GlConst.toGlInternalId(format),
|
||||
+ GlConst.toGlInternalId(format, stencil),
|
||||
width >> i,
|
||||
height >> i,
|
||||
0,
|
||||
- GlConst.toGlExternalId(format),
|
||||
- GlConst.toGlType(format),
|
||||
+ GlConst.toGlExternalId(format, stencil),
|
||||
+ GlConst.toGlType(format, stencil),
|
||||
null
|
||||
);
|
||||
}
|
||||
@@ -184,7 +_,7 @@
|
||||
} else {
|
||||
for (int i = 0; i < mipLevels; i++) {
|
||||
GlStateManager._texImage2D(
|
||||
- target, i, GlConst.toGlInternalId(format), width >> i, height >> i, 0, GlConst.toGlExternalId(format), GlConst.toGlType(format), null
|
||||
+ target, i, GlConst.toGlInternalId(format, stencil), width >> i, height >> i, 0, GlConst.toGlExternalId(format, stencil), GlConst.toGlType(format, stencil), null
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -195,7 +_,7 @@
|
||||
} else if (error != 0) {
|
||||
throw new IllegalStateException("OpenGL error " + error);
|
||||
} else {
|
||||
- GlTexture texture = new GlTexture(usage, label, format, width, height, depthOrLayers, mipLevels, id);
|
||||
+ GlTexture texture = new GlTexture(usage, label, format, width, height, depthOrLayers, mipLevels, id, stencil);
|
||||
this.debugLabels.applyLabel(texture);
|
||||
return texture;
|
||||
}
|
||||
+10
-10
@@ -1,18 +1,18 @@
|
||||
--- a/com/mojang/renderpearl/backend/opengl/GlStateManager.java
|
||||
+++ b/com/mojang/renderpearl/backend/opengl/GlStateManager.java
|
||||
@@ -82,6 +_,11 @@
|
||||
--- a/com/mojang/blaze3d/opengl/GlStateManager.java
|
||||
+++ b/com/mojang/blaze3d/opengl/GlStateManager.java
|
||||
@@ -86,6 +_,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ public static boolean _isBlendEnabled(int index) {
|
||||
+ public static boolean _isBlendEnabled() {
|
||||
+ RenderSystem.assertOnRenderThread();
|
||||
+ return BLEND_ENABLE[index];
|
||||
+ return BLEND.mode.enabled;
|
||||
+ }
|
||||
+
|
||||
public static void _disableBlend(final int index) {
|
||||
public static void _disableBlend() {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
if (BLEND_ENABLE[index]) {
|
||||
@@ -401,9 +_,17 @@
|
||||
BLEND.mode.disable();
|
||||
@@ -380,9 +_,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
+
|
||||
public static void _texParameter(final int target, final int name, final int value) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL33C.glTexParameteri(target, name, value);
|
||||
+ if (target == GL33C.GL_TEXTURE1) {
|
||||
GL11.glTexParameteri(target, name, value);
|
||||
+ if (target == GL13.GL_TEXTURE1) {
|
||||
+ lastBrightnessX = name;
|
||||
+ lastBrightnessY = value;
|
||||
+ }
|
||||
@@ -0,0 +1,29 @@
|
||||
--- a/com/mojang/blaze3d/opengl/GlTexture.java
|
||||
+++ b/com/mojang/blaze3d/opengl/GlTexture.java
|
||||
@@ -28,8 +_,13 @@
|
||||
final int mipLevels,
|
||||
final int id
|
||||
) {
|
||||
+ this(usage, label, format, width, height, depthOrLayers, mipLevels, id, false);
|
||||
+ }
|
||||
+
|
||||
+ protected GlTexture(int usage, String label, TextureFormat format, int width, int height, int depthOrLayers, int mipLevels, int id, boolean stencil) {
|
||||
super(usage, label, format, width, height, depthOrLayers, mipLevels);
|
||||
this.id = id;
|
||||
+ this.stencilEnabled = stencil;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -96,5 +_,12 @@
|
||||
if (this.closed && this.views == 0) {
|
||||
this.destroyImmediately();
|
||||
}
|
||||
+ }
|
||||
+
|
||||
+ private final boolean stencilEnabled;
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isStencilEnabled() {
|
||||
+ return this.stencilEnabled;
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,18 @@
|
||||
--- a/com/mojang/blaze3d/pipeline/RenderTarget.java
|
||||
+++ b/com/mojang/blaze3d/pipeline/RenderTarget.java
|
||||
@@ -96,7 +_,7 @@
|
||||
@@ -80,7 +_,7 @@
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
if (this.depthFormat != null) {
|
||||
- this.depthTexture = device.createTexture(() -> this.label + " / Depth", 15, this.depthFormat, width, height, 1, 1);
|
||||
+ this.depthTexture = device.createTexture(() -> this.label + " / Depth", 15, this.depthFormat, width, height, 1, 1, this.stencilEnabled);
|
||||
if (this.useDepth) {
|
||||
- this.depthTexture = device.createTexture(() -> this.label + " / Depth", 15, TextureFormat.DEPTH32, width, height, 1, 1);
|
||||
+ this.depthTexture = device.createTexture(() -> this.label + " / Depth", 15, TextureFormat.DEPTH32, width, height, 1, 1, this.stencilEnabled);
|
||||
this.depthTextureView = device.createTextureView(this.depthTexture);
|
||||
}
|
||||
|
||||
@@ -140,5 +_,26 @@
|
||||
@@ -124,5 +_,26 @@
|
||||
|
||||
public boolean hasDepth() {
|
||||
return this.depthFormat != null;
|
||||
public @Nullable GpuTextureView getDepthTextureView() {
|
||||
return this.depthTextureView;
|
||||
+ }
|
||||
+
|
||||
+ private boolean stencilEnabled = false;
|
||||
|
||||
@@ -1,33 +1,31 @@
|
||||
--- a/com/mojang/blaze3d/platform/Window.java
|
||||
+++ b/com/mojang/blaze3d/platform/Window.java
|
||||
@@ -114,9 +_,10 @@
|
||||
Monitor initialMonitor = monitorManager.getMonitor(SDLVideo.SDL_GetPrimaryDisplay());
|
||||
this.windowedWidth = this.width = allowedWindowMinSize(displayData.width(), 320);
|
||||
this.windowedHeight = this.height = allowedWindowMinSize(displayData.height(), 240);
|
||||
- this.handle = this.createWindow(backend, this.width, this.height, title);
|
||||
+ this.handle = net.minecraftforge.fml.loading.ImmediateWindowHandler.setupMinecraftWindow(this.width, this.height, title, () -> backend);
|
||||
this.setWindowMaxSize(maximumSize, maximumSize);
|
||||
MacosUtil.disableCloseWindowMenuItem();
|
||||
@@ -97,8 +_,9 @@
|
||||
Monitor initialMonitor = this.screenManager.getMonitor(GLFW.glfwGetPrimaryMonitor());
|
||||
this.windowedWidth = this.width = allowedWindowMinSize(displayData.width());
|
||||
this.windowedHeight = this.height = allowedWindowMinSize(displayData.height());
|
||||
- this.handle = this.createWindow(backend, this.width, this.height, title, this.fullscreen && initialMonitor != null ? initialMonitor.getMonitor() : 0L);
|
||||
+ this.handle = net.minecraftforge.fml.loading.ImmediateWindowHandler.setupMinecraftWindow(this.width, this.height, title, this.fullscreen && initialMonitor != null ? initialMonitor.getMonitor() : 0L, () -> backend);
|
||||
this.backend = backend;
|
||||
+ if (!net.minecraftforge.fml.loading.ImmediateWindowHandler.positionWindow(Optional.ofNullable(initialMonitor), w->this.width = this.windowedWidth = w, h->this.height = this.windowedHeight = h, x->this.x = this.windowedX = x, y->this.y = this.windowedY = y)) {
|
||||
if (initialMonitor != null) {
|
||||
this.windowedX = this.x = initialMonitor.x() + (initialMonitor.w() - this.width) / 2;
|
||||
this.windowedY = this.y = initialMonitor.y() + (initialMonitor.h() - this.height) / 2;
|
||||
@@ -132,6 +_,7 @@
|
||||
this.windowedY = this.y = actualY.get(0);
|
||||
}
|
||||
VideoMode mode = initialMonitor.getPreferredVidMode(this.fullscreen ? this.preferredFullscreenVideoMode : Optional.empty());
|
||||
this.windowedX = this.x = initialMonitor.getX() + mode.getWidth() / 2 - this.width / 2;
|
||||
@@ -110,6 +_,7 @@
|
||||
this.windowedX = this.x = actualX[0];
|
||||
this.windowedY = this.y = actualY[0];
|
||||
}
|
||||
+ }
|
||||
|
||||
this.setMode();
|
||||
this.refreshFramebufferSize();
|
||||
@@ -148,6 +_,10 @@
|
||||
@@ -300,6 +_,9 @@
|
||||
GLFW.glfwGetFramebufferSize(this.handle, outWidth, outHeight);
|
||||
this.framebufferWidth = outWidth[0] > 0 ? outWidth[0] : 1;
|
||||
this.framebufferHeight = outHeight[0] > 0 ? outHeight[0] : 1;
|
||||
+ if (this.framebufferHeight == 0 || this.framebufferWidth == 0) {
|
||||
+ net.minecraftforge.fml.loading.ImmediateWindowHandler.updateFBSize(w -> this.framebufferWidth = w, h -> this.framebufferHeight = h);
|
||||
+ }
|
||||
}
|
||||
|
||||
private long createWindow(final GpuBackend backend, final int width, final int height, final String title) {
|
||||
+ return createWindowStatic(backend, width, height, title);
|
||||
+ }
|
||||
+
|
||||
+ public static long createWindowStatic(final GpuBackend backend, final int width, final int height, final String title) {
|
||||
long flags = 8224L;
|
||||
long windowHandle = backend.createWindow(title, width, height, 8224L);
|
||||
if (windowHandle == 0L) {
|
||||
private void onResize(final long handle, final int newWidth, final int newHeight) {
|
||||
@@ -0,0 +1,46 @@
|
||||
--- a/com/mojang/blaze3d/systems/GpuDevice.java
|
||||
+++ b/com/mojang/blaze3d/systems/GpuDevice.java
|
||||
@@ -61,6 +_,21 @@
|
||||
return this.backend.createTexture(label, usage, format, width, height, depthOrLayers, mipLevels);
|
||||
}
|
||||
|
||||
+ /** Forge: same as {@link #createTexture(Supplier, int, TextureFormat, int, int, int)} but with stencil support */
|
||||
+ public GpuTexture createTexture(
|
||||
+ final @Nullable Supplier<String> label,
|
||||
+ @GpuTexture.Usage final int usage,
|
||||
+ final TextureFormat format,
|
||||
+ final int width,
|
||||
+ final int height,
|
||||
+ final int depthOrLayers,
|
||||
+ final int mipLevels,
|
||||
+ final boolean stencil
|
||||
+ ) {
|
||||
+ this.verifyTextureCreationArgs(usage, width, height, depthOrLayers, mipLevels);
|
||||
+ return this.backend.createTexture(label, usage, format, width, height, depthOrLayers, mipLevels, stencil);
|
||||
+ }
|
||||
+
|
||||
public GpuTexture createTexture(
|
||||
final @Nullable String label,
|
||||
@GpuTexture.Usage final int usage,
|
||||
@@ -72,6 +_,21 @@
|
||||
) {
|
||||
this.verifyTextureCreationArgs(usage, width, height, depthOrLayers, mipLevels);
|
||||
return this.backend.createTexture(label, usage, format, width, height, depthOrLayers, mipLevels);
|
||||
+ }
|
||||
+
|
||||
+ /** Forge: same as {@link #createTexture(Supplier, int, TextureFormat, int, int, int)} but with stencil support */
|
||||
+ public GpuTexture createTexture(
|
||||
+ final @Nullable String label,
|
||||
+ @GpuTexture.Usage final int usage,
|
||||
+ final TextureFormat format,
|
||||
+ final int width,
|
||||
+ final int height,
|
||||
+ final int depthOrLayers,
|
||||
+ final int mipLevels,
|
||||
+ final boolean stencil
|
||||
+ ) {
|
||||
+ this.verifyTextureCreationArgs(usage, width, height, depthOrLayers, mipLevels);
|
||||
+ return this.backend.createTexture(label, usage, format, width, height, depthOrLayers, mipLevels, stencil);
|
||||
}
|
||||
|
||||
private void verifyTextureCreationArgs(@GpuTexture.Usage final int usage, final int width, final int height, final int depthOrLayers, final int mipLevels) {
|
||||
@@ -0,0 +1,22 @@
|
||||
--- a/com/mojang/blaze3d/systems/GpuDeviceBackend.java
|
||||
+++ b/com/mojang/blaze3d/systems/GpuDeviceBackend.java
|
||||
@@ -30,9 +_,19 @@
|
||||
@Nullable Supplier<String> label, @GpuTexture.Usage final int usage, TextureFormat format, int width, int height, int depthOrLayers, int mipLevels
|
||||
);
|
||||
|
||||
+ /** Forge: same as {@link #createTexture(Supplier<String>, int, TextureFormat, int, int, int)} but with stencil support */
|
||||
+ default GpuTexture createTexture(@Nullable Supplier<String> label, @GpuTexture.Usage final int usage, TextureFormat format, int width, int height, int depthOrLayers, int mipLevels, boolean stencil) {
|
||||
+ return createTexture(label, usage, format, width, height, depthOrLayers, mipLevels);
|
||||
+ }
|
||||
+
|
||||
GpuTexture createTexture(
|
||||
@Nullable String label, @GpuTexture.Usage final int usage, TextureFormat format, int width, int height, int depthOrLayers, int mipLevels
|
||||
);
|
||||
+
|
||||
+ /** Forge: same as {@link #createTexture(String, int, TextureFormat, int, int, int)} but with stencil support */
|
||||
+ default GpuTexture createTexture(@Nullable String label, @GpuTexture.Usage final int usage, TextureFormat format, int width, int height, int depthOrLayers, int mipLevels, boolean stencil) {
|
||||
+ return createTexture(label, usage, format, width, height, depthOrLayers, mipLevels);
|
||||
+ }
|
||||
|
||||
GpuTextureView createTextureView(GpuTexture texture);
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
--- a/com/mojang/blaze3d/textures/GpuTexture.java
|
||||
+++ b/com/mojang/blaze3d/textures/GpuTexture.java
|
||||
@@ -8,7 +_,7 @@
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
-public abstract class GpuTexture implements AutoCloseable {
|
||||
+public abstract class GpuTexture implements AutoCloseable, net.minecraftforge.client.extensions.IForgeGpuTexture {
|
||||
public static final int USAGE_COPY_DST = 1;
|
||||
public static final int USAGE_COPY_SRC = 2;
|
||||
public static final int USAGE_TEXTURE_BINDING = 4;
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/com/mojang/blaze3d/vertex/PoseStack.java
|
||||
+++ b/com/mojang/blaze3d/vertex/PoseStack.java
|
||||
@@ -17,7 +_,7 @@
|
||||
@@ -16,7 +_,7 @@
|
||||
import org.joml.Vector3fc;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
--- a/com/mojang/blaze3d/vertex/VertexFormat.java
|
||||
+++ b/com/mojang/blaze3d/vertex/VertexFormat.java
|
||||
@@ -29,6 +_,7 @@
|
||||
private final int[] offsetsByElement = new int[32];
|
||||
private @Nullable GpuBuffer immediateDrawVertexBuffer;
|
||||
private @Nullable GpuBuffer immediateDrawIndexBuffer;
|
||||
+ private final com.google.common.collect.ImmutableMap<String, VertexFormatElement> elementMapping;
|
||||
|
||||
private VertexFormat(final List<VertexFormatElement> elements, final List<String> names, final IntList offsets, final int vertexSize) {
|
||||
this.elements = elements;
|
||||
@@ -41,6 +_,11 @@
|
||||
int index = element != null ? elements.indexOf(element) : -1;
|
||||
this.offsetsByElement[id] = index != -1 ? offsets.getInt(index) : -1;
|
||||
}
|
||||
+
|
||||
+ ImmutableMap.Builder<String, VertexFormatElement> elementMapping = ImmutableMap.builder();
|
||||
+ for (int i = 0; i < elements.size(); i++)
|
||||
+ elementMapping.put(names.get(i), elements.get(i));
|
||||
+ this.elementMapping = elementMapping.buildOrThrow();
|
||||
}
|
||||
|
||||
public static VertexFormat.Builder builder() {
|
||||
@@ -139,6 +_,9 @@
|
||||
this.immediateDrawIndexBuffer = uploadToBuffer(this.immediateDrawIndexBuffer, buffer, 72, () -> "Immediate index buffer for " + this);
|
||||
return this.immediateDrawIndexBuffer;
|
||||
}
|
||||
+
|
||||
+ public ImmutableMap<String, VertexFormatElement> getElementMapping() { return elementMapping; }
|
||||
+ public int getOffset(int index) { return offsetsByElement[index]; }
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class Builder {
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/com/mojang/math/Transformation.java
|
||||
+++ b/com/mojang/math/Transformation.java
|
||||
@@ -14,7 +_,7 @@
|
||||
@@ -16,7 +_,7 @@
|
||||
import org.joml.Vector3fc;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
@@ -9,21 +9,21 @@
|
||||
private static final Vector3fc ZERO_TRANSLATION = new Vector3f();
|
||||
private static final Vector3fc UNIT_SCALE = new Vector3f(1.0F, 1.0F, 1.0F);
|
||||
private static final Quaternionfc ZERO_ROTATION = new Quaternionf();
|
||||
@@ -172,6 +_,20 @@
|
||||
@@ -171,6 +_,20 @@
|
||||
this.scale().lerp(that.scale(), progress, new Vector3f()),
|
||||
this.rightRotation().slerp(that.rightRotation(), progress, new Quaternionf())
|
||||
);
|
||||
+ }
|
||||
+
|
||||
+ private org.joml.Matrix3f normalTransform = null;
|
||||
+ public org.joml.Matrix3f getNormalMatrix() {
|
||||
+ private Matrix3f normalTransform = null;
|
||||
+ public Matrix3f getNormalMatrix() {
|
||||
+ checkNormalTransform();
|
||||
+ return normalTransform;
|
||||
+ }
|
||||
+
|
||||
+ private void checkNormalTransform() {
|
||||
+ if (normalTransform == null) {
|
||||
+ normalTransform = new org.joml.Matrix3f(matrix);
|
||||
+ normalTransform = new Matrix3f(matrix);
|
||||
+ normalTransform.invert();
|
||||
+ normalTransform.transpose();
|
||||
+ }
|
||||
|
||||
+2
-2
@@ -5,8 +5,8 @@
|
||||
|
||||
@Override
|
||||
+ public boolean keyPressed(net.minecraft.client.input.KeyEvent event) {
|
||||
+ if (event.isEscape()) {
|
||||
+ minecraft.gui.setScreen(this.nextScreen);
|
||||
+ if (event.key() == org.lwjgl.glfw.GLFW.GLFW_KEY_ESCAPE) {
|
||||
+ minecraft.setScreen(this.nextScreen);
|
||||
+ return true;
|
||||
+ }
|
||||
+ return super.keyPressed(event);
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
--- a/com/mojang/realmsclient/gui/screens/RealmsResetWorldScreen.java
|
||||
+++ b/com/mojang/realmsclient/gui/screens/RealmsResetWorldScreen.java
|
||||
@@ -300,7 +_,7 @@
|
||||
@@ -302,7 +_,7 @@
|
||||
int y = this.getY();
|
||||
graphics.blit(RenderPipelines.GUI_TEXTURED, this.image, x + 2, y + 2, 0.0F, 0.0F, 56, 56, 56, 56, 56, 56, color);
|
||||
graphics.blitSprite(RenderPipelines.GUI_TEXTURED, SLOT_FRAME_SPRITE, x, y, 60, 60, color);
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
--- a/com/mojang/renderpearl/api/device/GpuDevice.java
|
||||
+++ b/com/mojang/renderpearl/api/device/GpuDevice.java
|
||||
@@ -37,7 +_,17 @@
|
||||
@Nullable Supplier<String> label, @GpuTexture.Usage int usage, GpuFormat format, int width, int height, int depthOrLayers, int mipLevels
|
||||
);
|
||||
|
||||
+ default GpuTexture createTexture(
|
||||
+ @Nullable Supplier<String> label, @GpuTexture.Usage int usage, GpuFormat format, int width, int height, int depthOrLayers, int mipLevels, boolean stencil
|
||||
+ ) {
|
||||
+ return createTexture(label, usage, format, width, height, depthOrLayers, mipLevels);
|
||||
+ }
|
||||
+
|
||||
GpuTexture createTexture(@Nullable String label, @GpuTexture.Usage int usage, GpuFormat format, int width, int height, int depthOrLayers, int mipLevels);
|
||||
+
|
||||
+ default GpuTexture createTexture(@Nullable String label, @GpuTexture.Usage int usage, GpuFormat format, int width, int height, int depthOrLayers, int mipLevels, boolean stencil) {
|
||||
+ return createTexture(label, usage, format, width, height, depthOrLayers, mipLevels, stencil);
|
||||
+ }
|
||||
|
||||
GpuTextureView createTextureView(GpuTexture texture);
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
--- a/com/mojang/renderpearl/api/textures/GpuTexture.java
|
||||
+++ b/com/mojang/renderpearl/api/textures/GpuTexture.java
|
||||
@@ -10,7 +_,7 @@
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
-public interface GpuTexture extends UncheckedAutoCloseable {
|
||||
+public interface GpuTexture extends UncheckedAutoCloseable, net.minecraftforge.client.extensions.IForgeGpuTexture {
|
||||
int USAGE_COPY_DST = 1;
|
||||
int USAGE_COPY_SRC = 2;
|
||||
int USAGE_TEXTURE_BINDING = 4;
|
||||
@@ -1,25 +0,0 @@
|
||||
--- a/com/mojang/renderpearl/api/vertex/VertexFormat.java
|
||||
+++ b/com/mojang/renderpearl/api/vertex/VertexFormat.java
|
||||
@@ -19,6 +_,7 @@
|
||||
private final int vertexSize;
|
||||
private final int stepRate;
|
||||
private final List<VertexFormatElement> elementValues;
|
||||
+ private final com.google.common.collect.ImmutableMap<String, VertexFormatElement> elementMapping;
|
||||
|
||||
private VertexFormat(final List<VertexFormatElement> elements, final int vertexSize, final int stepRate) {
|
||||
this.vertexSize = vertexSize;
|
||||
@@ -29,7 +_,14 @@
|
||||
}
|
||||
|
||||
this.elementValues = elements;
|
||||
+
|
||||
+ var elementMapping = com.google.common.collect.ImmutableMap.<String, VertexFormatElement>builder();
|
||||
+ for (var element : elements)
|
||||
+ elementMapping.put(element.name(), element);
|
||||
+ this.elementMapping = elementMapping.buildOrThrow();
|
||||
}
|
||||
+
|
||||
+ public com.google.common.collect.ImmutableMap<String, VertexFormatElement> getElementMapping() { return elementMapping; }
|
||||
|
||||
public static VertexFormat.Builder builder(final int stepRate) {
|
||||
return new VertexFormat.Builder(stepRate);
|
||||
@@ -1,13 +0,0 @@
|
||||
--- a/com/mojang/renderpearl/backend/api/GpuDeviceBackend.java
|
||||
+++ b/com/mojang/renderpearl/backend/api/GpuDeviceBackend.java
|
||||
@@ -30,6 +_,10 @@
|
||||
|
||||
GpuTexture createTexture(@Nullable String label, @GpuTexture.Usage int usage, GpuFormat format, int width, int height, int depthOrLayers, int mipLevels);
|
||||
|
||||
+ default GpuTexture createTexture(@Nullable String label, @GpuTexture.Usage int usage, GpuFormat format, int width, int height, int depthOrLayers, int mipLevels, boolean stencil) {
|
||||
+ return createTexture(label, usage, format, width, height, depthOrLayers, mipLevels);
|
||||
+ }
|
||||
+
|
||||
GpuTextureView createTextureView(GpuTexture texture, int baseMipLevel, int mipLevels);
|
||||
|
||||
GpuBuffer createBuffer(@Nullable Supplier<String> label, @GpuBuffer.Usage int usage, long size);
|
||||
@@ -1,43 +0,0 @@
|
||||
--- a/com/mojang/renderpearl/backend/common/BaseGpuTexture.java
|
||||
+++ b/com/mojang/renderpearl/backend/common/BaseGpuTexture.java
|
||||
@@ -24,6 +_,19 @@
|
||||
final int depthOrLayers,
|
||||
final int mipLevels
|
||||
) {
|
||||
+ this(usage, label, format, width, height, depthOrLayers, mipLevels, false);
|
||||
+ }
|
||||
+
|
||||
+ public BaseGpuTexture(
|
||||
+ final @GpuTexture.Usage int usage,
|
||||
+ final String label,
|
||||
+ final GpuFormat format,
|
||||
+ final int width,
|
||||
+ final int height,
|
||||
+ final int depthOrLayers,
|
||||
+ final int mipLevels,
|
||||
+ final boolean stencil
|
||||
+ ) {
|
||||
this.usage = usage;
|
||||
this.label = label;
|
||||
this.format = format;
|
||||
@@ -31,6 +_,7 @@
|
||||
this.height = height;
|
||||
this.depthOrLayers = depthOrLayers;
|
||||
this.mipLevels = mipLevels;
|
||||
+ this.stencilEnabled = stencil;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -66,5 +_,12 @@
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return this.label;
|
||||
+ }
|
||||
+
|
||||
+ private final boolean stencilEnabled;
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isStencilEnabled() {
|
||||
+ return this.stencilEnabled;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
--- a/com/mojang/renderpearl/backend/opengl/GlBackend.java
|
||||
+++ b/com/mojang/renderpearl/backend/opengl/GlBackend.java
|
||||
@@ -38,6 +_,8 @@
|
||||
"OpenGL is not supported: " + Objects.requireNonNullElse(SDLError.SDL_GetError(), "<no error>"),
|
||||
BackendCreationException.Reason.OPENGL_MISSING
|
||||
);
|
||||
+ // If we have loaded the early loading screen, we expect the libraries to be loaded, so don't actually error
|
||||
+ if (!"OpenGL is not supported: OpenGL library already loaded".equals(this.libraryLoadFailure.getMessage()))
|
||||
throw this.libraryLoadFailure;
|
||||
}
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
--- a/com/mojang/renderpearl/backend/opengl/GlConst.java
|
||||
+++ b/com/mojang/renderpearl/backend/opengl/GlConst.java
|
||||
@@ -239,6 +_,10 @@
|
||||
}
|
||||
|
||||
public static int toGlInternalId(final GpuFormat gpuFormat) {
|
||||
+ return toGlInternalId(gpuFormat, false);
|
||||
+ }
|
||||
+ public static int toGlInternalId(final GpuFormat gpuFormat, final boolean stencil) {
|
||||
+ if (stencil && gpuFormat.hasDepthAspect()) return org.lwjgl.opengl.GL30.GL_DEPTH32F_STENCIL8;
|
||||
return switch (gpuFormat) {
|
||||
case R8_UNORM -> 33321;
|
||||
case R8_SNORM -> 36756;
|
||||
@@ -291,6 +_,10 @@
|
||||
}
|
||||
|
||||
public static int toGlExternalId(final GpuFormat gpuFormat) {
|
||||
+ return toGlExternalId(gpuFormat, false);
|
||||
+ }
|
||||
+ public static int toGlExternalId(final GpuFormat gpuFormat, final boolean stencil) {
|
||||
+ if (stencil && gpuFormat.hasDepthAspect()) return org.lwjgl.opengl.GL30.GL_DEPTH_STENCIL;
|
||||
return switch (gpuFormat) {
|
||||
case R8_UNORM, R8_SNORM, R16_UNORM, R16_SNORM, R16_FLOAT, R32_FLOAT -> 6403;
|
||||
case RG8_UNORM, RG8_SNORM, RG16_UNORM, RG16_SNORM, RG16_FLOAT, RG32_FLOAT -> 33319;
|
||||
@@ -308,6 +_,10 @@
|
||||
}
|
||||
|
||||
public static int toGlType(final GpuFormat gpuFormat) {
|
||||
+ return toGlType(gpuFormat, false);
|
||||
+ }
|
||||
+ public static int toGlType(final GpuFormat gpuFormat, boolean stencil) {
|
||||
+ if (stencil && gpuFormat.hasDepthAspect()) return org.lwjgl.opengl.GL30.GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
|
||||
return switch (gpuFormat) {
|
||||
case R8_UNORM, RG8_UNORM, RGB8_UNORM, RGBA8_UNORM, R8_UINT, RG8_UINT, RGBA8_UINT, S8_UINT, RGB8_UINT -> 5121;
|
||||
case R8_SNORM, RG8_SNORM, RGB8_SNORM, RGBA8_SNORM, R8_SINT, RG8_SINT, RGBA8_SINT, RGB8_SINT -> 5120;
|
||||
@@ -1,36 +0,0 @@
|
||||
--- a/com/mojang/renderpearl/backend/opengl/GlDevice.java
|
||||
+++ b/com/mojang/renderpearl/backend/opengl/GlDevice.java
|
||||
@@ -200,6 +_,11 @@
|
||||
final int depthOrLayers,
|
||||
final int mipLevels
|
||||
) {
|
||||
+ return this.createTexture(label, usage, format, width, height, depthOrLayers, mipLevels, false);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public GpuTexture createTexture(@Nullable String label, @GpuTexture.Usage final int usage, final GpuFormat format, final int width, final int height, final int depthOrLayers, final int mipLevels, boolean stencil) {
|
||||
GlStateManager.clearGlErrors();
|
||||
int id = GlStateManager._genTexture();
|
||||
if (label == null) {
|
||||
@@ -223,9 +_,9 @@
|
||||
GlStateManager._texParameter(target, 34892, 0);
|
||||
}
|
||||
|
||||
- int glInternalID = GlConst.toGlInternalId(format);
|
||||
- int glExternalID = GlConst.toGlExternalId(format);
|
||||
- int glType = GlConst.toGlType(format);
|
||||
+ int glInternalID = GlConst.toGlInternalId(format, stencil);
|
||||
+ int glExternalID = GlConst.toGlExternalId(format, stencil);
|
||||
+ int glType = GlConst.toGlType(format, stencil);
|
||||
if (glInternalID != 0 && glExternalID != 0 && glType != 0) {
|
||||
if (isCubemap) {
|
||||
for (int cubeTarget : GlConst.CUBEMAP_TARGETS) {
|
||||
@@ -248,7 +_,7 @@
|
||||
throw new IllegalStateException("OpenGL error " + error);
|
||||
}
|
||||
|
||||
- GlTexture texture = new GlTexture(usage, label, format, width, height, depthOrLayers, mipLevels, id, this.frameBufferCache);
|
||||
+ GlTexture texture = new GlTexture(usage, label, format, width, height, depthOrLayers, mipLevels, id, this.frameBufferCache, stencil);
|
||||
this.debugLabels.applyLabel(texture);
|
||||
return texture;
|
||||
} else {
|
||||
@@ -1,15 +0,0 @@
|
||||
--- a/com/mojang/renderpearl/backend/opengl/GlTexture.java
|
||||
+++ b/com/mojang/renderpearl/backend/opengl/GlTexture.java
|
||||
@@ -28,7 +_,11 @@
|
||||
final int id,
|
||||
final FrameBufferCache frameBufferCache
|
||||
) {
|
||||
- super(usage, label, format, width, height, depthOrLayers, mipLevels);
|
||||
+ this(usage, label, format, width, height, depthOrLayers, mipLevels, id, frameBufferCache, false);
|
||||
+ }
|
||||
+
|
||||
+ protected GlTexture(@GpuTexture.Usage int usage, String label, GpuFormat format, int width, int height, int depthOrLayers, int mipLevels, int id, FrameBufferCache frameBufferCache, boolean stencil) {
|
||||
+ super(usage, label, format, width, height, depthOrLayers, mipLevels, stencil);
|
||||
this.id = id;
|
||||
this.frameBufferCache = frameBufferCache;
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
--- a/com/mojang/renderpearl/backend/vulkan/VulkanDevice.java
|
||||
+++ b/com/mojang/renderpearl/backend/vulkan/VulkanDevice.java
|
||||
@@ -213,7 +_,21 @@
|
||||
final int depthOrLayers,
|
||||
final int mipLevels
|
||||
) {
|
||||
- return new VulkanGpuTexture(this, usage, this.isDebuggingEnabled() && label != null ? label : "", format, width, height, depthOrLayers, mipLevels);
|
||||
+ return createTexture(label, usage, format, width, height, depthOrLayers, mipLevels, false);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public GpuTexture createTexture(
|
||||
+ final @Nullable String label,
|
||||
+ final @GpuTexture.Usage int usage,
|
||||
+ final GpuFormat format,
|
||||
+ final int width,
|
||||
+ final int height,
|
||||
+ final int depthOrLayers,
|
||||
+ final int mipLevels,
|
||||
+ final boolean stencil
|
||||
+ ) {
|
||||
+ return new VulkanGpuTexture(this, usage, this.isDebuggingEnabled() && label != null ? label : "", format, width, height, depthOrLayers, mipLevels, stencil);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1,25 +0,0 @@
|
||||
--- a/com/mojang/renderpearl/backend/vulkan/VulkanGpuTexture.java
|
||||
+++ b/com/mojang/renderpearl/backend/vulkan/VulkanGpuTexture.java
|
||||
@@ -34,7 +_,21 @@
|
||||
final int depthOrLayers,
|
||||
final int mipLevels
|
||||
) {
|
||||
- super(usage, label, format, width, height, depthOrLayers, mipLevels);
|
||||
+ this(device, usage, label, format, width, height, depthOrLayers, mipLevels, false);
|
||||
+ }
|
||||
+
|
||||
+ public VulkanGpuTexture(
|
||||
+ final VulkanDevice device,
|
||||
+ final @GpuTexture.Usage int usage,
|
||||
+ final String label,
|
||||
+ final GpuFormat format,
|
||||
+ final int width,
|
||||
+ final int height,
|
||||
+ final int depthOrLayers,
|
||||
+ final int mipLevels,
|
||||
+ final boolean stencil
|
||||
+ ) {
|
||||
+ super(usage, label, format, width, height, depthOrLayers, mipLevels, stencil);
|
||||
this.device = device;
|
||||
|
||||
try (MemoryStack stack = MemoryStack.stackPush()) {
|
||||
@@ -1,47 +0,0 @@
|
||||
--- a/com/mojang/renderpearl/frontend/FrontendGpuDevice.java
|
||||
+++ b/com/mojang/renderpearl/frontend/FrontendGpuDevice.java
|
||||
@@ -94,6 +_,21 @@
|
||||
return this.createTexture(this.isDebuggingEnabled() && label != null ? label.get() : null, usage, format, width, height, depthOrLayers, mipLevels);
|
||||
}
|
||||
|
||||
+ /** Forge: same as {@link #createTexture(Supplier, int, GpuFormat, int, int, int, int)} but with stencil support */
|
||||
+ @Override
|
||||
+ public GpuTexture createTexture(
|
||||
+ final @Nullable Supplier<String> label,
|
||||
+ final @GpuTexture.Usage int usage,
|
||||
+ final GpuFormat format,
|
||||
+ final int width,
|
||||
+ final int height,
|
||||
+ final int depthOrLayers,
|
||||
+ final int mipLevels,
|
||||
+ final boolean stencil
|
||||
+ ) {
|
||||
+ return this.createTexture(this.isDebuggingEnabled() && label != null ? label.get() : null, usage, format, width, height, depthOrLayers, mipLevels, stencil);
|
||||
+ }
|
||||
+
|
||||
@Override
|
||||
public GpuTexture createTexture(
|
||||
final @Nullable String label,
|
||||
@@ -106,6 +_,22 @@
|
||||
) {
|
||||
this.verifyTextureCreationArgs(usage, width, height, depthOrLayers, mipLevels);
|
||||
return this.backend.createTexture(label, usage, format, width, height, depthOrLayers, mipLevels);
|
||||
+ }
|
||||
+
|
||||
+ /** Forge: same as {@link #createTexture(String, int, GpuFormat, int, int, int, int)} but with stencil support */
|
||||
+ @Override
|
||||
+ public GpuTexture createTexture(
|
||||
+ final @Nullable String label,
|
||||
+ final @GpuTexture.Usage int usage,
|
||||
+ final GpuFormat format,
|
||||
+ final int width,
|
||||
+ final int height,
|
||||
+ final int depthOrLayers,
|
||||
+ final int mipLevels,
|
||||
+ final boolean stencil
|
||||
+ ) {
|
||||
+ this.verifyTextureCreationArgs(usage, width, height, depthOrLayers, mipLevels);
|
||||
+ return this.backend.createTexture(label, usage, format, width, height, depthOrLayers, mipLevels, stencil);
|
||||
}
|
||||
|
||||
private void verifyTextureCreationArgs(final @GpuTexture.Usage int usage, final int width, final int height, final int depthOrLayers, final int mipLevels) {
|
||||
@@ -1,7 +1,7 @@
|
||||
--- a/net/minecraft/CrashReport.java
|
||||
+++ b/net/minecraft/CrashReport.java
|
||||
@@ -58,14 +_,9 @@
|
||||
if (this.uncategorizedStackTrace.length > 0) {
|
||||
if (this.uncategorizedStackTrace != null && this.uncategorizedStackTrace.length > 0) {
|
||||
builder.append("-- Head --\n");
|
||||
builder.append("Thread: ").append(Thread.currentThread().getName()).append("\n");
|
||||
- builder.append("Stacktrace:\n");
|
||||
@@ -26,20 +26,23 @@
|
||||
this.systemReport.appendToCrashReportString(builder);
|
||||
}
|
||||
|
||||
@@ -84,15 +_,7 @@
|
||||
exception = replaceMessage(exception, this.title);
|
||||
@@ -92,18 +_,7 @@
|
||||
exception.setStackTrace(this.exception.getStackTrace());
|
||||
}
|
||||
|
||||
- String var4;
|
||||
- try {
|
||||
- writer = new StringWriter();
|
||||
- printWriter = new PrintWriter(writer);
|
||||
- exception.printStackTrace(printWriter);
|
||||
- return writer.toString();
|
||||
- var4 = writer.toString();
|
||||
- } finally {
|
||||
- IOUtils.closeQuietly(writer);
|
||||
- IOUtils.closeQuietly(printWriter);
|
||||
- IOUtils.closeQuietly((Writer)writer);
|
||||
- IOUtils.closeQuietly((Writer)printWriter);
|
||||
- }
|
||||
-
|
||||
- return var4;
|
||||
+ return net.minecraftforge.logging.CrashReportExtender.generateEnhancedStackTrace(exception);
|
||||
}
|
||||
|
||||
private static Throwable copyProperties(final Throwable original, final Throwable copy) {
|
||||
public String getFriendlyReport(final ReportType reportType, final List<String> extraComments) {
|
||||
@@ -1,21 +1,21 @@
|
||||
--- a/net/minecraft/CrashReportCategory.java
|
||||
+++ b/net/minecraft/CrashReportCategory.java
|
||||
@@ -138,8 +_,10 @@
|
||||
@@ -140,8 +_,10 @@
|
||||
if (full.length <= 0) {
|
||||
return 0;
|
||||
} else {
|
||||
- this.stackTrace = new StackTraceElement[full.length - 3 - nestedOffset];
|
||||
- System.arraycopy(full, 3 + nestedOffset, this.stackTrace, 0, this.stackTrace.length);
|
||||
+ int len = full.length - 3 - nestedOffset;
|
||||
+ if (len <= 0) len = full.length;
|
||||
+ this.stackTrace = new StackTraceElement[len];
|
||||
+ System.arraycopy(full, full.length - len, this.stackTrace, 0, this.stackTrace.length);
|
||||
return this.stackTrace.length;
|
||||
}
|
||||
|
||||
- this.stackTrace = new StackTraceElement[full.length - 3 - nestedOffset];
|
||||
- System.arraycopy(full, 3 + nestedOffset, this.stackTrace, 0, this.stackTrace.length);
|
||||
+ int len = full.length - 3 - nestedOffset;
|
||||
+ if (len <= 0) len = full.length;
|
||||
+ this.stackTrace = new StackTraceElement[len];
|
||||
+ System.arraycopy(full, full.length - len, this.stackTrace, 0, this.stackTrace.length);
|
||||
return this.stackTrace.length;
|
||||
}
|
||||
@@ -188,16 +_,16 @@
|
||||
|
||||
@@ -181,16 +_,16 @@
|
||||
|
||||
if (this.stackTrace.length > 0) {
|
||||
if (this.stackTrace != null && this.stackTrace.length > 0) {
|
||||
builder.append("\nStacktrace:");
|
||||
-
|
||||
- for (StackTraceElement element : this.stackTrace) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/SharedConstants.java
|
||||
+++ b/net/minecraft/SharedConstants.java
|
||||
@@ -219,6 +_,7 @@
|
||||
@@ -216,6 +_,7 @@
|
||||
}
|
||||
|
||||
static {
|
||||
|
||||
@@ -1,62 +1,15 @@
|
||||
--- a/net/minecraft/advancements/Advancement.java
|
||||
+++ b/net/minecraft/advancements/Advancement.java
|
||||
@@ -31,11 +_,12 @@
|
||||
Map<String, Criterion<?>> criteria,
|
||||
AdvancementRequirements requirements,
|
||||
boolean sendsTelemetryEvent,
|
||||
- Optional<Component> name
|
||||
+ Optional<Component> name,
|
||||
+ Optional<java.util.List<net.minecraftforge.common.crafting.ConditionalAdvancement>> forgeConditions
|
||||
) {
|
||||
private static final Codec<Map<String, Criterion<?>>> CRITERIA_CODEC = Codec.unboundedMap(Codec.STRING, Criterion.CODEC)
|
||||
.validate(criteria -> criteria.isEmpty() ? DataResult.error(() -> "Advancement criteria cannot be empty") : DataResult.success(criteria));
|
||||
- public static final Codec<Advancement> CODEC = RecordCodecBuilder.<Advancement>create(
|
||||
+ public static final Codec<Advancement> CODEC = net.minecraftforge.common.crafting.ConditionalAdvancement.wrapCodec(RecordCodecBuilder.<Advancement>mapCodec(
|
||||
i -> i.group(
|
||||
Identifier.CODEC.optionalFieldOf("parent").forGetter(Advancement::parent),
|
||||
DisplayInfo.CODEC.optionalFieldOf("display").forGetter(Advancement::display),
|
||||
@@ -49,7 +_,7 @@
|
||||
return new Advancement(parent, display, rewards, criteria, requirements, sendsTelemetryEvent);
|
||||
})
|
||||
)
|
||||
- .validate(Advancement::validate);
|
||||
+ .validate(Advancement::validate));
|
||||
public static final StreamCodec<RegistryFriendlyByteBuf, Advancement> STREAM_CODEC = StreamCodec.composite(
|
||||
Identifier.STREAM_CODEC.apply(ByteBufCodecs::optional),
|
||||
Advancement::parent,
|
||||
@@ -70,9 +_,21 @@
|
||||
final AdvancementRewards rewards,
|
||||
final Map<String, Criterion<?>> criteria,
|
||||
final AdvancementRequirements requirements,
|
||||
+ final boolean sendsTelemetryEvent,
|
||||
+ final Optional<Component> name
|
||||
+ ) {
|
||||
+ this(parent, display, rewards, criteria, requirements, sendsTelemetryEvent, name, Optional.empty());
|
||||
+ }
|
||||
+
|
||||
+ public Advancement(
|
||||
+ final Optional<Identifier> parent,
|
||||
+ final Optional<DisplayInfo> display,
|
||||
+ final AdvancementRewards rewards,
|
||||
+ final Map<String, Criterion<?>> criteria,
|
||||
+ final AdvancementRequirements requirements,
|
||||
final boolean sendsTelemetryEvent
|
||||
) {
|
||||
- this(parent, display, rewards, Map.copyOf(criteria), requirements, sendsTelemetryEvent, display.map(Advancement::decorateName));
|
||||
+ this(parent, display, rewards, Map.copyOf(criteria), requirements, sendsTelemetryEvent, display.map(Advancement::decorateName), Optional.empty());
|
||||
}
|
||||
|
||||
private static DataResult<Advancement> validate(final Advancement advancement) {
|
||||
@@ -235,7 +_,11 @@
|
||||
@@ -219,7 +_,11 @@
|
||||
}
|
||||
|
||||
public AdvancementHolder save(final BootstrapContext<Advancement> output, final String name) {
|
||||
public AdvancementHolder save(final Consumer<AdvancementHolder> output, final String name) {
|
||||
- AdvancementHolder advancement = this.build(Identifier.parse(name));
|
||||
+ return save(output, Identifier.parse(name));
|
||||
+ }
|
||||
+
|
||||
+ public AdvancementHolder save(final BootstrapContext<Advancement> output, final Identifier id) {
|
||||
+ public AdvancementHolder save(Consumer<AdvancementHolder> output, Identifier id) {
|
||||
+ AdvancementHolder advancement = this.build(id);
|
||||
advancement.register(output);
|
||||
output.accept(advancement);
|
||||
return advancement;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/advancements/AdvancementRewards.java
|
||||
+++ b/net/minecraft/advancements/AdvancementRewards.java
|
||||
@@ -46,6 +_,7 @@
|
||||
@@ -43,6 +_,7 @@
|
||||
LootParams params = new LootParams.Builder(level)
|
||||
.withParameter(LootContextParams.THIS_ENTITY, player)
|
||||
.withParameter(LootContextParams.ORIGIN, player.position())
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
--- a/net/minecraft/client/Camera.java
|
||||
+++ b/net/minecraft/client/Camera.java
|
||||
@@ -228,11 +_,13 @@
|
||||
@@ -217,12 +_,14 @@
|
||||
return 90.0F;
|
||||
} else {
|
||||
float fov = this.minecraft.options.fov().get().intValue() * Mth.lerp(partialTicks, this.oldFovModifier, this.fovModifier);
|
||||
- return this.modifyFovBasedOnDeathOrFluid(partialTicks, fov);
|
||||
+ var ret = this.modifyFovBasedOnDeathOrFluid(partialTicks, fov);
|
||||
+ return net.minecraftforge.client.event.ForgeEventFactoryClient.fireComputeFov(this.minecraft.gameRenderer, this, partialTicks, ret, true).getFOV();
|
||||
}
|
||||
|
||||
float fov = this.minecraft.options.fov().get().intValue() * Mth.lerp(partialTicks, this.oldFovModifier, this.fovModifier);
|
||||
- return this.modifyFovBasedOnDeathOrFluid(partialTicks, fov);
|
||||
+ var ret = this.modifyFovBasedOnDeathOrFluid(partialTicks, fov);
|
||||
+ return net.minecraftforge.client.event.ForgeEventFactoryClient.fireComputeFov(this.minecraft.gameRenderer, this, partialTicks, ret, true).getFOV();
|
||||
}
|
||||
|
||||
private float calculateHudFov(final float partialTicks) {
|
||||
@@ -16,7 +17,7 @@
|
||||
}
|
||||
|
||||
private float modifyFovBasedOnDeathOrFluid(final float partialTicks, float fov) {
|
||||
@@ -341,9 +_,13 @@
|
||||
@@ -331,9 +_,13 @@
|
||||
}
|
||||
|
||||
protected void setRotation(final float yRot, final float xRot) {
|
||||
@@ -31,7 +32,7 @@
|
||||
FORWARDS.rotate(this.rotation, this.forwards);
|
||||
UP.rotate(this.rotation, this.up);
|
||||
LEFT.rotate(this.rotation, this.left);
|
||||
@@ -374,6 +_,13 @@
|
||||
@@ -364,6 +_,13 @@
|
||||
|
||||
public float yRot() {
|
||||
return this.yRot;
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
return this.key.equals(that.key);
|
||||
}
|
||||
|
||||
@@ -177,11 +_,13 @@
|
||||
@@ -175,11 +_,13 @@
|
||||
}
|
||||
|
||||
public Component getTranslatedKeyMessage() {
|
||||
@@ -85,7 +85,7 @@
|
||||
}
|
||||
|
||||
public String saveString() {
|
||||
@@ -193,11 +_,94 @@
|
||||
@@ -191,11 +_,94 @@
|
||||
}
|
||||
|
||||
private void registerMapping(final InputConstants.Key key) {
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
--- a/net/minecraft/client/KeyboardHandler.java
|
||||
+++ b/net/minecraft/client/KeyboardHandler.java
|
||||
@@ -496,7 +_,7 @@
|
||||
if (screen != null) {
|
||||
try {
|
||||
if (action != 1 && action != -1) {
|
||||
- if (action == 0 && screen.keyReleased(event)) {
|
||||
+ if (action == 0 && net.minecraftforge.client.ForgeHooksClient.onScreenKeyReleased(screen, event)) {
|
||||
if (options.keyDebugModifier.matches(event)) {
|
||||
this.usedDebugKeyAsModifier = false;
|
||||
}
|
||||
@@ -505,7 +_,7 @@
|
||||
@@ -514,7 +_,7 @@
|
||||
if (screen != null) {
|
||||
try {
|
||||
if (action != 1 && action != 2) {
|
||||
- if (action == 0 && screen.keyReleased(event)) {
|
||||
+ if (action == 0 && net.minecraftforge.client.ForgeHooksClient.onScreenKeyReleased(screen, event)) {
|
||||
if (options.keyDebugModifier.matches(event)) {
|
||||
this.usedDebugKeyAsModifier = false;
|
||||
}
|
||||
} else {
|
||||
screen.afterKeyboardAction();
|
||||
- if (screen.keyPressed(event)) {
|
||||
+ if (net.minecraftforge.client.ForgeHooksClient.onScreenKeyPressed(screen, event)) {
|
||||
if (this.minecraft.gui.screen() == null) {
|
||||
InputConstants.Key key = InputConstants.getKey(event);
|
||||
KeyMapping.set(key, false);
|
||||
@@ -578,6 +_,7 @@
|
||||
@@ -523,7 +_,7 @@
|
||||
}
|
||||
} else {
|
||||
screen.afterKeyboardAction();
|
||||
- if (screen.keyPressed(event)) {
|
||||
+ if (net.minecraftforge.client.ForgeHooksClient.onScreenKeyPressed(screen, event)) {
|
||||
if (this.minecraft.screen == null) {
|
||||
InputConstants.Key key = InputConstants.getKey(event);
|
||||
KeyMapping.set(key, false);
|
||||
@@ -595,6 +_,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,12 +26,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -586,7 +_,7 @@
|
||||
Screen screen = this.minecraft.gui.screen();
|
||||
if (screen != null && this.minecraft.gui.overlay() == null) {
|
||||
@@ -603,7 +_,7 @@
|
||||
Screen screen = this.minecraft.screen;
|
||||
if (screen != null && this.minecraft.getOverlay() == null) {
|
||||
try {
|
||||
- screen.charTyped(event);
|
||||
+ net.minecraftforge.client.ForgeHooksClient.onScreenCharTyped(screen, event);
|
||||
} catch (Throwable t) {
|
||||
CrashReport report = CrashReport.forThrowable(t, "charTyped event handler");
|
||||
CrashReportCategory keyDetails = report.addCategory("Key");
|
||||
} catch (Throwable var8) {
|
||||
CrashReport report = CrashReport.forThrowable(var8, "charTyped event handler");
|
||||
screen.fillCrashDetails(report);
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/client/Minecraft.java
|
||||
+++ b/net/minecraft/client/Minecraft.java
|
||||
@@ -265,7 +_,7 @@
|
||||
@@ -268,7 +_,7 @@
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
@@ -8,8 +8,8 @@
|
||||
+public class Minecraft extends ReentrantBlockableEventLoop<Runnable> implements WindowEventHandler, net.minecraftforge.client.extensions.IForgeMinecraft {
|
||||
private static Minecraft instance;
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final SectionCategory TRACY_CURRENT_LEVEL = TracyClient.createSectionCategory("Level");
|
||||
@@ -420,7 +_,6 @@
|
||||
private static final int MAX_TICKS_PER_UPDATE = 10;
|
||||
@@ -432,7 +_,6 @@
|
||||
}
|
||||
}, Util.nonCriticalIoPool());
|
||||
LOGGER.info("Setting user: {}", this.user.getName());
|
||||
@@ -17,57 +17,68 @@
|
||||
this.demo = gameConfig.game.demo;
|
||||
this.allowsMultiplayer = !gameConfig.game.disableMultiplayer;
|
||||
this.allowsChat = !gameConfig.game.disableChat;
|
||||
@@ -568,6 +_,7 @@
|
||||
this.keyboardHandler = new KeyboardHandler(this);
|
||||
this.options.applyGraphicsPreset(this.options.graphicsPreset().get());
|
||||
this.resourceManager = new ReloadableResourceManager(PackType.CLIENT_RESOURCES);
|
||||
+ net.minecraftforge.client.loading.ClientModLoader.begin(this, this.resourcePackRepository, this.resourceManager);
|
||||
this.resourcePackRepository.reload();
|
||||
this.options.loadSelectedResourcePacks(this.resourcePackRepository);
|
||||
this.languageManager = new LanguageManager(this, this.options.languageCode, var1 -> {
|
||||
@@ -645,6 +_,7 @@
|
||||
ParticleResources particleResources = new ParticleResources();
|
||||
this.resourceManager.registerReloadListener(particleResources);
|
||||
this.particleEngine = new ParticleEngine(this.level, particleResources);
|
||||
+ net.minecraftforge.client.ForgeHooksClient.onRegisterParticleProviders(particleResources);
|
||||
particleResources.onReload(this.particleEngine::clearParticles);
|
||||
this.gameRenderer = new GameRenderer(this, new FirstPersonHandsAndItemsRenderer(this), this.modelManager, this.itemModelResolver);
|
||||
this.resourceManager.registerReloadListener(this.gameRenderer);
|
||||
@@ -663,6 +_,7 @@
|
||||
this.window.getHeight()
|
||||
);
|
||||
this.levelExtractor = new LevelExtractor(this, this.gameRenderer.gameRenderState().levelRenderState, this.levelRenderer);
|
||||
+ net.minecraftforge.client.event.ForgeEventFactoryClient.onInitLevelRenderer();
|
||||
this.resourceManager.registerReloadListener(this.levelExtractor);
|
||||
this.resourceManager.registerReloadListener(this.levelRenderer.cloudRenderer());
|
||||
this.gpuWarnlistManager = new GpuWarnlistManager();
|
||||
@@ -694,6 +_,7 @@
|
||||
MessageBox.error(message.toString());
|
||||
}
|
||||
|
||||
+ net.minecraftforge.client.ForgeHooksClient.initClientHooks(this, this.resourceManager);
|
||||
this.window.setAllowCursorChanges(this.options.allowCursorChanges().get());
|
||||
this.window.setQuitShortcuts(this.options.quitShortcuts().get());
|
||||
if (InputQuirks.EMULATE_RIGHT_CLICK_WITH_CTRL_KEY) {
|
||||
@@ -721,14 +_,15 @@
|
||||
.createReload(Util.backgroundExecutor().forName("resourceLoad"), this, RESOURCE_RELOAD_INITIAL_TASK, packs);
|
||||
GameLoadTimesEvent.INSTANCE.beginStep(TelemetryProperty.LOAD_TIME_LOADING_OVERLAY_MS);
|
||||
GameLoadCookie loadCookie = new GameLoadCookie(realmsClient, gameConfig.quickPlay);
|
||||
- this.gui.setOverlay(new LoadingOverlay(this, reloadInstance, maybeT -> Util.ifElse(maybeT, t -> this.rollbackResourcePacks(t, loadCookie), () -> {
|
||||
+ this.gui.setOverlay(net.minecraftforge.fml.loading.ImmediateWindowHandler.<LoadingOverlay>loadingOverlay(() -> this, () ->reloadInstance, maybeT -> Util.ifElse(maybeT, t -> this.rollbackResourcePacks(t, loadCookie), () -> {
|
||||
if (SharedConstants.IS_RUNNING_IN_IDE) {
|
||||
this.selfTest();
|
||||
@@ -518,14 +_,14 @@
|
||||
LOGGER.error("Couldn't set icon", (Throwable)var23);
|
||||
}
|
||||
|
||||
this.reloadStateTracker.finishReload();
|
||||
this.onResourceLoadFinished(loadCookie);
|
||||
- }), false));
|
||||
+ net.minecraftforge.client.loading.ClientModLoader.completeModLoading();
|
||||
+ }), false).get());
|
||||
this.quickPlayLog = QuickPlayLog.of(gameConfig.quickPlay.logPath());
|
||||
this.framerateLimitTracker = new FramerateLimitTracker(this.options, this);
|
||||
this.fpsPieProfiler = new ContinuousProfiler(Util.timeSource(), () -> this.fpsPieRenderTicks, this.framerateLimitTracker::isHeavilyThrottled);
|
||||
@@ -812,6 +_,7 @@
|
||||
+ // FORGE: Move mouse and keyboard handler setup further below
|
||||
this.mouseHandler = new MouseHandler(this);
|
||||
- this.mouseHandler.setup(this.window);
|
||||
this.keyboardHandler = new KeyboardHandler(this);
|
||||
- this.keyboardHandler.setup(this.window);
|
||||
this.options.applyGraphicsPreset(this.options.graphicsPreset().get());
|
||||
LOGGER.info("Using optional rendering extensions: {}", String.join(", ", RenderSystem.getDevice().getEnabledExtensions()));
|
||||
this.mainRenderTarget = new MainTarget(this.window.getWidth(), this.window.getHeight());
|
||||
this.resourceManager = new ReloadableResourceManager(PackType.CLIENT_RESOURCES);
|
||||
+ net.minecraftforge.client.loading.ClientModLoader.begin(this, this.resourcePackRepository, this.resourceManager);
|
||||
this.resourcePackRepository.reload();
|
||||
this.options.loadSelectedResourcePacks(this.resourcePackRepository);
|
||||
this.languageManager = new LanguageManager(this.options.languageCode, languageData -> {
|
||||
@@ -613,6 +_,7 @@
|
||||
this.particleResources = new ParticleResources();
|
||||
this.resourceManager.registerReloadListener(this.particleResources);
|
||||
this.particleEngine = new ParticleEngine(this.level, this.particleResources);
|
||||
+ net.minecraftforge.client.ForgeHooksClient.onRegisterParticleProviders(this.particleResources);
|
||||
this.particleResources.onReload(this.particleEngine::clearParticles);
|
||||
this.waypointStyles = new WaypointStyleManager();
|
||||
this.resourceManager.registerReloadListener(this.waypointStyles);
|
||||
@@ -634,6 +_,9 @@
|
||||
this.resourceManager.registerReloadListener(this.gpuWarnlistManager);
|
||||
this.resourceManager.registerReloadListener(this.regionalCompliancies);
|
||||
this.gui = new Gui(this);
|
||||
+ // FORGE: Moved keyboard and mouse handler setup below ingame gui creation to prevent NPEs in them.
|
||||
+ this.mouseHandler.setup(this.window);
|
||||
+ this.keyboardHandler.setup(this.window);
|
||||
RealmsClient realmsClient = RealmsClient.getOrCreate(this);
|
||||
this.realmsDataFetcher = new RealmsDataFetcher(realmsClient);
|
||||
RenderSystem.setErrorCallback(this::onFullscreenError);
|
||||
@@ -665,6 +_,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ net.minecraftforge.client.ForgeHooksClient.initClientHooks(this, this.resourceManager);
|
||||
this.window.updateVsync(this.options.enableVsync().get());
|
||||
this.window.updateRawMouseInput(this.options.rawMouseInput().get());
|
||||
this.window.setAllowCursorChanges(this.options.allowCursorChanges().get());
|
||||
@@ -690,14 +_,15 @@
|
||||
.createReload(Util.backgroundExecutor().forName("resourceLoad"), this, RESOURCE_RELOAD_INITIAL_TASK, packs);
|
||||
GameLoadTimesEvent.INSTANCE.beginStep(TelemetryProperty.LOAD_TIME_LOADING_OVERLAY_MS);
|
||||
Minecraft.GameLoadCookie loadCookie = new Minecraft.GameLoadCookie(realmsClient, gameConfig.quickPlay);
|
||||
- this.setOverlay(new LoadingOverlay(this, reloadInstance, maybeT -> Util.ifElse(maybeT, t -> this.rollbackResourcePacks(t, loadCookie), () -> {
|
||||
+ this.setOverlay(net.minecraftforge.fml.loading.ImmediateWindowHandler.<LoadingOverlay>loadingOverlay(() -> this, () ->reloadInstance, maybeT -> Util.ifElse(maybeT, t -> this.rollbackResourcePacks(t, loadCookie), () -> {
|
||||
if (SharedConstants.IS_RUNNING_IN_IDE) {
|
||||
this.selfTest();
|
||||
}
|
||||
|
||||
this.reloadStateTracker.finishReload();
|
||||
this.onResourceLoadFinished(loadCookie);
|
||||
- }), false));
|
||||
+ net.minecraftforge.client.loading.ClientModLoader.completeModLoading();
|
||||
+ }), false).get());
|
||||
this.quickPlayLog = QuickPlayLog.of(gameConfig.quickPlay.logPath());
|
||||
this.framerateLimitTracker = new FramerateLimitTracker(this.options, this);
|
||||
this.fpsPieProfiler = new ContinuousProfiler(Util.timeSource, () -> this.fpsPieRenderTicks, this.framerateLimitTracker::isHeavilyThrottled);
|
||||
@@ -816,6 +_,7 @@
|
||||
StringBuilder builder = new StringBuilder("Minecraft");
|
||||
if (checkModStatus().shouldReportAsModified()) {
|
||||
builder.append("*");
|
||||
@@ -75,51 +86,88 @@
|
||||
}
|
||||
|
||||
builder.append(" ");
|
||||
@@ -835,6 +_,8 @@
|
||||
@@ -839,6 +_,8 @@
|
||||
}
|
||||
|
||||
private static UserApiService createUserApiService(final MinecraftServicesDiscoveryService discoveryService, final GameConfig config) {
|
||||
private UserApiService createUserApiService(final YggdrasilAuthenticationService authService, final GameConfig config) {
|
||||
+ if ("0".equals(config.user.user.getAccessToken())) // Forge: We use "0" in dev. Short circuit to stop exception spam.
|
||||
+ return UserApiService.OFFLINE;
|
||||
return config.game.offlineDeveloperMode ? UserApiService.OFFLINE : discoveryService.createUserApiService(config.user.user.getAccessToken());
|
||||
return config.game.offlineDeveloperMode ? UserApiService.OFFLINE : authService.createUserApiService(config.user.user.getAccessToken());
|
||||
}
|
||||
|
||||
@@ -851,7 +_,7 @@
|
||||
}
|
||||
|
||||
private void rollbackResourcePacks(final Throwable t, final @Nullable GameLoadCookie loadCookie) {
|
||||
private void rollbackResourcePacks(final Throwable t, final Minecraft.@Nullable GameLoadCookie loadCookie) {
|
||||
- if (this.resourcePackRepository.getSelectedIds().size() > 1) {
|
||||
+ if (this.resourcePackRepository.getSelectedPacks().stream().anyMatch(e -> !e.isRequired())) { //Forge: This caused infinite loop if any resource packs are forced. Such as mod resources. So check if we can disable any.
|
||||
this.clearResourcePacksOnError(t, null, loadCookie);
|
||||
} else {
|
||||
Util.throwAsRuntime(t);
|
||||
@@ -1148,6 +_,7 @@
|
||||
FreeTypeUtil.destroy();
|
||||
this.windowSurface.close();
|
||||
RenderSystem.shutdownRenderer();
|
||||
+ net.minecraftforge.fml.config.ConfigTracker.forceUnload();
|
||||
} catch (Throwable t) {
|
||||
LOGGER.error("Shutdown failure!", t);
|
||||
throw t;
|
||||
@@ -1305,7 +_,9 @@
|
||||
profiler.popPush("gpuAsync");
|
||||
RenderSystem.executePendingTasks();
|
||||
profiler.pop();
|
||||
+ net.minecraftforge.client.event.ForgeEventFactoryClient.onRenderTickStart(this.deltaTracker);
|
||||
this.gameRenderer.render();
|
||||
+ net.minecraftforge.client.event.ForgeEventFactoryClient.onRenderTickEnd(this.deltaTracker);
|
||||
}
|
||||
|
||||
profiler.push("swapchainBlit");
|
||||
@@ -1432,6 +_,7 @@
|
||||
this.window.setGuiScale(guiScale);
|
||||
if (this.gui.screen() != null) {
|
||||
this.gui.screen().resize(this.window.getGuiScaledWidth(), this.window.getGuiScaledHeight());
|
||||
+ this.gui.resizeLayers(this.window.getGuiScaledWidth(), this.window.getGuiScaledHeight());
|
||||
@@ -1128,12 +_,6 @@
|
||||
LOGGER.error("setScreen called from non-game thread");
|
||||
}
|
||||
|
||||
this.mouseHandler.resyncMousePosition();
|
||||
@@ -1595,6 +_,7 @@
|
||||
- if (this.screen != null) {
|
||||
- this.screen.removed();
|
||||
- } else {
|
||||
- this.setLastInputType(InputType.NONE);
|
||||
- }
|
||||
-
|
||||
if (screen == null) {
|
||||
if (this.clientLevelTeardownInProgress) {
|
||||
throw new IllegalStateException("Trying to return to in-game GUI during disconnection");
|
||||
@@ -1152,6 +_,23 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ net.minecraftforge.client.ForgeHooksClient.clearGuiLayers(this);
|
||||
+ Screen old = this.screen;
|
||||
+ if (screen != null) {
|
||||
+ var event = net.minecraftforge.client.event.ForgeEventFactoryClient.onScreenOpening(old, screen);
|
||||
+ if (event == null) return;
|
||||
+ screen = event;
|
||||
+ }
|
||||
+
|
||||
+ if (screen != old) {
|
||||
+ if (old != null) {
|
||||
+ net.minecraftforge.client.event.ForgeEventFactoryClient.onScreenClose(old);
|
||||
+ old.removed();
|
||||
+ } else {
|
||||
+ this.setLastInputType(InputType.NONE);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
this.screen = screen;
|
||||
if (this.screen != null) {
|
||||
this.screen.added();
|
||||
@@ -1235,6 +_,7 @@
|
||||
Util.shutdownExecutors();
|
||||
RenderSystem.getSamplerCache().close();
|
||||
RenderSystem.getDevice().close();
|
||||
+ net.minecraftforge.fml.config.ConfigTracker.forceUnload();
|
||||
} catch (Throwable var5) {
|
||||
LOGGER.error("Shutdown failure!", var5);
|
||||
throw var5;
|
||||
@@ -1346,7 +_,9 @@
|
||||
profiler.popPush("gpuAsync");
|
||||
RenderSystem.executePendingTasks();
|
||||
profiler.pop();
|
||||
+ net.minecraftforge.client.event.ForgeEventFactoryClient.onRenderTickStart(this.deltaTracker);
|
||||
this.gameRenderer.render(this.deltaTracker, advanceGameTime);
|
||||
+ net.minecraftforge.client.event.ForgeEventFactoryClient.onRenderTickEnd(this.deltaTracker);
|
||||
profiler.push("present");
|
||||
if (!this.gameRenderer.getGameRenderState().windowRenderState.isMinimized) {
|
||||
this.mainRenderTarget.blitToScreen();
|
||||
@@ -1450,6 +_,7 @@
|
||||
this.window.setGuiScale(guiScale);
|
||||
if (this.screen != null) {
|
||||
this.screen.resize(this.window.getGuiScaledWidth(), this.window.getGuiScaledHeight());
|
||||
+ net.minecraftforge.client.ForgeHooksClient.resizeGuiLayers(this, this.window.getGuiScaledWidth(), this.window.getGuiScaledHeight());
|
||||
}
|
||||
|
||||
this.mouseHandler.setIgnoreFirstMove();
|
||||
@@ -1601,6 +_,7 @@
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
@@ -127,90 +175,89 @@
|
||||
this.running = false;
|
||||
}
|
||||
|
||||
@@ -1622,9 +_,16 @@
|
||||
@@ -1630,10 +_,18 @@
|
||||
if (down && this.hitResult != null && this.hitResult.getType() == HitResult.Type.BLOCK) {
|
||||
BlockHitResult blockHit = (BlockHitResult)this.hitResult;
|
||||
BlockPos pos = blockHit.getBlockPos();
|
||||
- if (!this.level.getBlockState(pos).isAir()) {
|
||||
+ if (!this.level.isEmptyBlock(pos)) {
|
||||
+ var inputEvent = new net.minecraftforge.client.event.InputEvent.InteractionKeyMappingTriggered.Attack(this.options.keyAttack, InteractionHand.MAIN_HAND);
|
||||
+ if (net.minecraftforge.client.event.InputEvent.InteractionKeyMappingTriggered.Attack.BUS.post(inputEvent)) {
|
||||
+ var inputEvent = new net.minecraftforge.client.event.InputEvent.InteractionKeyMappingTriggered(0, this.options.keyAttack, InteractionHand.MAIN_HAND);
|
||||
+ if (net.minecraftforge.client.event.InputEvent.InteractionKeyMappingTriggered.BUS.post(inputEvent)) {
|
||||
+ if (inputEvent.shouldSwingHand()) {
|
||||
+ this.player.swing(InteractionHand.MAIN_HAND, swingAnimation, false);
|
||||
+ this.level.addBreakingBlockEffect(pos, blockHit);
|
||||
+ this.player.swing(InteractionHand.MAIN_HAND);
|
||||
+ }
|
||||
+ return;
|
||||
+ }
|
||||
Direction direction = blockHit.getDirection();
|
||||
- if (this.gameMode.continueDestroyBlock(pos, direction)) {
|
||||
- this.level.addBreakingBlockEffect(pos, direction);
|
||||
+ if (this.gameMode.continueDestroyBlock(pos, direction) && inputEvent.shouldSwingHand()) {
|
||||
this.player.swing(InteractionHand.MAIN_HAND, swingAnimation, false);
|
||||
this.player.connection.send(ServerboundPunchPacket.INSTANCE);
|
||||
+ this.level.addBreakingBlockEffect(pos, blockHit);
|
||||
this.player.swing(InteractionHand.MAIN_HAND);
|
||||
}
|
||||
@@ -1679,6 +_,8 @@
|
||||
}
|
||||
@@ -1676,6 +_,8 @@
|
||||
this.player.swing(InteractionHand.MAIN_HAND);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
+ var inputEvent = new net.minecraftforge.client.event.InputEvent.InteractionKeyMappingTriggered(0, this.options.keyAttack, InteractionHand.MAIN_HAND);
|
||||
+ if (!net.minecraftforge.client.event.InputEvent.InteractionKeyMappingTriggered.BUS.post(inputEvent))
|
||||
switch (this.hitResult.getType()) {
|
||||
case ENTITY:
|
||||
AttackRange customItemRange = heldItem.get(DataComponents.ATTACK_RANGE);
|
||||
@@ -1686,7 +_,7 @@
|
||||
case BLOCK:
|
||||
BlockHitResult blockHit = (BlockHitResult)this.hitResult;
|
||||
BlockPos pos = blockHit.getBlockPos();
|
||||
- if (!this.level.getBlockState(pos).isAir()) {
|
||||
+ if (!this.level.isEmptyBlock(pos)) {
|
||||
this.gameMode.startDestroyBlock(pos, blockHit.getDirection());
|
||||
if (this.level.getBlockState(pos).isAir()) {
|
||||
endAttack = true;
|
||||
@@ -1699,8 +_,10 @@
|
||||
}
|
||||
|
||||
+ var inputEvent = new net.minecraftforge.client.event.InputEvent.InteractionKeyMappingTriggered.Attack(this.options.keyAttack, InteractionHand.MAIN_HAND);
|
||||
+ if (!net.minecraftforge.client.event.InputEvent.InteractionKeyMappingTriggered.Attack.BUS.post(inputEvent))
|
||||
switch (this.hitResult.getType()) {
|
||||
case ENTITY:
|
||||
AttackRange customItemRange = heldItem.get(DataComponents.ATTACK_RANGE);
|
||||
@@ -1689,7 +_,7 @@
|
||||
case BLOCK:
|
||||
BlockHitResult blockHit = (BlockHitResult)this.hitResult;
|
||||
BlockPos pos = blockHit.getBlockPos();
|
||||
- if (!this.level.getBlockState(pos).isAir()) {
|
||||
+ if (!this.level.isEmptyBlock(pos)) {
|
||||
this.gameMode.startDestroyBlock(pos, blockHit.getDirection());
|
||||
if (this.level.getBlockState(pos).isAir()) {
|
||||
endAttack = true;
|
||||
@@ -1702,10 +_,13 @@
|
||||
}
|
||||
|
||||
this.player.resetAttackStrengthTicker();
|
||||
+ net.minecraftforge.event.ForgeEventFactory.onLeftClickEmpty(this.player);
|
||||
}
|
||||
|
||||
+ if (inputEvent.shouldSwingHand()) {
|
||||
this.player.swing(InteractionHand.MAIN_HAND, attackAnimation, false);
|
||||
this.player.connection.send(ServerboundPunchPacket.INSTANCE);
|
||||
+ }
|
||||
return endAttack;
|
||||
}
|
||||
}
|
||||
@@ -1726,6 +_,13 @@
|
||||
this.player.resetAttackStrengthTicker();
|
||||
+ net.minecraftforge.event.ForgeEventFactory.onLeftClickEmpty(this.player);
|
||||
}
|
||||
|
||||
SwingAnimation swingAnimation = heldItem.getInteractAnimation();
|
||||
+
|
||||
+ var inputEvent = new net.minecraftforge.client.event.InputEvent.InteractionKeyMappingTriggered.UseItem(this.options.keyUse, hand);
|
||||
+ if (net.minecraftforge.client.event.InputEvent.InteractionKeyMappingTriggered.UseItem.BUS.post(inputEvent)) {
|
||||
+ if (inputEvent.shouldSwingHand()) this.player.swing(hand, swingAnimation, false);
|
||||
+ if (inputEvent.shouldSwingHand())
|
||||
this.player.swing(InteractionHand.MAIN_HAND);
|
||||
return endAttack;
|
||||
}
|
||||
@@ -1717,6 +_,12 @@
|
||||
}
|
||||
|
||||
for (InteractionHand hand : InteractionHand.values()) {
|
||||
+ var inputEvent = new net.minecraftforge.client.event.InputEvent.InteractionKeyMappingTriggered(1, this.options.keyUse, hand);
|
||||
+ if (net.minecraftforge.client.event.InputEvent.InteractionKeyMappingTriggered.BUS.post(inputEvent)) {
|
||||
+ if (inputEvent.shouldSwingHand()) this.player.swing(hand);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if (this.hitResult != null) {
|
||||
switch (this.hitResult.getType()) {
|
||||
case ENTITY:
|
||||
@@ -1737,7 +_,7 @@
|
||||
ItemStack heldItem = this.player.getItemInHand(hand);
|
||||
if (!heldItem.isItemEnabled(this.level.enabledFeatures())) {
|
||||
return;
|
||||
@@ -1733,7 +_,7 @@
|
||||
|
||||
if (this.player.isWithinEntityInteractionRange(entity, 0.0)
|
||||
&& this.gameMode.interact(this.player, entity, entityHit, hand) instanceof InteractionResult.Success success) {
|
||||
- if (success.swingSource() == InteractionResult.SwingSource.PREDICTED) {
|
||||
+ if (success.swingSource() == InteractionResult.SwingSource.PREDICTED && inputEvent.shouldSwingHand()) {
|
||||
this.player.swing(hand, swingAnimation, false);
|
||||
- if (success.swingSource() == InteractionResult.SwingSource.CLIENT) {
|
||||
+ if (success.swingSource() == InteractionResult.SwingSource.CLIENT && inputEvent.shouldSwingHand()) {
|
||||
this.player.swing(hand);
|
||||
}
|
||||
|
||||
@@ -1749,7 +_,7 @@
|
||||
@@ -1745,7 +_,7 @@
|
||||
int oldCount = heldItem.getCount();
|
||||
InteractionResult useResult = this.gameMode.useItemOn(this.player, hand, blockHit);
|
||||
if (useResult instanceof InteractionResult.Success success) {
|
||||
- if (success.swingSource() == InteractionResult.SwingSource.PREDICTED) {
|
||||
+ if (success.swingSource() == InteractionResult.SwingSource.PREDICTED && inputEvent.shouldSwingHand()) {
|
||||
this.player.swing(hand, swingAnimation, false);
|
||||
- if (success.swingSource() == InteractionResult.SwingSource.CLIENT) {
|
||||
+ if (success.swingSource() == InteractionResult.SwingSource.CLIENT && inputEvent.shouldSwingHand()) {
|
||||
this.player.swing(hand);
|
||||
if (!heldItem.isEmpty() && (heldItem.getCount() != oldCount || this.player.hasInfiniteMaterials())) {
|
||||
this.player.itemUsed(hand);
|
||||
@@ -1765,6 +_,9 @@
|
||||
this.gameRenderer.itemInHandRenderer.itemUsed(hand);
|
||||
@@ -1761,6 +_,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,26 +265,26 @@
|
||||
+ net.minecraftforge.event.ForgeEventFactory.onRightClickEmpty(this.player, hand);
|
||||
+
|
||||
if (!heldItem.isEmpty() && this.gameMode.useItem(this.player, hand) instanceof InteractionResult.Success success) {
|
||||
if (success.swingSource() == InteractionResult.SwingSource.PREDICTED) {
|
||||
this.player.swing(hand, swingAnimation, false);
|
||||
@@ -1793,6 +_,8 @@
|
||||
if (success.swingSource() == InteractionResult.SwingSource.CLIENT) {
|
||||
this.player.swing(hand);
|
||||
@@ -1789,6 +_,8 @@
|
||||
}
|
||||
|
||||
ProfilerFiller profiler = Profiler.get();
|
||||
+ net.minecraftforge.event.ForgeEventFactory.onPreClientTick();
|
||||
+
|
||||
profiler.push("gameMode");
|
||||
if (!this.pause && this.level != null) {
|
||||
this.gameMode.tick();
|
||||
@@ -1845,6 +_,7 @@
|
||||
profiler.push("gui");
|
||||
this.textInputManager.tick();
|
||||
this.chatListener.tick();
|
||||
@@ -1871,6 +_,7 @@
|
||||
|
||||
this.tutorial.tick();
|
||||
|
||||
+ net.minecraftforge.event.ForgeEventFactory.onPreLevelTick(this.level, () -> true);
|
||||
try {
|
||||
this.level.tick(() -> true);
|
||||
} catch (Throwable t) {
|
||||
@@ -1858,6 +_,7 @@
|
||||
} catch (Throwable var6) {
|
||||
@@ -1884,6 +_,7 @@
|
||||
|
||||
throw new ReportedException(report);
|
||||
}
|
||||
@@ -245,7 +292,7 @@
|
||||
}
|
||||
|
||||
profiler.popPush("animateTick");
|
||||
@@ -1882,6 +_,7 @@
|
||||
@@ -1908,6 +_,7 @@
|
||||
profiler.popPush("keyboard");
|
||||
this.keyboardHandler.tick();
|
||||
profiler.pop();
|
||||
@@ -253,7 +300,7 @@
|
||||
}
|
||||
|
||||
private boolean isLevelRunningNormally() {
|
||||
@@ -2088,6 +_,7 @@
|
||||
@@ -2138,6 +_,7 @@
|
||||
}
|
||||
|
||||
public void setLevel(final ClientLevel level) {
|
||||
@@ -261,23 +308,23 @@
|
||||
this.level = level;
|
||||
this.updateLevelInEngines(level);
|
||||
}
|
||||
@@ -2149,6 +_,7 @@
|
||||
@@ -2199,6 +_,7 @@
|
||||
IntegratedServer server = this.singleplayerServer;
|
||||
this.singleplayerServer = null;
|
||||
this.gameRenderer.resetData();
|
||||
+ net.minecraftforge.client.event.ForgeEventFactoryClient.firePlayerLogout(this.gameMode, this.player);
|
||||
this.gameMode = null;
|
||||
this.narrator.clear();
|
||||
this.gui.setClientLevelTeardownInProgress(true);
|
||||
@@ -2156,6 +_,7 @@
|
||||
this.clientLevelTeardownInProgress = true;
|
||||
@@ -2206,6 +_,7 @@
|
||||
try {
|
||||
if (this.level != null) {
|
||||
this.gui.hud.onDisconnected();
|
||||
this.gui.onDisconnected();
|
||||
+ net.minecraftforge.event.ForgeEventFactory.onLevelUnload(this.level);
|
||||
}
|
||||
|
||||
this.level = null;
|
||||
@@ -2171,6 +_,7 @@
|
||||
@@ -2220,6 +_,7 @@
|
||||
}
|
||||
|
||||
profiler.pop();
|
||||
@@ -285,7 +332,7 @@
|
||||
}
|
||||
|
||||
this.setScreenAndShow(screen);
|
||||
@@ -2403,6 +_,7 @@
|
||||
@@ -2372,6 +_,7 @@
|
||||
|
||||
private void pickBlockOrEntity() {
|
||||
if (this.hitResult != null && this.hitResult.getType() != HitResult.Type.MISS) {
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
--- a/net/minecraft/client/MouseHandler.java
|
||||
+++ b/net/minecraft/client/MouseHandler.java
|
||||
@@ -79,6 +_,7 @@
|
||||
@@ -87,6 +_,7 @@
|
||||
this.activeButton = null;
|
||||
}
|
||||
|
||||
+ if (net.minecraftforge.client.event.ForgeEventFactoryClient.onMouseButtonPre(rawButtonInfo, action)) return;
|
||||
if (this.minecraft.gui.overlay() == null) {
|
||||
if (pressed
|
||||
&& this.minecraft
|
||||
@@ -104,7 +_,7 @@
|
||||
+ if (net.minecraftforge.client.event.ForgeEventFactoryClient.onMouseButtonPre(buttonInfo, action)) return;
|
||||
if (this.minecraft.getOverlay() == null) {
|
||||
if (this.minecraft.screen == null) {
|
||||
if (!this.mouseGrabbed && pressed) {
|
||||
@@ -106,7 +_,7 @@
|
||||
&& currentTime - this.lastClick.time() < 250L
|
||||
&& this.lastClick.screen() == screen
|
||||
&& this.lastClickButton == event.button();
|
||||
- if (screen.mouseClicked(event, doubleClick)) {
|
||||
+ if (net.minecraftforge.client.event.ForgeEventFactoryClient.onScreenMouseClicked(screen, xm, ym, event, doubleClick)) {
|
||||
this.lastClick = new MouseHandler.LastClick(currentTime, screen);
|
||||
this.lastClickButton = rawButtonInfo.button();
|
||||
this.lastClickButton = buttonInfo.button();
|
||||
return;
|
||||
@@ -118,7 +_,7 @@
|
||||
@@ -121,7 +_,7 @@
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
@@ -25,44 +25,44 @@
|
||||
+ if (net.minecraftforge.client.event.ForgeEventFactoryClient.onScreenMouseReleased(screen, xm, ym, event)) {
|
||||
return;
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
@@ -147,6 +_,7 @@
|
||||
} catch (Throwable var17) {
|
||||
@@ -151,6 +_,7 @@
|
||||
KeyMapping.click(mouseKey);
|
||||
}
|
||||
}
|
||||
+ net.minecraftforge.client.event.ForgeEventFactoryClient.onMouseButtonPost(rawButtonInfo, action);
|
||||
+ net.minecraftforge.client.event.ForgeEventFactoryClient.onMouseButtonPost(buttonInfo, action);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,7 +_,9 @@
|
||||
if (this.minecraft.gui.screen() != null) {
|
||||
@@ -202,7 +_,9 @@
|
||||
if (this.minecraft.screen != null) {
|
||||
double xm = this.getScaledXPos(this.minecraft.getWindow());
|
||||
double ym = this.getScaledYPos(this.minecraft.getWindow());
|
||||
- this.minecraft.gui.screen().mouseScrolled(xm, ym, scaledXOffset, scaledYOffset);
|
||||
+ if (net.minecraftforge.client.event.ForgeEventFactoryClient.onScreenMouseScrollPre(this.minecraft.gui.screen(), xm, ym, scaledXOffset, scaledYOffset)) return;
|
||||
+ if (this.minecraft.gui.screen().mouseScrolled(xm, ym, scaledXOffset, scaledYOffset)) return;
|
||||
+ net.minecraftforge.client.event.ForgeEventFactoryClient.onScreenMouseScrollPost(this.minecraft.gui.screen(), xm, ym, scaledXOffset, scaledYOffset);
|
||||
this.minecraft.gui.screen().afterMouseAction();
|
||||
- this.minecraft.screen.mouseScrolled(xm, ym, scaledXOffset, scaledYOffset);
|
||||
+ if (net.minecraftforge.client.event.ForgeEventFactoryClient.onScreenMouseScrollPre(this.minecraft.screen, xm, ym, scaledXOffset, scaledYOffset)) return;
|
||||
+ if (this.minecraft.screen.mouseScrolled(xm, ym, scaledXOffset, scaledYOffset)) return;
|
||||
+ net.minecraftforge.client.event.ForgeEventFactoryClient.onScreenMouseScrollPost(this.minecraft.screen, xm, ym, scaledXOffset, scaledYOffset);
|
||||
this.minecraft.screen.afterMouseAction();
|
||||
} else if (this.minecraft.player != null) {
|
||||
Vector2i wheelXY = this.scrollWheelHandler.onMouseScroll(scaledXOffset, scaledYOffset);
|
||||
@@ -191,6 +_,7 @@
|
||||
@@ -211,6 +_,7 @@
|
||||
}
|
||||
|
||||
int wheel = wheelXY.y == 0 ? -wheelXY.x : wheelXY.y;
|
||||
+ if (net.minecraftforge.client.event.ForgeEventFactoryClient.onMouseScroll(this, scaledXOffset, scaledYOffset)) return;
|
||||
if (this.minecraft.player.isSpectator()) {
|
||||
if (this.minecraft.gui.hud.getSpectatorGui().isMenuActive()) {
|
||||
this.minecraft.gui.hud.getSpectatorGui().onMouseScrolled(-wheel);
|
||||
@@ -285,7 +_,7 @@
|
||||
if (this.minecraft.gui.getSpectatorGui().isMenuActive()) {
|
||||
this.minecraft.gui.getSpectatorGui().onMouseScrolled(-wheel);
|
||||
@@ -317,7 +_,7 @@
|
||||
double dy = getScaledYPos(window, this.accumulatedDY);
|
||||
|
||||
try {
|
||||
- screen.mouseDragged(new MouseButtonEvent(xm, ym, this.activeButton), dx, dy);
|
||||
+ net.minecraftforge.client.ForgeHooksClient.onScreenMouseDrag(screen, new MouseButtonEvent(xm, ym, this.activeButton), dx, dy);
|
||||
} catch (Throwable t) {
|
||||
CrashReport report = CrashReport.forThrowable(t, "mouseDragged event handler");
|
||||
CrashReportCategory mouseDetails = report.addCategory("Mouse");
|
||||
@@ -369,6 +_,14 @@
|
||||
} catch (Throwable var19) {
|
||||
CrashReport report = CrashReport.forThrowable(var19, "mouseDragged event handler");
|
||||
screen.fillCrashDetails(report);
|
||||
@@ -402,6 +_,14 @@
|
||||
|
||||
public double ypos() {
|
||||
return this.ypos;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/client/Options.java
|
||||
+++ b/net/minecraft/client/Options.java
|
||||
@@ -1011,6 +_,7 @@
|
||||
@@ -929,6 +_,7 @@
|
||||
);
|
||||
public boolean syncWrites;
|
||||
public boolean startedCleanly = true;
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
public static boolean isSoundDeviceDefault(final String deviceName) {
|
||||
return deviceName.equals("");
|
||||
@@ -1510,6 +_,7 @@
|
||||
@@ -1404,6 +_,7 @@
|
||||
}
|
||||
|
||||
public Options(final Minecraft minecraft, final File workingDirectory) {
|
||||
@@ -16,7 +16,7 @@
|
||||
this.minecraft = minecraft;
|
||||
this.optionsFile = new File(workingDirectory, "options.txt");
|
||||
boolean largeDistances = Runtime.getRuntime().maxMemory() >= 1000000000L;
|
||||
@@ -1663,20 +_,32 @@
|
||||
@@ -1556,15 +_,28 @@
|
||||
this.startedCleanly = access.process("startedCleanly", this.startedCleanly);
|
||||
access.process("musicToast", this.musicToast);
|
||||
access.process("musicFrequency", this.musicFrequency);
|
||||
@@ -31,18 +31,13 @@
|
||||
+ String currentValue = keyMapping.saveString() + (keyMapping.getKeyModifier() != net.minecraftforge.client.settings.KeyModifier.NONE ? ":" + keyMapping.getKeyModifier() : "");
|
||||
String newValue = access.process("key_" + keyMapping.getName(), currentValue);
|
||||
if (!currentValue.equals(newValue)) {
|
||||
try {
|
||||
- keyMapping.setKey(InputConstants.getKey(newValue));
|
||||
+ if (newValue.indexOf(':') != -1) {
|
||||
+ String[] pts = newValue.split(":");
|
||||
+ keyMapping.setKeyModifierAndCode(net.minecraftforge.client.settings.KeyModifier.valueFromString(pts[1]), InputConstants.getKey(pts[0]));
|
||||
+ } else {
|
||||
+ keyMapping.setKeyModifierAndCode(net.minecraftforge.client.settings.KeyModifier.NONE, InputConstants.getKey(newValue));
|
||||
+ }
|
||||
} catch (IllegalArgumentException e) {
|
||||
LOGGER.warn("Invalid keyMapping {} = {}, unbinding", keyMapping.getName(), newValue, e);
|
||||
keyMapping.setKey(InputConstants.UNKNOWN);
|
||||
}
|
||||
keyMapping.setKey(InputConstants.getKey(newValue));
|
||||
+ if (newValue.indexOf(':') != -1) {
|
||||
+ String[] pts = newValue.split(":");
|
||||
+ keyMapping.setKeyModifierAndCode(net.minecraftforge.client.settings.KeyModifier.valueFromString(pts[1]), InputConstants.getKey(pts[0]));
|
||||
+ } else {
|
||||
+ keyMapping.setKeyModifierAndCode(net.minecraftforge.client.settings.KeyModifier.NONE, InputConstants.getKey(newValue));
|
||||
+ }
|
||||
}
|
||||
}
|
||||
+ }
|
||||
@@ -51,7 +46,7 @@
|
||||
for (SoundSource source : SoundSource.values()) {
|
||||
access.process("soundCategory_" + source.getName(), this.soundSourceVolumes.get(source));
|
||||
}
|
||||
@@ -1691,6 +_,10 @@
|
||||
@@ -1579,6 +_,10 @@
|
||||
}
|
||||
|
||||
public void load() {
|
||||
@@ -62,7 +57,7 @@
|
||||
try {
|
||||
if (!this.optionsFile.exists()) {
|
||||
return;
|
||||
@@ -1710,7 +_,8 @@
|
||||
@@ -1598,7 +_,8 @@
|
||||
}
|
||||
|
||||
final CompoundTag options = this.dataFix(rawOptions);
|
||||
@@ -70,9 +65,9 @@
|
||||
+ java.util.function.Consumer<FieldAccess> processor = limited ? this::processOptionsKeysOnly : this::processOptions;
|
||||
+ processor.accept(
|
||||
new Options.FieldAccess() {
|
||||
private @Nullable String getValue(final String name) {
|
||||
Tag tag = options.get(name);
|
||||
@@ -1792,6 +_,17 @@
|
||||
{
|
||||
Objects.requireNonNull(Options.this);
|
||||
@@ -1680,6 +_,17 @@
|
||||
);
|
||||
options.getString("fullscreenResolution").ifPresent(fullscreenResolution -> this.fullscreenVideoModeString = fullscreenResolution);
|
||||
KeyMapping.resetMapping();
|
||||
@@ -87,22 +82,26 @@
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Failed to load options", e);
|
||||
} catch (Exception var7) {
|
||||
LOGGER.error("Failed to load options", (Throwable)var7);
|
||||
}
|
||||
@@ -1821,9 +_,11 @@
|
||||
@@ -1707,6 +_,7 @@
|
||||
public void save() {
|
||||
try (final PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(this.optionsFile), StandardCharsets.UTF_8))) {
|
||||
writer.println("version:" + SharedConstants.getCurrentVersion().dataVersion().version());
|
||||
+ var seen = new java.util.HashSet<String>();
|
||||
this.processOptions(
|
||||
new Options.FieldAccess() {
|
||||
{
|
||||
@@ -1714,6 +_,7 @@
|
||||
}
|
||||
|
||||
public void writePrefix(final String name) {
|
||||
+ seen.add(name);
|
||||
writer.print(name);
|
||||
writer.print(':');
|
||||
}
|
||||
@@ -1879,6 +_,12 @@
|
||||
@@ -1769,6 +_,12 @@
|
||||
if (fullscreenVideoModeString != null) {
|
||||
writer.println("fullscreenResolution:" + fullscreenVideoModeString);
|
||||
}
|
||||
@@ -112,10 +111,10 @@
|
||||
+ writer.println(entry.getKey() + ":" + entry.getValue());
|
||||
+ }
|
||||
+
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Failed to save options", e);
|
||||
} catch (Exception var6) {
|
||||
LOGGER.error("Failed to save options", (Throwable)var6);
|
||||
}
|
||||
@@ -1916,6 +_,7 @@
|
||||
@@ -1806,6 +_,7 @@
|
||||
}
|
||||
|
||||
public void broadcastOptions() {
|
||||
@@ -123,7 +122,7 @@
|
||||
if (this.minecraft.player != null) {
|
||||
this.minecraft.player.connection.broadcastClientInformation(this.buildPlayerInformation());
|
||||
}
|
||||
@@ -2029,6 +_,23 @@
|
||||
@@ -1923,6 +_,23 @@
|
||||
|
||||
public static Component genericValueLabel(final Component caption, final int value) {
|
||||
return genericValueLabel(caption, Component.literal(Integer.toString(value)));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/client/Screenshot.java
|
||||
+++ b/net/minecraft/client/Screenshot.java
|
||||
@@ -53,14 +_,24 @@
|
||||
@@ -44,6 +_,13 @@
|
||||
file = new File(picDir, forceName);
|
||||
}
|
||||
|
||||
@@ -14,17 +14,19 @@
|
||||
Util.ioPool()
|
||||
.execute(
|
||||
() -> {
|
||||
try (image) {
|
||||
- image.writeToFile(file);
|
||||
- Component component = Component.literal(file.getName())
|
||||
+ image.writeToFile(outputFile);
|
||||
+ Component component = Component.literal(outputFile.getName())
|
||||
.withStyle(ChatFormatting.UNDERLINE)
|
||||
- .withStyle(s -> s.withClickEvent(new ClickEvent.OpenFile(file.getAbsoluteFile())));
|
||||
+ .withStyle(s -> s.withClickEvent(new ClickEvent.OpenFile(outputFile.getAbsoluteFile())));
|
||||
+ if (event.getResultMessage() != null)
|
||||
+ callback.accept(event.getResultMessage());
|
||||
+ else
|
||||
callback.accept(Component.translatable("screenshot.success", component));
|
||||
} catch (Exception e) {
|
||||
LOGGER.warn("Couldn't save screenshot", e);
|
||||
@@ -51,10 +_,13 @@
|
||||
NativeImage twrVar0$ = image;
|
||||
|
||||
try {
|
||||
- image.writeToFile(file);
|
||||
- Component component = Component.literal(file.getName())
|
||||
+ image.writeToFile(outputFile);
|
||||
+ Component component = Component.literal(outputFile.getName())
|
||||
.withStyle(ChatFormatting.UNDERLINE)
|
||||
.withStyle(s -> s.withClickEvent(new ClickEvent.OpenFile(file.getAbsoluteFile())));
|
||||
+ if (event.getResultMessage() != null)
|
||||
+ callback.accept(event.getResultMessage());
|
||||
+ else
|
||||
callback.accept(Component.translatable("screenshot.success", component));
|
||||
} catch (Throwable var7) {
|
||||
if (image != null) {
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/client/data/models/ItemModelGenerators.java
|
||||
+++ b/net/minecraft/client/data/models/ItemModelGenerators.java
|
||||
@@ -921,6 +_,9 @@
|
||||
@@ -909,6 +_,9 @@
|
||||
this.declareCustomModelItem(Items.COD);
|
||||
this.declareCustomModelItem(Items.FEATHER);
|
||||
this.declareCustomModelItem(Items.LEAD);
|
||||
|
||||
@@ -100,8 +100,8 @@
|
||||
ClientItem donorInfo = this.itemInfos.get(donor);
|
||||
if (donorInfo == null) {
|
||||
@@ -131,8 +_,8 @@
|
||||
|
||||
this.register(acceptor, donorInfo);
|
||||
this.register(acceptor, donorInfo);
|
||||
}
|
||||
});
|
||||
- List<Identifier> missingDefinitions = BuiltInRegistries.ITEM
|
||||
- .listElements()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/client/gui/Font.java
|
||||
+++ b/net/minecraft/client/gui/Font.java
|
||||
@@ -28,7 +_,7 @@
|
||||
@@ -33,7 +_,7 @@
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
|
||||
@@ -1,79 +1,116 @@
|
||||
--- a/net/minecraft/client/gui/Gui.java
|
||||
+++ b/net/minecraft/client/gui/Gui.java
|
||||
@@ -67,7 +_,7 @@
|
||||
import org.slf4j.Logger;
|
||||
@@ -150,7 +_,7 @@
|
||||
public float vignetteBrightness = 1.0F;
|
||||
private int toolHighlightTimer;
|
||||
private ItemStack lastToolHighlight = ItemStack.EMPTY;
|
||||
- private final DebugScreenOverlay debugOverlay;
|
||||
+ protected DebugScreenOverlay debugOverlay;
|
||||
private final SubtitleOverlay subtitleOverlay;
|
||||
private final SpectatorGui spectatorGui;
|
||||
private final PlayerTabOverlay tabList;
|
||||
@@ -192,6 +_,7 @@
|
||||
() -> new JumpableVehicleBarRenderer(minecraft)
|
||||
);
|
||||
this.resetTitleTimes();
|
||||
+ net.minecraftforge.client.gui.overlay.ForgeLayeredDraw.init(this, minecraft);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
-public class Gui {
|
||||
+public class Gui extends net.minecraftforge.client.gui.overlay.ForgeLayerInstance {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final SectionCategory TRACY_CURRENT_SCREEN = TracyClient.createSectionCategory("Current Screen");
|
||||
private static final Component SOCIAL_INTERACTIONS_NOT_AVAILABLE = Component.translatable("multiplayer.socialInteractions.not_available");
|
||||
@@ -85,6 +_,7 @@
|
||||
private @Nullable TutorialToast socialInteractionsToast;
|
||||
public void resetTitleTimes() {
|
||||
@@ -202,6 +_,10 @@
|
||||
|
||||
public Gui(final Minecraft minecraft, final Hud hud, final GuiRenderState guiRenderState) {
|
||||
+ super(minecraft);
|
||||
this.minecraft = minecraft;
|
||||
this.hud = hud;
|
||||
this.splashManager = new SplashManager(minecraft.getUser());
|
||||
@@ -174,7 +_,7 @@
|
||||
profiler.push("screen");
|
||||
|
||||
try {
|
||||
- this.screen.extractRenderStateWithTooltipAndSubtitles(graphics, xMouse, yMouse, deltaTracker.getGameTimeDeltaTicks());
|
||||
+ drawScreen(graphics, xMouse, yMouse, deltaTracker.getRealtimeDeltaTicks());
|
||||
} catch (Throwable t) {
|
||||
CrashReport report = CrashReport.forThrowable(t, "Rendering screen");
|
||||
CrashReportCategory category = report.addCategory("Screen render details");
|
||||
@@ -228,14 +_,6 @@
|
||||
this.screenTracySection = null;
|
||||
}
|
||||
|
||||
- if (this.screen != null) {
|
||||
- this.screen.clearFocus();
|
||||
- this.minecraft.textInputManager().stopTextInput();
|
||||
- this.screen.removed();
|
||||
- } else {
|
||||
- this.minecraft.setLastInputType(InputType.NONE);
|
||||
- }
|
||||
-
|
||||
if (screen == null) {
|
||||
if (this.clientLevelTeardownInProgress) {
|
||||
throw new IllegalStateException("Trying to return to in-game GUI during disconnection");
|
||||
@@ -254,6 +_,24 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ clearLayers();
|
||||
+ Screen old = this.screen;
|
||||
+ if (screen != null) {
|
||||
+ var event = net.minecraftforge.client.event.ForgeEventFactoryClient.onScreenOpening(old, screen);
|
||||
+ if (event == null) return;
|
||||
+ screen = event;
|
||||
+ }
|
||||
+
|
||||
+ if (screen != old) {
|
||||
+ if (old != null) {
|
||||
+ net.minecraftforge.client.event.ForgeEventFactoryClient.onScreenClose(old);
|
||||
+ this.screen.clearFocus();
|
||||
+ this.minecraft.textInputManager().stopTextInput();
|
||||
+ old.removed();
|
||||
+ } else {
|
||||
+ this.minecraft.setLastInputType(InputType.NONE);
|
||||
public void extractRenderState(final GuiGraphicsExtractor graphics, final DeltaTracker deltaTracker) {
|
||||
if (!(this.minecraft.screen instanceof LevelLoadingScreen)) {
|
||||
+ if (Boolean.valueOf(true)) {
|
||||
+ net.minecraftforge.client.gui.overlay.ForgeLayeredDraw.extractRenderState(graphics, deltaTracker);
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
this.screen = screen;
|
||||
if (this.screen != null) {
|
||||
this.screen.added();
|
||||
@@ -474,5 +_,10 @@
|
||||
if (!this.minecraft.options.hideGui) {
|
||||
this.extractCameraOverlays(graphics, deltaTracker);
|
||||
this.extractCrosshair(graphics, deltaTracker);
|
||||
@@ -385,7 +_,7 @@
|
||||
int mouseX = Mth.floor(this.minecraft.mouseHandler.getScaledXPos(window));
|
||||
int mouseY = Mth.floor(this.minecraft.mouseHandler.getScaledYPos(window));
|
||||
graphics.nextStratum();
|
||||
- this.chat.extractRenderState(graphics, this.getFont(), this.tickCount, mouseX, mouseY, ChatComponent.DisplayMode.BACKGROUND, false);
|
||||
+ net.minecraftforge.client.ForgeHooksClient.onCustomizeChatEvent(graphics, this.chat, window, mouseX, mouseY, this.tickCount, this.getFont());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -478,6 +_,8 @@
|
||||
|
||||
for (MobEffectInstance instance : Ordering.natural().reverse().sortedCopy(activeEffects)) {
|
||||
Holder<MobEffect> effect = instance.getEffect();
|
||||
+ var renderer = net.minecraftforge.client.extensions.common.IClientMobEffectExtensions.of(instance);
|
||||
+ if (!renderer.isVisibleInGui(instance)) continue;
|
||||
if (instance.showIcon()) {
|
||||
int x = graphics.guiWidth();
|
||||
int y = 1;
|
||||
@@ -508,6 +_,7 @@
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
+ if (renderer.extractGuiIcon(instance, this, graphics, x, y, 0, alpha)) continue;
|
||||
graphics.blitSprite(RenderPipelines.GUI_TEXTURED, getMobEffectSprite(effect), x + 3, y + 3, 18, 18, ARGB.white(alpha));
|
||||
}
|
||||
}
|
||||
@@ -610,15 +_,37 @@
|
||||
}
|
||||
|
||||
public void extractSelectedItemName(final GuiGraphicsExtractor graphics) {
|
||||
+ renderSelectedItemName(graphics, 0);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ protected void setScreenInternal(Screen value) {
|
||||
+ this.screen = value;
|
||||
+ // Forge: Maintain vanilla parity during FLD#BACKGROUND
|
||||
+ public final void updateContextualInfo(final GuiGraphicsExtractor graphics, DeltaTracker deltaTracker) {
|
||||
+ Gui.ContextualInfo nextContextualInfo = this.nextContextualInfoState();
|
||||
+ if (nextContextualInfo != this.contextualInfoBar.getKey()) {
|
||||
+ this.contextualInfoBar = Pair.of(nextContextualInfo, this.contextualInfoBarRenderers.get(nextContextualInfo).get());
|
||||
+ }
|
||||
+
|
||||
+ this.contextualInfoBar.getValue().extractBackground(graphics, deltaTracker);
|
||||
+ }
|
||||
+ // Forge: Same as above but for FLD#CONTEXTUAL_INFO
|
||||
+ public final void extractContextualInfoState(final GuiGraphicsExtractor graphics, DeltaTracker deltaTracker) {
|
||||
+ this.contextualInfoBar.getValue().extractRenderState(graphics, deltaTracker);
|
||||
+ }
|
||||
+
|
||||
+ public void renderSelectedItemName(final GuiGraphicsExtractor graphics, int yShift) {
|
||||
if (this.toolHighlightTimer > 0 && !this.lastToolHighlight.isEmpty()) {
|
||||
MutableComponent str = Component.empty().append(this.lastToolHighlight.getHoverName()).withStyle(this.lastToolHighlight.getRarity().color());
|
||||
if (this.lastToolHighlight.has(DataComponents.CUSTOM_NAME)) {
|
||||
str.withStyle(ChatFormatting.ITALIC);
|
||||
}
|
||||
|
||||
- int strWidth = this.getFont().width(str);
|
||||
+ Component highlightTip = this.lastToolHighlight.getHighlightTip(str);
|
||||
+ Font font = net.minecraftforge.client.extensions.common.IClientItemExtensions.of(lastToolHighlight).getFont(lastToolHighlight, net.minecraftforge.client.extensions.common.IClientItemExtensions.FontContext.SELECTED_ITEM_NAME);
|
||||
+ if (font == null)
|
||||
+ font = this.getFont();
|
||||
+ int strWidth = font.width(highlightTip);
|
||||
int x = (graphics.guiWidth() - strWidth) / 2;
|
||||
- int y = graphics.guiHeight() - 59;
|
||||
+ int y = graphics.guiHeight() - Math.max(yShift, 59);
|
||||
if (!this.minecraft.gameMode.canHurtPlayer()) {
|
||||
y += 14;
|
||||
}
|
||||
@@ -629,7 +_,7 @@
|
||||
}
|
||||
|
||||
if (alpha > 0) {
|
||||
- graphics.textWithBackdrop(this.getFont(), str, x, y, strWidth, ARGB.white(alpha));
|
||||
+ graphics.textWithBackdrop(font, highlightTip, x, y, strWidth, ARGB.white(alpha));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1195,7 +_,9 @@
|
||||
this.toolHighlightTimer = 0;
|
||||
} else if (this.lastToolHighlight.isEmpty()
|
||||
|| !selected.is(this.lastToolHighlight.getItem())
|
||||
- || !selected.getHoverName().equals(this.lastToolHighlight.getHoverName())) {
|
||||
+ || !selected.getHoverName().equals(this.lastToolHighlight.getHoverName())
|
||||
+ || !selected.getHighlightTip(selected.getHoverName()).equals(lastToolHighlight.getHighlightTip(lastToolHighlight.getHoverName()))
|
||||
+ ) {
|
||||
this.toolHighlightTimer = (int)(40.0 * this.minecraft.options.notificationDisplayTime().get());
|
||||
} else if (this.toolHighlightTimer > 0) {
|
||||
this.toolHighlightTimer--;
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/client/gui/GuiGraphicsExtractor.java
|
||||
+++ b/net/minecraft/client/gui/GuiGraphicsExtractor.java
|
||||
@@ -85,7 +_,7 @@
|
||||
@@ -88,7 +_,7 @@
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
@@ -10,7 +10,7 @@
|
||||
private final Minecraft minecraft;
|
||||
private final Matrix3x2fStack pose;
|
||||
@@ -914,6 +_,7 @@
|
||||
CrashReport report = CrashReport.forThrowable(t, "Rendering item");
|
||||
CrashReport report = CrashReport.forThrowable(var11, "Rendering item");
|
||||
CrashReportCategory category = report.addCategory("Item being rendered");
|
||||
category.setDetail("Item Type", () -> String.valueOf(itemStack.getItem()));
|
||||
+ category.setDetail("Registry Name", () -> String.valueOf(net.minecraftforge.registries.ForgeRegistries.ITEMS.getKey(itemStack.getItem())));
|
||||
@@ -25,7 +25,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1109,16 +_,29 @@
|
||||
@@ -1112,16 +_,25 @@
|
||||
this.setTooltipForNextFrame(this.minecraft.font, formattedCharSequences, DefaultTooltipPositioner.INSTANCE, x, y, false);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
public void setTooltipForNextFrame(final Font font, final ItemStack itemStack, final int xo, final int yo) {
|
||||
+ this.tooltipStack = itemStack;
|
||||
this.setTooltipForNextFrame(
|
||||
font, Screen.getTooltipFromItem(this.minecraft, itemStack), itemStack.getTooltipImage(), xo, yo, itemStack.get(DataComponents.TOOLTIP_STYLE), true
|
||||
font, Screen.getTooltipFromItem(this.minecraft, itemStack), itemStack.getTooltipImage(), xo, yo, itemStack.get(DataComponents.TOOLTIP_STYLE)
|
||||
);
|
||||
+ this.tooltipStack = ItemStack.EMPTY;
|
||||
}
|
||||
@@ -43,21 +43,17 @@
|
||||
}
|
||||
|
||||
+ public void setTooltipForNextFrame(Font font, List<Component> texts, Optional<TooltipComponent> optionalImage, ItemStack stack, int xo, int yo) {
|
||||
+ this.setTooltipForNextFrame(font, texts, optionalImage, stack, xo, yo, false);
|
||||
+ }
|
||||
+
|
||||
+ public void setTooltipForNextFrame(Font font, List<Component> texts, Optional<TooltipComponent> optionalImage, ItemStack stack, int xo, int yo, final boolean extraSpaceAfterFirstLine) {
|
||||
+ this.tooltipStack = stack;
|
||||
+ this.setTooltipForNextFrame(font, texts, optionalImage, xo, yo, stack.get(DataComponents.TOOLTIP_STYLE), extraSpaceAfterFirstLine);
|
||||
+ this.tooltipStack = ItemStack.EMPTY;
|
||||
+ this.tooltipStack = stack;
|
||||
+ this.setTooltipForNextFrame(font, texts, optionalImage, xo, yo, stack.get(DataComponents.TOOLTIP_STYLE));
|
||||
+ this.tooltipStack = ItemStack.EMPTY;
|
||||
+ }
|
||||
+
|
||||
public void setTooltipForNextFrame(
|
||||
final Font font,
|
||||
final List<Component> texts,
|
||||
@@ -1139,11 +_,7 @@
|
||||
final @Nullable Identifier style,
|
||||
final boolean extraSpaceAfterFirstLine
|
||||
@@ -1130,11 +_,7 @@
|
||||
final int yo,
|
||||
final @Nullable Identifier style
|
||||
) {
|
||||
- List<ClientTooltipComponent> components = texts.stream()
|
||||
- .map(Component::getVisualOrderText)
|
||||
@@ -65,10 +61,10 @@
|
||||
- .collect(Util.toMutableList());
|
||||
- optionalImage.ifPresent(image -> components.add(components.isEmpty() ? 0 : 1, ClientTooltipComponent.create(image)));
|
||||
+ List<ClientTooltipComponent> components = net.minecraftforge.client.ForgeHooksClient.gatherTooltipComponents(this.tooltipStack, texts, optionalImage, xo, guiWidth(), guiHeight(), font);
|
||||
this.setTooltipForNextFrameInternal(font, components, xo, yo, DefaultTooltipPositioner.INSTANCE, style, false, extraSpaceAfterFirstLine);
|
||||
this.setTooltipForNextFrameInternal(font, components, xo, yo, DefaultTooltipPositioner.INSTANCE, style, false);
|
||||
}
|
||||
|
||||
@@ -1171,7 +_,22 @@
|
||||
@@ -1162,7 +_,22 @@
|
||||
}
|
||||
|
||||
public void setComponentTooltipForNextFrame(final Font font, final List<Component> lines, final int xo, final int yo) {
|
||||
@@ -92,34 +88,36 @@
|
||||
}
|
||||
|
||||
public void setComponentTooltipForNextFrame(final Font font, final List<Component> lines, final int xo, final int yo, final @Nullable Identifier style) {
|
||||
@@ -1235,9 +_,14 @@
|
||||
@@ -1213,10 +_,16 @@
|
||||
) {
|
||||
if (!lines.isEmpty()) {
|
||||
if (this.deferredTooltip == null || replaceExisting) {
|
||||
- this.deferredTooltip = () -> this.tooltip(font, lines, xo, yo, positioner, style, extraSpaceAfterFirstLine);
|
||||
- this.deferredTooltip = () -> this.tooltip(font, lines, xo, yo, positioner, style);
|
||||
+ final var stackContext = this.tooltipStack;
|
||||
+ this.deferredTooltip = () -> this.tooltip(font, lines, xo, yo, positioner, style, extraSpaceAfterFirstLine, stackContext);
|
||||
+ this.deferredTooltip = () -> this.tooltip(font, lines, xo, yo, positioner, style, stackContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
+
|
||||
+ public void tooltip(Font font, List<ClientTooltipComponent> lines, int xo, int yo, ClientTooltipPositioner positioner, @Nullable Identifier style) {
|
||||
+ tooltip(font, lines, xo, yo, positioner, style, ItemStack.EMPTY);
|
||||
+ }
|
||||
+
|
||||
+ public void tooltip(Font font, List<ClientTooltipComponent> lines, int xo, int yo, ClientTooltipPositioner positioner, @Nullable Identifier style, boolean extraSpaceAfterFirstLine) {
|
||||
+ tooltip(font, lines, xo, yo, positioner, style, extraSpaceAfterFirstLine, ItemStack.EMPTY);
|
||||
}
|
||||
|
||||
public void tooltip(
|
||||
@@ -1247,13 +_,16 @@
|
||||
final Font font,
|
||||
@@ -1224,13 +_,16 @@
|
||||
final int xo,
|
||||
final int yo,
|
||||
final ClientTooltipPositioner positioner,
|
||||
final @Nullable Identifier style,
|
||||
- boolean extraSpaceAfterFirstLine
|
||||
+ boolean extraSpaceAfterFirstLine,
|
||||
- final @Nullable Identifier style
|
||||
+ final @Nullable Identifier style,
|
||||
+ ItemStack itemstack
|
||||
) {
|
||||
+ var preEvent = net.minecraftforge.client.ForgeHooksClient.onRenderTooltipPre(itemstack, this, xo, yo, guiWidth(), guiHeight(), lines, font, positioner, style);
|
||||
+ if (preEvent == null) return;
|
||||
int textWidth = 0;
|
||||
int tempHeight = extraSpaceAfterFirstLine && lines.size() != 1 ? 0 : -2;
|
||||
int tempHeight = lines.size() == 1 ? -2 : 0;
|
||||
|
||||
for (ClientTooltipComponent line : lines) {
|
||||
- int lineWidth = line.getWidth(font);
|
||||
@@ -127,25 +125,25 @@
|
||||
if (lineWidth > textWidth) {
|
||||
textWidth = lineWidth;
|
||||
}
|
||||
@@ -1263,25 +_,25 @@
|
||||
@@ -1240,25 +_,25 @@
|
||||
|
||||
int w = textWidth;
|
||||
int h = tempHeight;
|
||||
- Vector2ic positionedTooltip = positioner.positionTooltip(this.guiWidth(), this.guiHeight(), xo, yo, w, h);
|
||||
+ Vector2ic positionedTooltip = positioner.positionTooltip(this.guiWidth(), this.guiHeight(), preEvent.getX(), preEvent.getY(), w, h);
|
||||
- Vector2ic positionedTooltip = positioner.positionTooltip(this.guiWidth(), this.guiHeight(), xo, yo, textWidth, tempHeight);
|
||||
+ Vector2ic positionedTooltip = positioner.positionTooltip(this.guiWidth(), this.guiHeight(), preEvent.getX(), preEvent.getY(), textWidth, tempHeight);
|
||||
int x = positionedTooltip.x();
|
||||
int y = positionedTooltip.y();
|
||||
this.pose.pushMatrix();
|
||||
- TooltipRenderUtil.extractTooltipBackground(this, x, y, w, h, style);
|
||||
+ TooltipRenderUtil.extractTooltipBackground(this, x, y, w, h, preEvent.getBackground());
|
||||
- TooltipRenderUtil.extractTooltipBackground(this, x, y, textWidth, tempHeight, style);
|
||||
+ TooltipRenderUtil.extractTooltipBackground(this, x, y, textWidth, tempHeight, preEvent.getBackground());
|
||||
int localY = y;
|
||||
|
||||
for (int i = 0; i < lines.size(); i++) {
|
||||
ClientTooltipComponent line = lines.get(i);
|
||||
- line.extractText(this, font, x, localY);
|
||||
- localY += line.getHeight(font) + (extraSpaceAfterFirstLine && i == 0 ? 2 : 0);
|
||||
- localY += line.getHeight(font) + (i == 0 ? 2 : 0);
|
||||
+ line.extractText(this, preEvent.getFont(), x, localY);
|
||||
+ localY += line.getHeight(preEvent.getFont()) + (extraSpaceAfterFirstLine && i == 0 ? 2 : 0);
|
||||
+ localY += line.getHeight(preEvent.getFont()) + (i == 0 ? 2 : 0);
|
||||
}
|
||||
|
||||
localY = y;
|
||||
@@ -153,13 +151,13 @@
|
||||
for (int i = 0; i < lines.size(); i++) {
|
||||
ClientTooltipComponent line = lines.get(i);
|
||||
- line.extractImage(font, x, localY, w, h, this);
|
||||
- localY += line.getHeight(font) + (extraSpaceAfterFirstLine && i == 0 ? 2 : 0);
|
||||
- localY += line.getHeight(font) + (i == 0 ? 2 : 0);
|
||||
+ line.extractImage(preEvent.getFont(), x, localY, w, h, this);
|
||||
+ localY += line.getHeight(preEvent.getFont()) + (extraSpaceAfterFirstLine && i == 0 ? 2 : 0);
|
||||
+ localY += line.getHeight(preEvent.getFont()) + (i == 0 ? 2 : 0);
|
||||
}
|
||||
|
||||
this.pose.popMatrix();
|
||||
@@ -1355,6 +_,14 @@
|
||||
@@ -1333,6 +_,14 @@
|
||||
|
||||
private ActiveTextCollector.Parameters createDefaultTextParameters(final float opacity) {
|
||||
return new ActiveTextCollector.Parameters(new Matrix3x2f(this.pose), opacity, this.scissorStack.peek());
|
||||
|
||||
@@ -1,116 +0,0 @@
|
||||
--- a/net/minecraft/client/gui/Hud.java
|
||||
+++ b/net/minecraft/client/gui/Hud.java
|
||||
@@ -157,7 +_,7 @@
|
||||
public float vignetteBrightness = 1.0F;
|
||||
private int toolHighlightTimer;
|
||||
private ItemStack lastToolHighlight = ItemStack.EMPTY;
|
||||
- private final DebugScreenOverlay debugOverlay;
|
||||
+ protected DebugScreenOverlay debugOverlay;
|
||||
private final SubtitleOverlay subtitleOverlay;
|
||||
private final SpectatorGui spectatorGui;
|
||||
private final PlayerTabOverlay tabList;
|
||||
@@ -199,6 +_,7 @@
|
||||
() -> new JumpableVehicleBar(minecraft)
|
||||
);
|
||||
this.resetTitleTimes();
|
||||
+ net.minecraftforge.client.gui.overlay.ForgeLayeredDraw.init(this, minecraft);
|
||||
}
|
||||
|
||||
public void registerReloadListeners(final ReloadableResourceManager resourceManager) {
|
||||
@@ -222,6 +_,10 @@
|
||||
public void extractRenderState(final GuiGraphicsExtractor graphics, final DeltaTracker deltaTracker) {
|
||||
this.minecraft.gameRenderer.gameRenderState().guiRenderState.isHudHidden = this.isHidden;
|
||||
if (!(this.minecraft.gui.screen() instanceof LevelLoadingScreen)) {
|
||||
+ if (Boolean.valueOf(true)) {
|
||||
+ net.minecraftforge.client.gui.overlay.ForgeLayeredDraw.extractRenderState(graphics, deltaTracker);
|
||||
+ return;
|
||||
+ }
|
||||
if (!this.isHidden) {
|
||||
this.extractCameraOverlays(graphics, deltaTracker);
|
||||
this.extractCrosshair(graphics, deltaTracker);
|
||||
@@ -405,7 +_,7 @@
|
||||
int mouseX = Mth.floor(this.minecraft.mouseHandler.getScaledXPos(window));
|
||||
int mouseY = Mth.floor(this.minecraft.mouseHandler.getScaledYPos(window));
|
||||
graphics.nextStratum();
|
||||
- this.chat.extractRenderState(graphics, this.getFont(), this.tickCount, mouseX, mouseY, ChatComponent.DisplayMode.BACKGROUND, false);
|
||||
+ net.minecraftforge.client.ForgeHooksClient.onCustomizeChatEvent(graphics, this.chat, window, mouseX, mouseY, this.tickCount, this.getFont());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -500,6 +_,8 @@
|
||||
|
||||
for (MobEffectInstance instance : Ordering.natural().reverse().sortedCopy(activeEffects)) {
|
||||
Holder<MobEffect> effect = instance.getEffect();
|
||||
+ var renderer = net.minecraftforge.client.extensions.common.IClientMobEffectExtensions.of(instance);
|
||||
+ if (!renderer.isVisibleInGui(instance)) continue;
|
||||
if (instance.showIcon()) {
|
||||
int x = graphics.guiWidth();
|
||||
int y = 1;
|
||||
@@ -530,6 +_,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ if (renderer.extractGuiIcon(instance, this, graphics, x, y, 0, alpha)) continue;
|
||||
graphics.blitSprite(RenderPipelines.GUI_TEXTURED, getMobEffectSprite(effect), x + 3, y + 3, 18, 18, ARGB.white(alpha));
|
||||
}
|
||||
}
|
||||
@@ -632,15 +_,37 @@
|
||||
}
|
||||
|
||||
public void extractSelectedItemName(final GuiGraphicsExtractor graphics) {
|
||||
+ renderSelectedItemName(graphics, 0);
|
||||
+ }
|
||||
+
|
||||
+ // Forge: Maintain vanilla parity during FLD#BACKGROUND
|
||||
+ public final void updateContextualInfo(final GuiGraphicsExtractor graphics, DeltaTracker deltaTracker) {
|
||||
+ var nextContextualInfo = this.nextContextualInfoState();
|
||||
+ if (nextContextualInfo != this.contextualInfoBar.getFirst()) {
|
||||
+ this.contextualInfoBar = Pair.of(nextContextualInfo, this.contextualInfoBars.get(nextContextualInfo).get());
|
||||
+ }
|
||||
+
|
||||
+ this.contextualInfoBar.getSecond().extractBackground(graphics, deltaTracker);
|
||||
+ }
|
||||
+ // Forge: Same as above but for FLD#CONTEXTUAL_INFO
|
||||
+ public final void extractContextualInfoState(final GuiGraphicsExtractor graphics, DeltaTracker deltaTracker) {
|
||||
+ this.contextualInfoBar.getSecond().extractRenderState(graphics, deltaTracker);
|
||||
+ }
|
||||
+
|
||||
+ public void renderSelectedItemName(final GuiGraphicsExtractor graphics, int yShift) {
|
||||
if (this.toolHighlightTimer > 0 && !this.lastToolHighlight.isEmpty()) {
|
||||
MutableComponent str = Component.empty().append(this.lastToolHighlight.getHoverName()).withStyle(this.lastToolHighlight.getRarity().color());
|
||||
if (this.lastToolHighlight.has(DataComponents.CUSTOM_NAME)) {
|
||||
str.withStyle(ChatFormatting.ITALIC);
|
||||
}
|
||||
|
||||
- int strWidth = this.getFont().width(str);
|
||||
+ Component highlightTip = this.lastToolHighlight.getHighlightTip(str);
|
||||
+ Font font = net.minecraftforge.client.extensions.common.IClientItemExtensions.of(lastToolHighlight).getFont(lastToolHighlight, net.minecraftforge.client.extensions.common.IClientItemExtensions.FontContext.SELECTED_ITEM_NAME);
|
||||
+ if (font == null)
|
||||
+ font = this.getFont();
|
||||
+ int strWidth = font.width(highlightTip);
|
||||
int x = (graphics.guiWidth() - strWidth) / 2;
|
||||
- int y = graphics.guiHeight() - 59;
|
||||
+ int y = graphics.guiHeight() - Math.max(yShift, 59);
|
||||
if (!this.minecraft.gameMode.canHurtPlayer()) {
|
||||
y += 14;
|
||||
}
|
||||
@@ -651,7 +_,7 @@
|
||||
}
|
||||
|
||||
if (alpha > 0) {
|
||||
- graphics.textWithBackdrop(this.getFont(), str, x, y, strWidth, ARGB.white(alpha));
|
||||
+ graphics.textWithBackdrop(font, highlightTip, x, y, strWidth, ARGB.white(alpha));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1219,7 +_,9 @@
|
||||
this.toolHighlightTimer = 0;
|
||||
} else if (this.lastToolHighlight.isEmpty()
|
||||
|| !selected.is(this.lastToolHighlight.getItem())
|
||||
- || !selected.getHoverName().equals(this.lastToolHighlight.getHoverName())) {
|
||||
+ || !selected.getHoverName().equals(this.lastToolHighlight.getHoverName())
|
||||
+ || !selected.getHighlightTip(selected.getHoverName()).equals(lastToolHighlight.getHighlightTip(lastToolHighlight.getHoverName()))
|
||||
+ ) {
|
||||
this.toolHighlightTimer = (int)(40.0 * this.minecraft.options.notificationDisplayTime().get());
|
||||
} else if (this.toolHighlightTimer > 0) {
|
||||
this.toolHighlightTimer--;
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/client/gui/components/AbstractWidget.java
|
||||
+++ b/net/minecraft/client/gui/components/AbstractWidget.java
|
||||
@@ -225,6 +_,23 @@
|
||||
@@ -221,6 +_,23 @@
|
||||
this.focused = focused;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
--- a/net/minecraft/client/gui/components/BossHealthOverlay.java
|
||||
+++ b/net/minecraft/client/gui/components/BossHealthOverlay.java
|
||||
@@ -68,13 +_,16 @@
|
||||
|
||||
for (LerpingBossEvent event : this.events.values()) {
|
||||
int xLeft = screenWidth / 2 - 91;
|
||||
int yo = yOffset;
|
||||
+ var progressEvent = net.minecraftforge.client.ForgeHooksClient.onCustomizeBossEventProgress(graphics, this.minecraft.getWindow(), event, xLeft, yOffset, 10 + this.minecraft.font.lineHeight);
|
||||
+ if (progressEvent != null) {
|
||||
this.extractBar(graphics, xLeft, yo, event);
|
||||
this.extractBar(graphics, xLeft, yOffset, event);
|
||||
Component msg = event.getName();
|
||||
int width = this.minecraft.font.width(msg);
|
||||
int x = screenWidth / 2 - width / 2;
|
||||
int y = yo - 9;
|
||||
int y = yOffset - 9;
|
||||
graphics.text(this.minecraft.font, msg, x, y, -1);
|
||||
- yOffset += 10 + 9;
|
||||
+ }
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/client/gui/components/toasts/ToastManager.java
|
||||
+++ b/net/minecraft/client/gui/components/toasts/ToastManager.java
|
||||
@@ -142,6 +_,7 @@
|
||||
@@ -143,6 +_,7 @@
|
||||
}
|
||||
|
||||
public void addToast(final Toast toast) {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
--- a/net/minecraft/client/gui/render/GuiRenderer.java
|
||||
+++ b/net/minecraft/client/gui/render/GuiRenderer.java
|
||||
@@ -110,6 +_,7 @@
|
||||
@@ -130,6 +_,7 @@
|
||||
builder.put((Class<? extends PictureInPictureRenderState>)pictureInPictureRenderer.getRenderStateClass(), pictureInPictureRenderer);
|
||||
}
|
||||
|
||||
+ net.minecraftforge.client.ForgeHooksClient.onRegisterPictureInPictureRenderers(pictureInPictureRenderers, builder);
|
||||
+ net.minecraftforge.client.ForgeHooksClient.onRegisterPictureInPictureRenderers(pictureInPictureRenderers, bufferSource, builder);
|
||||
this.pictureInPictureRenderers = builder.buildOrThrow();
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
--- a/net/minecraft/client/gui/screens/ChatScreen.java
|
||||
+++ b/net/minecraft/client/gui/screens/ChatScreen.java
|
||||
@@ -141,6 +_,7 @@
|
||||
this.handleChatInput(this.input.getValue(), true);
|
||||
if (this.closeOnSubmit) {
|
||||
this.exitReason = ChatScreen.ExitReason.DONE;
|
||||
+ if (this.minecraft.gui.screen() == this) // FORGE: Prevent closing the screen if another screen has been opened.
|
||||
this.minecraft.gui.setScreen(null);
|
||||
} else {
|
||||
this.input.setValue("");
|
||||
@@ -139,6 +_,7 @@
|
||||
this.handleChatInput(this.input.getValue(), true);
|
||||
if (this.closeOnSubmit) {
|
||||
this.exitReason = ChatScreen.ExitReason.DONE;
|
||||
+ if (this.minecraft.screen == this) // FORGE: Prevent closing the screen if another screen has been opened.
|
||||
this.minecraft.setScreen(null);
|
||||
} else {
|
||||
this.input.setValue("");
|
||||
@@ -1,11 +1,11 @@
|
||||
--- a/net/minecraft/client/gui/screens/ConnectScreen.java
|
||||
+++ b/net/minecraft/client/gui/screens/ConnectScreen.java
|
||||
@@ -109,6 +_,8 @@
|
||||
@@ -114,6 +_,8 @@
|
||||
}
|
||||
|
||||
if (resolvedAddress.isEmpty()) {
|
||||
+ ConnectScreen.LOGGER.error("Couldn't connect to server: Unknown host \"{}\"", hostAndPort.getHost());
|
||||
+ net.minecraftforge.network.DualStackUtils.logInitialPreferences();
|
||||
minecraft.execute(
|
||||
() -> minecraft.gui
|
||||
.setScreen(
|
||||
() -> minecraft.setScreen(
|
||||
new DisconnectedScreen(ConnectScreen.this.parent, ConnectScreen.this.connectFailedTitle, ConnectScreen.UNKNOWN_HOST_MESSAGE)
|
||||
@@ -16,7 +16,7 @@
|
||||
+ if (extractContentRenderState(graphics, logoAlpha)) {
|
||||
int contentX = (int)(graphics.guiWidth() * 0.5);
|
||||
int logoY = (int)(graphics.guiHeight() * 0.5);
|
||||
double logoHeight = Math.min(graphics.guiWidth() * 0.75, graphics.guiHeight()) * 0.25;
|
||||
double logoHeight = Math.min(graphics.guiWidth() * 0.75, (double)graphics.guiHeight()) * 0.25;
|
||||
@@ -148,6 +_,7 @@
|
||||
graphics, width / 2 - logoWidthHalf, barY - 5, width / 2 + logoWidthHalf, barY + 5, 1.0F - Mth.clamp(fadeOutAnim, 0.0F, 1.0F)
|
||||
);
|
||||
@@ -24,7 +24,7 @@
|
||||
+ }
|
||||
|
||||
if (fadeOutAnim >= 2.0F) {
|
||||
this.minecraft.gui.setOverlay(null);
|
||||
this.minecraft.setOverlay(null);
|
||||
@@ -157,6 +_,7 @@
|
||||
@Override
|
||||
public void tick() {
|
||||
@@ -34,10 +34,10 @@
|
||||
this.reload.checkExceptions();
|
||||
this.onFinish.accept(Optional.empty());
|
||||
@@ -164,7 +_,6 @@
|
||||
this.onFinish.accept(Optional.of(t));
|
||||
this.onFinish.accept(Optional.of(var2));
|
||||
}
|
||||
|
||||
- this.fadeOutStart = Util.getMillis();
|
||||
if (this.minecraft.gui.screen() != null) {
|
||||
if (this.minecraft.screen != null) {
|
||||
Window window = this.minecraft.getWindow();
|
||||
this.minecraft.gui.screen().init(window.getGuiScaledWidth(), window.getGuiScaledHeight());
|
||||
this.minecraft.screen.init(window.getGuiScaledWidth(), window.getGuiScaledHeight());
|
||||
@@ -1,10 +1,10 @@
|
||||
--- a/net/minecraft/client/gui/screens/PauseScreen.java
|
||||
+++ b/net/minecraft/client/gui/screens/PauseScreen.java
|
||||
@@ -163,6 +_,7 @@
|
||||
helper.addChild(this.openScreenButton(OPTIONS, () -> new OptionsScreen(this, this.minecraft.options)));
|
||||
helper.addChild(this.openScreenButton(WORLD_OPTIONS, () -> new WorldOptionsScreen(this, this.minecraft.level)));
|
||||
@@ -102,6 +_,7 @@
|
||||
} else {
|
||||
helper.addChild(this.openScreenButton(PLAYER_REPORTING, () -> new SocialInteractionsScreen(this)));
|
||||
}
|
||||
+ helper.addChild(Button.builder(Component.translatable("fml.menu.mods"), button -> this.minecraft.gui.setScreen(new net.minecraftforge.client.gui.ModListScreen(this))).width(BUTTON_WIDTH_FULL).build(), 2);
|
||||
+ helper.addChild(Button.builder(Component.translatable("fml.menu.mods"), button -> this.minecraft.setScreen(new net.minecraftforge.client.gui.ModListScreen(this))).width(BUTTON_WIDTH_FULL).build(), 2);
|
||||
|
||||
this.disconnectButton = helper.addChild(
|
||||
Button.builder(
|
||||
@@ -1,15 +1,15 @@
|
||||
--- a/net/minecraft/client/gui/screens/Screen.java
|
||||
+++ b/net/minecraft/client/gui/screens/Screen.java
|
||||
@@ -202,7 +_,7 @@
|
||||
@@ -194,7 +_,7 @@
|
||||
}
|
||||
|
||||
public void onClose() {
|
||||
- this.minecraft.gui.setScreen(null);
|
||||
+ this.minecraft.gui.popLayer();
|
||||
- this.minecraft.setScreen(null);
|
||||
+ this.minecraft.popGuiLayer();
|
||||
}
|
||||
|
||||
protected <T extends GuiEventListener & Renderable & NarratableEntry> T addRenderableWidget(final T widget) {
|
||||
@@ -333,8 +_,10 @@
|
||||
@@ -326,8 +_,10 @@
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
if (!this.initialized) {
|
||||
@@ -20,7 +20,7 @@
|
||||
} else {
|
||||
this.repositionElements();
|
||||
}
|
||||
@@ -351,8 +_,10 @@
|
||||
@@ -344,8 +_,10 @@
|
||||
protected void rebuildWidgets() {
|
||||
this.clearWidgets();
|
||||
this.clearFocus();
|
||||
@@ -31,16 +31,16 @@
|
||||
}
|
||||
|
||||
protected void fadeWidgets(final float widgetFade) {
|
||||
@@ -392,6 +_,8 @@
|
||||
@@ -385,6 +_,8 @@
|
||||
this.extractMenuBackground(graphics);
|
||||
}
|
||||
|
||||
+ net.minecraftforge.client.event.ForgeEventFactoryClient.onRenderScreenBackground(this, graphics);
|
||||
+
|
||||
this.minecraft.gui.hud.extractDeferredSubtitles();
|
||||
this.minecraft.gui.extractDeferredSubtitles();
|
||||
}
|
||||
|
||||
@@ -472,6 +_,19 @@
|
||||
@@ -474,6 +_,19 @@
|
||||
}
|
||||
|
||||
public void onFilesDrop(final List<Path> files) {
|
||||
@@ -59,4 +59,4 @@
|
||||
+ this.children.add(guiEventListener);
|
||||
}
|
||||
|
||||
private void scheduleNarration(final long delay, final boolean ignoreSuppression, final NarrationTrigger narrationTrigger) {
|
||||
private void scheduleNarration(final long delay, final boolean ignoreSuppression) {
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/client/gui/screens/TitleScreen.java
|
||||
+++ b/net/minecraft/client/gui/screens/TitleScreen.java
|
||||
@@ -57,6 +_,7 @@
|
||||
@@ -53,6 +_,7 @@
|
||||
private boolean fading;
|
||||
private long fadeInStart;
|
||||
private final LogoRenderer logoRenderer;
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
public TitleScreen() {
|
||||
this(false);
|
||||
@@ -114,11 +_,15 @@
|
||||
@@ -105,11 +_,15 @@
|
||||
int copyrightX = this.width - copyrightWidth - 2;
|
||||
int spacing = 24;
|
||||
int topPos = this.height / 4 + 48;
|
||||
@@ -17,23 +17,23 @@
|
||||
topPos = this.createDemoMenuOptions(topPos, 24);
|
||||
} else {
|
||||
topPos = this.createNormalMenuOptions(topPos, 24);
|
||||
+ modButton = this.addRenderableWidget(Button.builder(Component.translatable("fml.menu.mods"), button -> this.minecraft.gui.setScreen(new net.minecraftforge.client.gui.ModListScreen(this)))
|
||||
+ .pos(this.width / 2 - 100, topPos).size(98, 20).build());
|
||||
+ modButton = this.addRenderableWidget(Button.builder(Component.translatable("fml.menu.mods"), button -> this.minecraft.setScreen(new net.minecraftforge.client.gui.ModListScreen(this)))
|
||||
+ .pos(this.width / 2 - 100, topPos).size(98, 20).build());
|
||||
}
|
||||
+ modUpdateNotification = net.minecraftforge.client.gui.TitleScreenModUpdateIndicator.init(this, modButton);
|
||||
|
||||
int numberOfButtons = 3;
|
||||
int currentButton = 0;
|
||||
@@ -199,7 +_,7 @@
|
||||
}).bounds(this.width / 2 - 100, var7 = topPos + spacing, 200, 20).tooltip(tooltip).build()).active = multiplayerAllowed;
|
||||
topPos = this.createTestWorldButton(topPos, 24);
|
||||
SpriteIconButton language = this.addRenderableWidget(
|
||||
@@ -182,7 +_,7 @@
|
||||
}).bounds(this.width / 2 - 100, var6 = topPos + spacing, 200, 20).tooltip(tooltip).build()).active = multiplayerAllowed;
|
||||
this.addRenderableWidget(
|
||||
Button.builder(Component.translatable("menu.online"), var1 -> this.minecraft.gui.setScreen(new RealmsMainScreen(this)))
|
||||
- .bounds(this.width / 2 - 100, topPos = var7 + spacing, 200, 20)
|
||||
+ .bounds(this.width / 2 + 2, topPos = var7 + spacing, 98, 20)
|
||||
Button.builder(Component.translatable("menu.online"), button -> this.minecraft.setScreen(new RealmsMainScreen(this)))
|
||||
- .bounds(this.width / 2 - 100, topPos = var6 + spacing, 200, 20)
|
||||
+ .bounds(this.width / 2 + 2, topPos = var6 + spacing, 98, 20)
|
||||
.tooltip(tooltip)
|
||||
.build()
|
||||
)
|
||||
@@ -323,9 +_,18 @@
|
||||
@@ -310,9 +_,18 @@
|
||||
versionString = versionString + I18n.get("menu.modded");
|
||||
}
|
||||
|
||||
|
||||
Loaded 100 of 1036 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user