Compare commits

..
3 Commits
620 changed files with 9553 additions and 5714 deletions

No files matched your search

+1 -1
View File
@@ -2,7 +2,7 @@ name: Publish
on:
push:
branches: [ '26.3' ]
branches: [ '26.2' ]
permissions:
contents: read
+27 -34
View File
@@ -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) }
}
}
}
*/
+1 -1
View File
@@ -3,7 +3,7 @@
MinecraftForge
=============
[![Stable Release](https://img.shields.io/badge/dynamic/json?url=https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json&label=Stable&prefix=26.2-&query=$.promos["26.2-recommended"]&color=brightgreen&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBjbGFzcz0ic3ZnLWlubGluZS0tZmEgZmEtc3RhciBmYS13LTE4IiBhcmlhLWhpZGRlbj0idHJ1ZSIgZGF0YS1pY29uPSJzdGFyIiBkYXRhLXByZWZpeD0iZmFzIiBmb2N1c2FibGU9ImZhbHNlIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCA1NzYgNTEyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgo8cGF0aCBkPSJNMjU5LjMgMTcuOEwxOTQgMTUwLjIgNDcuOSAxNzEuNWMtMjYuMiAzLjgtMzYuNyAzNi4xLTE3LjcgNTQuNmwxMDUuNyAxMDMtMjUgMTQ1LjVjLTQuNSAyNi4zIDIzLjIgNDYgNDYuNCAzMy43TDI4OCA0MzkuNmwxMzAuNyA2OC43YzIzLjIgMTIuMiA1MC45LTcuNCA0Ni40LTMzLjdsLTI1LTE0NS41IDEwNS43LTEwM2MxOS0xOC41IDguNS01MC44LTE3LjctNTQuNkwzODIgMTUwLjIgMzE2LjcgMTcuOGMtMTEuNy0yMy42LTQ1LjYtMjMuOS01Ny40IDB6IiBmaWxsPSJ3aGl0ZSIvPgo8L3N2Zz4K)][Download]
[![Latest Release](https://img.shields.io/badge/dynamic/json?url=https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json&label=Latest&prefix=26.3-&query=$.promos["26.3-latest"]&color=blue&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBjbGFzcz0ic3ZnLWlubGluZS0tZmEgZmEtYnVnIGZhLXctMTYiIGFyaWEtaGlkZGVuPSJ0cnVlIiBkYXRhLWljb249ImJ1ZyIgZGF0YS1wcmVmaXg9ImZhcyIgZm9jdXNhYmxlPSJmYWxzZSIgcm9sZT0iaW1nIiB2aWV3Qm94PSIwIDAgNTEyIDUxMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTUxMS45ODggMjg4LjljLS40NzggMTcuNDMtMTUuMjE3IDMxLjEtMzIuNjUzIDMxLjFINDI0djE2YzAgMjEuODY0LTQuODgyIDQyLjU4NC0xMy42IDYxLjE0NWw2MC4yMjggNjAuMjI4YzEyLjQ5NiAxMi40OTcgMTIuNDk2IDMyLjc1OCAwIDQ1LjI1NS0xMi40OTggMTIuNDk3LTMyLjc1OSAxMi40OTYtNDUuMjU2IDBsLTU0LjczNi01NC43MzZDMzQ1Ljg4NiA0NjcuOTY1IDMxNC4zNTEgNDgwIDI4MCA0ODBWMjM2YzAtNi42MjctNS4zNzMtMTItMTItMTJoLTI0Yy02LjYyNyAwLTEyIDUuMzczLTEyIDEydjI0NGMtMzQuMzUxIDAtNjUuODg2LTEyLjAzNS05MC42MzYtMzIuMTA4bC01NC43MzYgNTQuNzM2Yy0xMi40OTggMTIuNDk3LTMyLjc1OSAxMi40OTYtNDUuMjU2IDAtMTIuNDk2LTEyLjQ5Ny0xMi40OTYtMzIuNzU4IDAtNDUuMjU1bDYwLjIyOC02MC4yMjhDOTIuODgyIDM3OC41ODQgODggMzU3Ljg2NCA4OCAzMzZ2LTE2SDMyLjY2NkMxNS4yMyAzMjAgLjQ5MSAzMDYuMzMuMDEzIDI4OC45LS40ODQgMjcwLjgxNiAxNC4wMjggMjU2IDMyIDI1Nmg1NnYtNTguNzQ1bC00Ni42MjgtNDYuNjI4Yy0xMi40OTYtMTIuNDk3LTEyLjQ5Ni0zMi43NTggMC00NS4yNTUgMTIuNDk4LTEyLjQ5NyAzMi43NTgtMTIuNDk3IDQ1LjI1NiAwTDE0MS4yNTUgMTYwaDIyOS40ODlsNTQuNjI3LTU0LjYyN2MxMi40OTgtMTIuNDk3IDMyLjc1OC0xMi40OTcgNDUuMjU2IDAgMTIuNDk2IDEyLjQ5NyAxMi40OTYgMzIuNzU4IDAgNDUuMjU1TDQyNCAxOTcuMjU1VjI1Nmg1NmMxNy45NzIgMCAzMi40ODQgMTQuODE2IDMxLjk4OCAzMi45ek0yNTcgMGMtNjEuODU2IDAtMTEyIDUwLjE0NC0xMTIgMTEyaDIyNEMzNjkgNTAuMTQ0IDMxOC44NTYgMCAyNTcgMHoiIGZpbGw9IndoaXRlIi8+Cjwvc3ZnPgo=
[![Latest Release](https://img.shields.io/badge/dynamic/json?url=https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json&label=Latest&prefix=26.2-&query=$.promos["26.2-latest"]&color=blue&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBjbGFzcz0ic3ZnLWlubGluZS0tZmEgZmEtYnVnIGZhLXctMTYiIGFyaWEtaGlkZGVuPSJ0cnVlIiBkYXRhLWljb249ImJ1ZyIgZGF0YS1wcmVmaXg9ImZhcyIgZm9jdXNhYmxlPSJmYWxzZSIgcm9sZT0iaW1nIiB2aWV3Qm94PSIwIDAgNTEyIDUxMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTUxMS45ODggMjg4LjljLS40NzggMTcuNDMtMTUuMjE3IDMxLjEtMzIuNjUzIDMxLjFINDI0djE2YzAgMjEuODY0LTQuODgyIDQyLjU4NC0xMy42IDYxLjE0NWw2MC4yMjggNjAuMjI4YzEyLjQ5NiAxMi40OTcgMTIuNDk2IDMyLjc1OCAwIDQ1LjI1NS0xMi40OTggMTIuNDk3LTMyLjc1OSAxMi40OTYtNDUuMjU2IDBsLTU0LjczNi01NC43MzZDMzQ1Ljg4NiA0NjcuOTY1IDMxNC4zNTEgNDgwIDI4MCA0ODBWMjM2YzAtNi42MjctNS4zNzMtMTItMTItMTJoLTI0Yy02LjYyNyAwLTEyIDUuMzczLTEyIDEydjI0NGMtMzQuMzUxIDAtNjUuODg2LTEyLjAzNS05MC42MzYtMzIuMTA4bC01NC43MzYgNTQuNzM2Yy0xMi40OTggMTIuNDk3LTMyLjc1OSAxMi40OTYtNDUuMjU2IDAtMTIuNDk2LTEyLjQ5Ny0xMi40OTYtMzIuNzU4IDAtNDUuMjU1bDYwLjIyOC02MC4yMjhDOTIuODgyIDM3OC41ODQgODggMzU3Ljg2NCA4OCAzMzZ2LTE2SDMyLjY2NkMxNS4yMyAzMjAgLjQ5MSAzMDYuMzMuMDEzIDI4OC45LS40ODQgMjcwLjgxNiAxNC4wMjggMjU2IDMyIDI1Nmg1NnYtNTguNzQ1bC00Ni42MjgtNDYuNjI4Yy0xMi40OTYtMTIuNDk3LTEyLjQ5Ni0zMi43NTggMC00NS4yNTUgMTIuNDk4LTEyLjQ5NyAzMi43NTgtMTIuNDk3IDQ1LjI1NiAwTDE0MS4yNTUgMTYwaDIyOS40ODlsNTQuNjI3LTU0LjYyN2MxMi40OTgtMTIuNDk3IDMyLjc1OC0xMi40OTcgNDUuMjU2IDAgMTIuNDk2IDEyLjQ5NyAxMi40OTYgMzIuNzU4IDAgNDUuMjU1TDQyNCAxOTcuMjU1VjI1Nmg1NmMxNy45NzIgMCAzMi40ODQgMTQuODE2IDMxLjk4OCAzMi45ek0yNTcgMGMtNjEuODU2IDAtMTEyIDUwLjE0NC0xMTIgMTEyaDIyNEMzNjkgNTAuMTQ0IDMxOC44NTYgMCAyNTcgMHoiIGZpbGw9IndoaXRlIi8+Cjwvc3ZnPgo=
)][Download] [![Discord](https://img.shields.io/discord/313125603924639766.svg?color=%237289da&label=Discord&logo=discord&logoColor=%237289da)][Discord] [![Support](https://img.shields.io/badge/Patreon-Support-orange.svg?logo=Patreon)][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();
@@ -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) {
+2 -2
View File
@@ -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() } }
}
@@ -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);
@@ -117,8 +116,8 @@ public class DisplayWindow implements ImmediateWindowProvider {
@Override
public ImmediateWindowProvider selectBackend(String backend) {
// We only support opengl
//if ("default".equals(backend) || "opengl".equals(backend))
// return this;
if ("default".equals(backend) || "opengl".equals(backend))
return this;
return ImmediateWindowProvider.getFallbackHandler();
}
@@ -185,7 +184,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 +196,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 +212,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 +227,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 +253,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 +294,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 +342,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 +418,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 +553,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 +585,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 +658,7 @@ public class DisplayWindow implements ImmediateWindowProvider {
@Override
public void periodicTick() {
pollEvents();
glfwPollEvents();
repaintTick.run();
}
@@ -650,67 +673,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;
}
}
@@ -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;
@@ -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)
@@ -102,8 +102,8 @@ public class ImmediateWindowHandler {
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) {
@@ -155,9 +155,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);
@@ -86,9 +86,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
@@ -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"
@@ -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
*/
@@ -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();
+4 -4
View File
@@ -1,6 +1,6 @@
[versions]
java = "25"
minecraft = "26.3"
minecraft-next = "26.4"
mcp = "20260918.230105"
changelog-base = "66.0"
minecraft = "26.2"
minecraft-next = "26.3"
mcp = "20260616.103818"
changelog-base = "65.0"
@@ -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
@@ -201,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())
@@ -1,5 +1,5 @@
--- a/com/mojang/renderpearl/backend/opengl/GlConst.java
+++ b/com/mojang/renderpearl/backend/opengl/GlConst.java
--- a/com/mojang/blaze3d/opengl/GlConst.java
+++ b/com/mojang/blaze3d/opengl/GlConst.java
@@ -239,6 +_,10 @@
}
@@ -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)
@@ -1,6 +1,20 @@
--- a/com/mojang/renderpearl/backend/opengl/GlDevice.java
+++ b/com/mojang/renderpearl/backend/opengl/GlDevice.java
@@ -200,6 +_,11 @@
--- a/com/mojang/blaze3d/opengl/GlDevice.java
+++ b/com/mojang/blaze3d/opengl/GlDevice.java
@@ -150,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 GpuFormat 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
@@ -163,6 +_,11 @@
final int depthOrLayers,
final int mipLevels
) {
@@ -12,7 +26,7 @@
GlStateManager.clearGlErrors();
int id = GlStateManager._genTexture();
if (label == null) {
@@ -223,9 +_,9 @@
@@ -186,9 +_,9 @@
GlStateManager._texParameter(target, 34892, 0);
}
@@ -25,7 +39,7 @@
if (glInternalID != 0 && glExternalID != 0 && glType != 0) {
if (isCubemap) {
for (int cubeTarget : GlConst.CUBEMAP_TARGETS) {
@@ -248,7 +_,7 @@
@@ -211,7 +_,7 @@
throw new IllegalStateException("OpenGL error " + error);
}
@@ -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
@@ -80,6 +_,11 @@
}
}
+ public static boolean _isBlendEnabled(int index) {
+ RenderSystem.assertOnRenderThread();
+ return BLEND_ENABLE[index];
+ return BLEND[index].mode.enabled;
+ }
+
public static void _disableBlend(final int index) {
public static void _disableBlend(int index) {
RenderSystem.assertOnRenderThread();
if (BLEND_ENABLE[index]) {
@@ -401,9 +_,17 @@
BLEND[index].mode.disable();
@@ -390,9 +_,17 @@
}
}
@@ -0,0 +1,30 @@
--- a/com/mojang/blaze3d/opengl/GlTexture.java
+++ b/com/mojang/blaze3d/opengl/GlTexture.java
@@ -27,9 +_,14 @@
final int id,
final FrameBufferCache frameBufferCache
) {
+ 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);
this.id = id;
this.frameBufferCache = frameBufferCache;
+ this.stencilEnabled = stencil;
}
@Override
@@ -84,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 @@
@@ -83,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, GpuFormat.D32_FLOAT, width, height, 1, 1);
+ this.depthTexture = device.createTexture(() -> this.label + " / Depth", 15, GpuFormat.D32_FLOAT, width, height, 1, 1, this.stencilEnabled);
this.depthTextureView = device.createTextureView(this.depthTexture);
}
@@ -140,5 +_,26 @@
@@ -121,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();
@@ -101,8 +_,9 @@
Monitor initialMonitor = monitorManager.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.monitor() : 0L);
+ this.handle = net.minecraftforge.fml.loading.ImmediateWindowHandler.setupMinecraftWindow(this.width, this.height, title, this.fullscreen && initialMonitor != null ? initialMonitor.monitor() : 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.x() + mode.getWidth() / 2 - this.width / 2;
@@ -114,6 +_,7 @@
this.windowedX = this.x = actualX[0];
this.windowedY = this.y = actualY[0];
}
+ }
this.setMode();
this.refreshFramebufferSize();
@@ -148,6 +_,10 @@
@@ -306,6 +_,9 @@
outHeight[0] = this.isSoftScreen() ? outHeight[0] - 1 : outHeight[0];
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) {
@@ -1,14 +1,13 @@
--- 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);
--- a/com/mojang/blaze3d/systems/GpuDevice.java
+++ b/com/mojang/blaze3d/systems/GpuDevice.java
@@ -73,6 +_,21 @@
return this.backend.createTexture(label, usage, format, width, height, depthOrLayers, mipLevels);
}
+ /** Forge: same as {@link #createTexture(Supplier, int, GpuFormat, int, int, int, int)} but with stencil support */
+ @Override
+ /** Forge: same as {@link #createTexture(Supplier, int, GpuFormat, int, int, int)} but with stencil support */
+ public GpuTexture createTexture(
+ final @Nullable Supplier<String> label,
+ final @GpuTexture.Usage int usage,
+ @GpuTexture.Usage final int usage,
+ final GpuFormat format,
+ final int width,
+ final int height,
@@ -16,23 +15,23 @@
+ final int mipLevels,
+ final boolean stencil
+ ) {
+ return this.createTexture(this.isDebuggingEnabled() && label != null ? label.get() : null, usage, format, width, height, depthOrLayers, mipLevels, stencil);
+ this.verifyTextureCreationArgs(usage, width, height, depthOrLayers, mipLevels);
+ return this.backend.createTexture(label, usage, format, width, height, depthOrLayers, mipLevels, stencil);
+ }
+
@Override
public GpuTexture createTexture(
final @Nullable String label,
@@ -106,6 +_,22 @@
final @GpuTexture.Usage int usage,
@@ -84,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(String, int, GpuFormat, int, int, int, int)} but with stencil support */
+ @Override
+ /** Forge: same as {@link #createTexture(Supplier, int, GpuFormat, int, int, int)} but with stencil support */
+ public GpuTexture createTexture(
+ final @Nullable String label,
+ final @GpuTexture.Usage int usage,
+ @GpuTexture.Usage final int usage,
+ final GpuFormat format,
+ final int width,
+ final int height,
@@ -0,0 +1,20 @@
--- a/com/mojang/blaze3d/systems/GpuDeviceBackend.java
+++ b/com/mojang/blaze3d/systems/GpuDeviceBackend.java
@@ -32,7 +_,17 @@
@Nullable Supplier<String> label, @GpuTexture.Usage int usage, GpuFormat format, int width, int height, int depthOrLayers, int mipLevels
);
+ /** Forge: same as {@link #createTexture(Supplier<String>, int, GpuFormat, int, int, int)} but with stencil support */
+ default GpuTexture createTexture(@Nullable Supplier<String> label, @GpuTexture.Usage final 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);
+
+ /** Forge: same as {@link #createTexture(String, int, GpuFormat, int, int, int)} but with stencil support */
+ default GpuTexture createTexture(@Nullable String label, @GpuTexture.Usage final 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);
@@ -0,0 +1,11 @@
--- a/com/mojang/blaze3d/textures/GpuTexture.java
+++ b/com/mojang/blaze3d/textures/GpuTexture.java
@@ -9,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)
@@ -1,5 +1,5 @@
--- a/com/mojang/renderpearl/api/vertex/VertexFormat.java
+++ b/com/mojang/renderpearl/api/vertex/VertexFormat.java
--- a/com/mojang/blaze3d/vertex/VertexFormat.java
+++ b/com/mojang/blaze3d/vertex/VertexFormat.java
@@ -19,6 +_,7 @@
private final int vertexSize;
private final int stepRate;
@@ -8,7 +8,7 @@
private VertexFormat(final List<VertexFormatElement> elements, final int vertexSize, final int stepRate) {
this.vertexSize = vertexSize;
@@ -29,7 +_,14 @@
@@ -29,6 +_,11 @@
}
this.elementValues = elements;
@@ -18,8 +18,14 @@
+ elementMapping.put(element.name(), element);
+ this.elementMapping = elementMapping.buildOrThrow();
}
public static VertexFormat.Builder builder(final int stepRate) {
@@ -69,6 +_,8 @@
public int hashCode() {
return this.elementValues.hashCode();
}
+
+ public com.google.common.collect.ImmutableMap<String, VertexFormatElement> getElementMapping() { return elementMapping; }
public static VertexFormat.Builder builder(final int stepRate) {
return new VertexFormat.Builder(stepRate);
@OnlyIn(Dist.CLIENT)
public static class Builder {
@@ -5,7 +5,7 @@
@Override
+ public boolean keyPressed(net.minecraft.client.input.KeyEvent event) {
+ if (event.isEscape()) {
+ if (event.key() == org.lwjgl.glfw.GLFW.GLFW_KEY_ESCAPE) {
+ minecraft.gui.setScreen(this.nextScreen);
+ return true;
+ }
@@ -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,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,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,6 +1,6 @@
--- a/net/minecraft/SharedConstants.java
+++ b/net/minecraft/SharedConstants.java
@@ -219,6 +_,7 @@
@@ -218,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 @@
@@ -220,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,6 +1,6 @@
--- a/net/minecraft/client/Camera.java
+++ b/net/minecraft/client/Camera.java
@@ -228,11 +_,13 @@
@@ -224,11 +_,13 @@
}
float fov = this.minecraft.options.fov().get().intValue() * Mth.lerp(partialTicks, this.oldFovModifier, this.fovModifier);
@@ -16,7 +16,7 @@
}
private float modifyFovBasedOnDeathOrFluid(final float partialTicks, float fov) {
@@ -341,9 +_,13 @@
@@ -337,9 +_,13 @@
}
protected void setRotation(final float yRot, final float xRot) {
@@ -31,7 +31,7 @@
FORWARDS.rotate(this.rotation, this.forwards);
UP.rotate(this.rotation, this.up);
LEFT.rotate(this.rotation, this.left);
@@ -374,6 +_,13 @@
@@ -370,6 +_,13 @@
public float yRot() {
return this.yRot;
@@ -70,7 +70,7 @@
return this.key.equals(that.key);
}
@@ -177,11 +_,13 @@
@@ -179,11 +_,13 @@
}
public Component getTranslatedKeyMessage() {
@@ -85,7 +85,7 @@
}
public String saveString() {
@@ -193,11 +_,94 @@
@@ -195,11 +_,94 @@
}
private void registerMapping(final InputConstants.Key key) {
@@ -1,15 +1,15 @@
--- a/net/minecraft/client/KeyboardHandler.java
+++ b/net/minecraft/client/KeyboardHandler.java
@@ -496,7 +_,7 @@
@@ -478,7 +_,7 @@
if (screen != null) {
try {
if (action != 1 && action != -1) {
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;
}
@@ -505,7 +_,7 @@
@@ -487,7 +_,7 @@
}
} else {
screen.afterKeyboardAction();
@@ -18,7 +18,7 @@
if (this.minecraft.gui.screen() == null) {
InputConstants.Key key = InputConstants.getKey(event);
KeyMapping.set(key, false);
@@ -578,6 +_,7 @@
@@ -562,6 +_,7 @@
}
}
}
@@ -26,7 +26,7 @@
}
}
@@ -586,7 +_,7 @@
@@ -570,7 +_,7 @@
Screen screen = this.minecraft.gui.screen();
if (screen != null && this.minecraft.gui.overlay() == null) {
try {
@@ -34,4 +34,4 @@
+ net.minecraftforge.client.ForgeHooksClient.onScreenCharTyped(screen, event);
} catch (Throwable t) {
CrashReport report = CrashReport.forThrowable(t, "charTyped event handler");
CrashReportCategory keyDetails = report.addCategory("Key");
screen.fillCrashDetails(report);
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/Minecraft.java
+++ b/net/minecraft/client/Minecraft.java
@@ -265,7 +_,7 @@
@@ -258,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;
@@ -410,7 +_,6 @@
}
}, Util.nonCriticalIoPool());
LOGGER.info("Setting user: {}", this.user.getName());
@@ -17,23 +17,30 @@
this.demo = gameConfig.game.demo;
this.allowsMultiplayer = !gameConfig.game.disableMultiplayer;
this.allowsChat = !gameConfig.game.disableChat;
@@ -568,6 +_,7 @@
@@ -547,12 +_,12 @@
LOGGER.error("Couldn't set icon", e);
}
+ // 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());
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 @@
this.languageManager = new LanguageManager(this.options.languageCode, var1 -> {
@@ -630,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.gameRenderer = new GameRenderer(this, this.entityRenderDispatcher.getItemInHandRenderer(), this.modelManager);
WindowRenderState windowRenderState = this.gameRenderer.gameRenderState().windowRenderState;
@@ -647,6 +_,7 @@
this.window.getHeight()
);
this.levelExtractor = new LevelExtractor(this, this.gameRenderer.gameRenderState().levelRenderState, this.levelRenderer);
@@ -41,15 +48,25 @@
this.resourceManager.registerReloadListener(this.levelExtractor);
this.resourceManager.registerReloadListener(this.levelRenderer.cloudRenderer());
this.gpuWarnlistManager = new GpuWarnlistManager();
@@ -694,6 +_,7 @@
MessageBox.error(message.toString());
@@ -654,6 +_,9 @@
this.resourceManager.registerReloadListener(this.regionalCompliancies);
this.gui = new Gui(this, new Hud(this), this.gameRenderer.gameRenderState().guiRenderState);
this.gui.registerReloadListeners(this.resourceManager);
+ // 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);
@@ -686,6 +_,7 @@
}
}
+ net.minecraftforge.client.ForgeHooksClient.initClientHooks(this, this.resourceManager);
this.window.updateRawMouseInput(this.options.rawMouseInput().get());
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 @@
this.window.setDefaultErrorCallback();
@@ -710,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);
@@ -67,7 +84,7 @@
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 @@
@@ -801,6 +_,7 @@
StringBuilder builder = new StringBuilder("Minecraft");
if (checkModStatus().shouldReportAsModified()) {
builder.append("*");
@@ -75,16 +92,16 @@
}
builder.append(" ");
@@ -835,6 +_,8 @@
@@ -824,6 +_,8 @@
}
private static UserApiService createUserApiService(final MinecraftServicesDiscoveryService discoveryService, final GameConfig config) {
private static 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 @@
@@ -840,7 +_,7 @@
}
private void rollbackResourcePacks(final Throwable t, final @Nullable GameLoadCookie loadCookie) {
@@ -93,33 +110,33 @@
this.clearResourcePacksOnError(t, null, loadCookie);
} else {
Util.throwAsRuntime(t);
@@ -1148,6 +_,7 @@
FreeTypeUtil.destroy();
@@ -1141,6 +_,7 @@
Util.shutdownExecutors();
this.windowSurface.close();
RenderSystem.shutdownRenderer();
+ net.minecraftforge.fml.config.ConfigTracker.forceUnload();
} catch (Throwable t) {
LOGGER.error("Shutdown failure!", t);
throw t;
@@ -1305,7 +_,9 @@
@@ -1301,7 +_,9 @@
profiler.popPush("gpuAsync");
RenderSystem.executePendingTasks();
profiler.pop();
+ net.minecraftforge.client.event.ForgeEventFactoryClient.onRenderTickStart(this.deltaTracker);
this.gameRenderer.render();
this.gameRenderer.render(this.deltaTracker, advanceGameTime);
+ net.minecraftforge.client.event.ForgeEventFactoryClient.onRenderTickEnd(this.deltaTracker);
}
profiler.push("swapchainBlit");
@@ -1432,6 +_,7 @@
profiler.push("present");
@@ -1425,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());
}
this.mouseHandler.resyncMousePosition();
@@ -1595,6 +_,7 @@
this.mouseHandler.setIgnoreFirstMove();
@@ -1576,6 +_,7 @@
}
public void stop() {
@@ -127,35 +144,38 @@
this.running = false;
}
@@ -1622,9 +_,16 @@
@@ -1599,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 @@
}
@@ -1656,6 +_,8 @@
return true;
}
+ 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))
switch (this.hitResult.getType()) {
case ENTITY:
AttackRange customItemRange = heldItem.get(DataComponents.ATTACK_RANGE);
@@ -1689,7 +_,7 @@
@@ -1666,7 +_,7 @@
case BLOCK:
BlockHitResult blockHit = (BlockHitResult)this.hitResult;
BlockPos pos = blockHit.getBlockPos();
@@ -164,53 +184,49 @@
this.gameMode.startDestroyBlock(pos, blockHit.getDirection());
if (this.level.getBlockState(pos).isAir()) {
endAttack = true;
@@ -1702,10 +_,13 @@
@@ -1679,8 +_,10 @@
}
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);
+ }
+ if (inputEvent.shouldSwingHand())
this.player.swing(InteractionHand.MAIN_HAND);
return endAttack;
}
}
@@ -1726,6 +_,13 @@
}
@@ -1696,6 +_,12 @@
}
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);
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;
@@ -1712,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 @@
@@ -1724,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);
@@ -1740,6 +_,9 @@
}
}
@@ -218,9 +234,9 @@
+ 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);
@@ -1768,6 +_,8 @@
}
ProfilerFiller profiler = Profiler.get();
@@ -229,7 +245,7 @@
profiler.push("gameMode");
if (!this.pause && this.level != null) {
this.gameMode.tick();
@@ -1845,6 +_,7 @@
@@ -1817,6 +_,7 @@
this.tutorial.tick();
@@ -237,7 +253,7 @@
try {
this.level.tick(() -> true);
} catch (Throwable t) {
@@ -1858,6 +_,7 @@
@@ -1830,6 +_,7 @@
throw new ReportedException(report);
}
@@ -245,7 +261,7 @@
}
profiler.popPush("animateTick");
@@ -1882,6 +_,7 @@
@@ -1854,6 +_,7 @@
profiler.popPush("keyboard");
this.keyboardHandler.tick();
profiler.pop();
@@ -253,7 +269,7 @@
}
private boolean isLevelRunningNormally() {
@@ -2088,6 +_,7 @@
@@ -2059,6 +_,7 @@
}
public void setLevel(final ClientLevel level) {
@@ -261,7 +277,7 @@
this.level = level;
this.updateLevelInEngines(level);
}
@@ -2149,6 +_,7 @@
@@ -2120,6 +_,7 @@
IntegratedServer server = this.singleplayerServer;
this.singleplayerServer = null;
this.gameRenderer.resetData();
@@ -269,7 +285,7 @@
this.gameMode = null;
this.narrator.clear();
this.gui.setClientLevelTeardownInProgress(true);
@@ -2156,6 +_,7 @@
@@ -2127,6 +_,7 @@
try {
if (this.level != null) {
this.gui.hud.onDisconnected();
@@ -277,7 +293,7 @@
}
this.level = null;
@@ -2171,6 +_,7 @@
@@ -2141,6 +_,7 @@
}
profiler.pop();
@@ -285,7 +301,7 @@
}
this.setScreenAndShow(screen);
@@ -2403,6 +_,7 @@
@@ -2354,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 @@
@@ -77,6 +_,7 @@
this.activeButton = null;
}
+ if (net.minecraftforge.client.event.ForgeEventFactoryClient.onMouseButtonPre(rawButtonInfo, action)) return;
+ if (net.minecraftforge.client.event.ForgeEventFactoryClient.onMouseButtonPre(buttonInfo, action)) return;
if (this.minecraft.gui.overlay() == null) {
if (pressed
&& this.minecraft
@@ -104,7 +_,7 @@
&& this.minecraft.handleGlobalKeyPress(InputConstants.Type.MOUSE.getOrCreate(buttonInfo.button()), buttonInfo.hasControlDownWithQuirk())) {
@@ -101,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 @@
@@ -116,7 +_,7 @@
}
} else {
try {
@@ -26,15 +26,15 @@
return;
}
} catch (Throwable t) {
@@ -147,6 +_,7 @@
@@ -146,6 +_,7 @@
KeyMapping.click(mouseKey);
}
}
+ net.minecraftforge.client.event.ForgeEventFactoryClient.onMouseButtonPost(rawButtonInfo, action);
+ net.minecraftforge.client.event.ForgeEventFactoryClient.onMouseButtonPost(buttonInfo, action);
}
}
@@ -182,7 +_,9 @@
@@ -197,7 +_,9 @@
if (this.minecraft.gui.screen() != null) {
double xm = this.getScaledXPos(this.minecraft.getWindow());
double ym = this.getScaledYPos(this.minecraft.getWindow());
@@ -45,7 +45,7 @@
this.minecraft.gui.screen().afterMouseAction();
} else if (this.minecraft.player != null) {
Vector2i wheelXY = this.scrollWheelHandler.onMouseScroll(scaledXOffset, scaledYOffset);
@@ -191,6 +_,7 @@
@@ -206,6 +_,7 @@
}
int wheel = wheelXY.y == 0 ? -wheelXY.x : wheelXY.y;
@@ -53,7 +53,7 @@
if (this.minecraft.player.isSpectator()) {
if (this.minecraft.gui.hud.getSpectatorGui().isMenuActive()) {
this.minecraft.gui.hud.getSpectatorGui().onMouseScrolled(-wheel);
@@ -285,7 +_,7 @@
@@ -312,7 +_,7 @@
double dy = getScaledYPos(window, this.accumulatedDY);
try {
@@ -61,8 +61,8 @@
+ 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 @@
screen.fillCrashDetails(report);
@@ -397,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 @@
@@ -986,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 @@
@@ -1474,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 @@
@@ -1624,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 @@
@@ -1647,6 +_,10 @@
}
public void load() {
@@ -62,7 +57,7 @@
try {
if (!this.optionsFile.exists()) {
return;
@@ -1710,7 +_,8 @@
@@ -1666,7 +_,8 @@
}
final CompoundTag options = this.dataFix(rawOptions);
@@ -72,7 +67,7 @@
new Options.FieldAccess() {
private @Nullable String getValue(final String name) {
Tag tag = options.get(name);
@@ -1792,6 +_,17 @@
@@ -1748,6 +_,17 @@
);
options.getString("fullscreenResolution").ifPresent(fullscreenResolution -> this.fullscreenVideoModeString = fullscreenResolution);
KeyMapping.resetMapping();
@@ -90,7 +85,7 @@
} catch (Exception e) {
LOGGER.error("Failed to load options", e);
}
@@ -1821,9 +_,11 @@
@@ -1778,9 +_,11 @@
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());
@@ -102,7 +97,7 @@
writer.print(name);
writer.print(':');
}
@@ -1879,6 +_,12 @@
@@ -1836,6 +_,12 @@
if (fullscreenVideoModeString != null) {
writer.println("fullscreenResolution:" + fullscreenVideoModeString);
}
@@ -115,7 +110,7 @@
} catch (Exception e) {
LOGGER.error("Failed to save options", e);
}
@@ -1916,6 +_,7 @@
@@ -1873,6 +_,7 @@
}
public void broadcastOptions() {
@@ -123,7 +118,7 @@
if (this.minecraft.player != null) {
this.minecraft.player.connection.broadcastClientInformation(this.buildPlayerInformation());
}
@@ -2029,6 +_,23 @@
@@ -1986,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/data/models/ItemModelGenerators.java
+++ b/net/minecraft/client/data/models/ItemModelGenerators.java
@@ -921,6 +_,9 @@
@@ -868,6 +_,9 @@
this.declareCustomModelItem(Items.COD);
this.declareCustomModelItem(Items.FEATHER);
this.declareCustomModelItem(Items.LEAD);
@@ -1,15 +1,15 @@
--- a/net/minecraft/client/gui/Gui.java
+++ b/net/minecraft/client/gui/Gui.java
@@ -67,7 +_,7 @@
@@ -64,7 +_,7 @@
import org.slf4j.Logger;
@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 @@
public static final Component SAVING_LEVEL = Component.translatable("menu.savingLevel");
@@ -80,6 +_,7 @@
private @Nullable TutorialToast socialInteractionsToast;
public Gui(final Minecraft minecraft, final Hud hud, final GuiRenderState guiRenderState) {
@@ -17,7 +17,7 @@
this.minecraft = minecraft;
this.hud = hud;
this.splashManager = new SplashManager(minecraft.getUser());
@@ -174,7 +_,7 @@
@@ -175,7 +_,7 @@
profiler.push("screen");
try {
@@ -26,13 +26,11 @@
} catch (Throwable t) {
CrashReport report = CrashReport.forThrowable(t, "Rendering screen");
CrashReportCategory category = report.addCategory("Screen render details");
@@ -228,14 +_,6 @@
this.screenTracySection = null;
@@ -224,12 +_,6 @@
LOGGER.error("setScreen called from non-game thread");
}
- if (this.screen != null) {
- this.screen.clearFocus();
- this.minecraft.textInputManager().stopTextInput();
- this.screen.removed();
- } else {
- this.minecraft.setLastInputType(InputType.NONE);
@@ -41,7 +39,7 @@
if (screen == null) {
if (this.clientLevelTeardownInProgress) {
throw new IllegalStateException("Trying to return to in-game GUI during disconnection");
@@ -254,6 +_,24 @@
@@ -248,6 +_,22 @@
}
}
@@ -56,8 +54,6 @@
+ 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);
@@ -66,7 +62,7 @@
this.screen = screen;
if (this.screen != null) {
this.screen.added();
@@ -474,5 +_,10 @@
@@ -465,5 +_,10 @@
}
)
);
@@ -9,7 +9,7 @@
private static final int EXTRA_SPACE_AFTER_FIRST_TOOLTIP_LINE = 2;
private final Minecraft minecraft;
private final Matrix3x2fStack pose;
@@ -914,6 +_,7 @@
@@ -912,6 +_,7 @@
CrashReport report = CrashReport.forThrowable(t, "Rendering item");
CrashReportCategory category = report.addCategory("Item being rendered");
category.setDetail("Item Type", () -> String.valueOf(itemStack.getItem()));
@@ -17,7 +17,7 @@
category.setDetail("Item Components", () -> String.valueOf(itemStack.getComponents()));
category.setDetail("Item Foil", () -> String.valueOf(itemStack.hasFoil()));
throw new ReportedException(report);
@@ -940,6 +_,7 @@
@@ -938,6 +_,7 @@
this.itemCooldown(itemStack, x, y);
this.itemCount(font, itemStack, x, y, countText);
this.pose.popMatrix();
@@ -25,7 +25,7 @@
}
}
@@ -1109,16 +_,29 @@
@@ -1106,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
@@ -1124,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 @@
@@ -1156,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 @@
@@ -1207,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,
@@ -1218,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,7 +125,7 @@
if (lineWidth > textWidth) {
textWidth = lineWidth;
}
@@ -1263,25 +_,25 @@
@@ -1234,25 +_,25 @@
int w = textWidth;
int h = tempHeight;
@@ -143,9 +141,9 @@
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 @@
@@ -1326,6 +_,14 @@
private ActiveTextCollector.Parameters createDefaultTextParameters(final float opacity) {
return new ActiveTextCollector.Parameters(new Matrix3x2f(this.pose), opacity, this.scissorStack.peek());
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/gui/Hud.java
+++ b/net/minecraft/client/gui/Hud.java
@@ -157,7 +_,7 @@
@@ -156,7 +_,7 @@
public float vignetteBrightness = 1.0F;
private int toolHighlightTimer;
private ItemStack lastToolHighlight = ItemStack.EMPTY;
@@ -9,7 +9,7 @@
private final SubtitleOverlay subtitleOverlay;
private final SpectatorGui spectatorGui;
private final PlayerTabOverlay tabList;
@@ -199,6 +_,7 @@
@@ -198,6 +_,7 @@
() -> new JumpableVehicleBar(minecraft)
);
this.resetTitleTimes();
@@ -17,7 +17,7 @@
}
public void registerReloadListeners(final ReloadableResourceManager resourceManager) {
@@ -222,6 +_,10 @@
@@ -221,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)) {
@@ -28,7 +28,7 @@
if (!this.isHidden) {
this.extractCameraOverlays(graphics, deltaTracker);
this.extractCrosshair(graphics, deltaTracker);
@@ -405,7 +_,7 @@
@@ -404,7 +_,7 @@
int mouseX = Mth.floor(this.minecraft.mouseHandler.getScaledXPos(window));
int mouseY = Mth.floor(this.minecraft.mouseHandler.getScaledYPos(window));
graphics.nextStratum();
@@ -37,7 +37,7 @@
}
}
@@ -500,6 +_,8 @@
@@ -497,6 +_,8 @@
for (MobEffectInstance instance : Ordering.natural().reverse().sortedCopy(activeEffects)) {
Holder<MobEffect> effect = instance.getEffect();
@@ -46,7 +46,7 @@
if (instance.showIcon()) {
int x = graphics.guiWidth();
int y = 1;
@@ -530,6 +_,7 @@
@@ -527,6 +_,7 @@
}
}
@@ -54,7 +54,7 @@
graphics.blitSprite(RenderPipelines.GUI_TEXTURED, getMobEffectSprite(effect), x + 3, y + 3, 18, 18, ARGB.white(alpha));
}
}
@@ -632,15 +_,37 @@
@@ -629,15 +_,37 @@
}
public void extractSelectedItemName(final GuiGraphicsExtractor graphics) {
@@ -94,7 +94,7 @@
if (!this.minecraft.gameMode.canHurtPlayer()) {
y += 14;
}
@@ -651,7 +_,7 @@
@@ -648,7 +_,7 @@
}
if (alpha > 0) {
@@ -103,7 +103,7 @@
}
}
}
@@ -1219,7 +_,9 @@
@@ -1216,7 +_,9 @@
this.toolHighlightTimer = 0;
} else if (this.lastToolHighlight.isEmpty()
|| !selected.is(this.lastToolHighlight.getItem())
@@ -1,8 +1,8 @@
--- 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)));
@@ -165,6 +_,7 @@
Button.builder(OPTIONS, var1x -> this.minecraft.gui.setScreen(new OptionsScreen(this, this.minecraft.options, true))).width(204).build(), 2
);
}
+ 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);
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/gui/screens/Screen.java
+++ b/net/minecraft/client/gui/screens/Screen.java
@@ -202,7 +_,7 @@
@@ -196,7 +_,7 @@
}
public void onClose() {
@@ -9,7 +9,7 @@
}
protected <T extends GuiEventListener & Renderable & NarratableEntry> T addRenderableWidget(final T widget) {
@@ -333,8 +_,10 @@
@@ -327,8 +_,10 @@
this.width = width;
this.height = height;
if (!this.initialized) {
@@ -20,7 +20,7 @@
} else {
this.repositionElements();
}
@@ -351,8 +_,10 @@
@@ -345,8 +_,10 @@
protected void rebuildWidgets() {
this.clearWidgets();
this.clearFocus();
@@ -31,7 +31,7 @@
}
protected void fadeWidgets(final float widgetFade) {
@@ -392,6 +_,8 @@
@@ -386,6 +_,8 @@
this.extractMenuBackground(graphics);
}
@@ -40,7 +40,7 @@
this.minecraft.gui.hud.extractDeferredSubtitles();
}
@@ -472,6 +_,19 @@
@@ -471,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/advancements/AdvancementTab.java
+++ b/net/minecraft/client/gui/screens/advancements/AdvancementTab.java
@@ -38,6 +_,7 @@
@@ -41,6 +_,7 @@
private float fade;
private boolean centered;
private @Nullable AdvancementWidget hovered;
@@ -8,22 +8,15 @@
public AdvancementTab(
final Minecraft minecraft,
@@ -60,6 +_,11 @@
this.addWidget(root);
@@ -62,6 +_,15 @@
this.addWidget(this.root, rootNode.holder());
}
+ public AdvancementTab(Minecraft mc, AdvancementsScreen screen, AdvancementTabType type, int index, int page, AdvancementWidget root, ItemStackTemplate icon, Component title, Identifier background) {
+ this(mc, screen, type, index, root, icon, title, background);
+ public AdvancementTab(Minecraft mc, AdvancementsScreen screen, AdvancementTabType type, int index, int page, AdvancementNode adv, DisplayInfo info) {
+ this(mc, screen, type, index, adv, info);
+ this.page = page;
+ }
+
public void copyPosition(final AdvancementTab source) {
this.scrollX = source.scrollX;
this.scrollY = source.scrollY;
@@ -70,6 +_,10 @@
this.centered = source.centered;
}
+ public int getPage() {
+ return this.page;
+ }
@@ -31,14 +24,14 @@
public AdvancementTabType getType() {
return this.type;
}
@@ -179,8 +_,8 @@
Identifier background = rootDisplay.background().get().texturePath();
@@ -169,8 +_,8 @@
}
for (AdvancementTabType type : AdvancementTabType.values()) {
- if (index < type.getMax()) {
- return new AdvancementTab(minecraft, screen, type, index, rootWidget, rootDisplay.icon(), rootDisplay.title(), background);
- return new AdvancementTab(minecraft, screen, type, index, root, display.get());
+ if ((index % AdvancementTabType.MAX_TABS) < type.getMax()) {
+ return new AdvancementTab(minecraft, screen, type, index % AdvancementTabType.MAX_TABS, index / AdvancementTabType.MAX_TABS, rootWidget, rootDisplay.icon(), rootDisplay.title(), background);
+ return new AdvancementTab(minecraft, screen, type, index % AdvancementTabType.MAX_TABS, index / AdvancementTabType.MAX_TABS, root, display.get());
}
index -= type.getMax();
@@ -34,10 +34,10 @@
for (AdvancementTab tab : this.tabs.values()) {
- if (tab.isMouseOver(xo, yo, event.x(), event.y())) {
+ if (tab.getPage() == tabPage && tab.isMouseOver(xo, yo, event.x(), event.y())) {
this.advancements.setSelectedTab(tab.getRootAdvancement(), true);
this.advancements.setSelectedTab(tab.getRootNode().holder(), true);
break;
}
@@ -212,10 +_,12 @@
@@ -208,10 +_,12 @@
graphics.blit(RenderPipelines.GUI_TEXTURED, WINDOW_LOCATION, this.leftPos, this.topPos, 0.0F, 0.0F, 252, 140, 256, 256);
if (this.tabs.size() > 1) {
for (AdvancementTab tab : this.tabs.values()) {
@@ -50,7 +50,7 @@
tab.extractIcon(graphics, this.leftPos, this.topPos);
}
}
@@ -234,6 +_,7 @@
@@ -230,6 +_,7 @@
if (this.tabs.size() > 1) {
for (AdvancementTab tab : this.tabs.values()) {
@@ -20,8 +20,8 @@
ItemStack item = this.hoveredSlot.getItem();
if (this.menu.getCarried().isEmpty() || this.showTooltipWithItemInHand(item)) {
graphics.setTooltipForNextFrame(
- this.font, this.getTooltipFromContainerItem(item), item.getTooltipImage(), mouseX, mouseY, item.get(DataComponents.TOOLTIP_STYLE), true
+ this.font, this.getTooltipFromContainerItem(item), item.getTooltipImage(), item, mouseX, mouseY, true
- this.font, this.getTooltipFromContainerItem(item), item.getTooltipImage(), mouseX, mouseY, item.get(DataComponents.TOOLTIP_STYLE)
+ this.font, this.getTooltipFromContainerItem(item), item.getTooltipImage(), item, mouseX, mouseY
);
}
}
@@ -35,7 +35,7 @@
}
protected void extractLabels(final GuiGraphicsExtractor graphics, final int xm, final int ym) {
@@ -297,7 +_,8 @@
@@ -285,7 +_,8 @@
return true;
}
@@ -45,7 +45,7 @@
Slot slot = this.getHoveredSlot(event.x(), event.y());
this.doubleclick = this.lastClickSlot == slot && doubleClick;
this.skipNextRelease = false;
@@ -307,6 +_,7 @@
@@ -295,6 +_,7 @@
int xo = this.leftPos;
int yo = this.topPos;
boolean clickedOutside = this.hasClickedOutside(event.x(), event.y(), xo, yo);
@@ -53,25 +53,25 @@
int slotId = -1;
if (slot != null) {
slotId = slot.index;
@@ -318,7 +_,7 @@
@@ -306,7 +_,7 @@
if (slotId != -1 && !this.isQuickCrafting) {
if (this.menu.getCarried().isEmpty()) {
- if (cloning) {
+ if (this.minecraft.options.keyPickItem.isActiveAndMatches(mouseKey)) {
this.slotClicked(slot, slotId, event, ContainerInput.CLONE);
this.slotClicked(slot, slotId, event.button(), ContainerInput.CLONE);
} else {
boolean quickKey = slotId != -999 && event.hasShiftDown();
@@ -342,7 +_,7 @@
@@ -330,7 +_,7 @@
this.quickCraftingType = 0;
} else if (event.button() == 3) {
} else if (event.button() == 1) {
this.quickCraftingType = 1;
- } else if (cloning) {
+ } else if (this.minecraft.options.keyPickItem.isActiveAndMatches(mouseKey)) {
this.quickCraftingType = 2;
}
}
@@ -386,10 +_,13 @@
@@ -374,10 +_,13 @@
@Override
public boolean mouseReleased(final MouseButtonEvent event) {
@@ -85,25 +85,25 @@
int slotId = -1;
if (slot != null) {
slotId = slot.index;
@@ -406,7 +_,7 @@
@@ -394,7 +_,7 @@
if (target != null
&& target.mayPickup(this.minecraft.player)
&& target.hasItem()
- && target.container == slot.container
+ && target.isSameInventory(slot)
&& AbstractContainerMenu.canItemQuickReplace(target, this.lastQuickMoved, true)) {
this.slotClicked(target, target.index, event, ContainerInput.QUICK_MOVE);
this.slotClicked(target, target.index, event.button(), ContainerInput.QUICK_MOVE);
}
@@ -433,7 +_,7 @@
@@ -421,7 +_,7 @@
if (this.isQuickCrafting && !this.quickCraftSlots.isEmpty()) {
this.quickCraftToSlots();
} else if (!this.menu.getCarried().isEmpty()) {
- if (this.minecraft.options.keyPickItem.matchesMouse(event)) {
+ if (this.minecraft.options.keyPickItem.isActiveAndMatches(mouseKey)) {
this.slotClicked(slot, slotId, event, ContainerInput.CLONE);
this.slotClicked(slot, slotId, event.button(), ContainerInput.CLONE);
} else {
boolean quickKey = slotId != -999 && event.hasShiftDown();
@@ -501,7 +_,7 @@
@@ -489,7 +_,7 @@
return true;
}
@@ -112,7 +112,7 @@
this.onClose();
return true;
}
@@ -599,4 +_,11 @@
@@ -587,4 +_,11 @@
super.onClose();
}
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java
+++ b/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java
@@ -117,6 +_,8 @@
@@ -116,6 +_,8 @@
private final Set<TagKey<Item>> visibleTags = new HashSet<>();
private final boolean displayOperatorCreativeTab;
private final EffectsInInventory effects;
@@ -9,7 +9,7 @@
public CreativeModeInventoryScreen(final LocalPlayer player, final FeatureFlagSet enabledFeatures, final boolean displayOperatorCreativeTab) {
super(new CreativeModeInventoryScreen.ItemPickerMenu(player), player.getInventory(), CommonComponents.EMPTY, 195, 136);
@@ -165,7 +_,7 @@
@@ -164,7 +_,7 @@
private void refreshCurrentTabContents(final Collection<ItemStack> displayList) {
int oldRowIndex = this.menu.getRowIndexForScroll(this.scrollOffs);
this.menu.items.clear();
@@ -18,7 +18,7 @@
this.refreshSearchResults();
} else {
this.menu.items.addAll(displayList);
@@ -331,6 +_,36 @@
@@ -330,6 +_,36 @@
protected void init() {
if (this.minecraft.player.hasInfiniteMaterials()) {
super.init();
@@ -55,7 +55,7 @@
this.searchBox = new EditBox(this.font, this.leftPos + 82, this.topPos + 6, 80, 9, Component.translatable("itemGroup.search"));
this.searchBox.setMaxLength(50);
this.searchBox.setBordered(false);
@@ -380,7 +_,7 @@
@@ -379,7 +_,7 @@
return false;
}
@@ -64,7 +64,7 @@
return false;
}
@@ -408,7 +_,7 @@
@@ -407,7 +_,7 @@
@Override
public boolean keyPressed(final KeyEvent event) {
this.ignoreTextInput = false;
@@ -73,7 +73,7 @@
if (this.minecraft.options.keyChat.matches(event)) {
this.ignoreTextInput = true;
this.selectTab(CreativeModeTabs.searchTab());
@@ -449,6 +_,7 @@
@@ -443,6 +_,7 @@
}
private void refreshSearchResults() {
@@ -81,7 +81,7 @@
this.menu.items.clear();
this.visibleTags.clear();
String searchTerm = this.searchBox.getValue();
@@ -461,10 +_,10 @@
@@ -455,10 +_,10 @@
SearchTree<ItemStack> tree;
if (searchTerm.startsWith("#")) {
searchTerm = searchTerm.substring(1);
@@ -94,7 +94,7 @@
}
this.menu.items.addAll(tree.search(searchTerm.toLowerCase(Locale.ROOT)));
@@ -492,7 +_,7 @@
@@ -486,7 +_,7 @@
@Override
protected void extractLabels(final GuiGraphicsExtractor graphics, final int xm, final int ym) {
if (selectedTab.showTitle()) {
@@ -103,7 +103,7 @@
}
}
@@ -502,7 +_,7 @@
@@ -496,7 +_,7 @@
double xm = event.x() - this.leftPos;
double ym = event.y() - this.topPos;
@@ -112,7 +112,7 @@
if (this.checkTabClicked(tab, xm, ym)) {
return true;
}
@@ -524,7 +_,7 @@
@@ -518,7 +_,7 @@
double ym = event.y() - this.topPos;
this.scrolling = false;
@@ -121,7 +121,7 @@
if (this.checkTabClicked(tab, xm, ym)) {
this.selectTab(tab);
return true;
@@ -617,13 +_,15 @@
@@ -611,13 +_,15 @@
this.originalSlots = null;
}
@@ -138,7 +138,7 @@
this.refreshSearchResults();
} else {
@@ -688,7 +_,14 @@
@@ -682,7 +_,14 @@
this.effects.extractRenderState(graphics, mouseX, mouseY);
super.extractRenderState(graphics, mouseX, mouseY, a);
@@ -154,7 +154,7 @@
if (this.checkTabHovering(graphics, tab, mouseX, mouseY)) {
break;
}
@@ -710,7 +_,7 @@
@@ -704,7 +_,7 @@
public List<Component> getTooltipFromContainerItem(final ItemStack itemStack) {
boolean isCreativeSlot = this.hoveredSlot != null && this.hoveredSlot instanceof CreativeModeInventoryScreen.CustomCreativeSlot;
boolean isSingleCategoryTab = selectedTab.getType() == CreativeModeTab.Type.CATEGORY;
@@ -163,7 +163,7 @@
TooltipFlag.Default originalTooltipStyle = this.minecraft.options.advancedItemTooltips ? TooltipFlag.Default.ADVANCED : TooltipFlag.Default.NORMAL;
TooltipFlag tooltipStyle = isCreativeSlot ? originalTooltipStyle.asCreative() : originalTooltipStyle;
List<Component> originalLines = itemStack.getTooltipLines(Item.TooltipContext.of(this.minecraft.level), this.minecraft.player, tooltipStyle);
@@ -734,7 +_,7 @@
@@ -728,7 +_,7 @@
int i = 1;
for (CreativeModeTab tab : CreativeModeTabs.tabs()) {
@@ -172,7 +172,7 @@
linesToDisplay.add(i++, tab.getDisplayName().copy().withStyle(ChatFormatting.BLUE));
}
}
@@ -746,7 +_,7 @@
@@ -740,7 +_,7 @@
public void extractBackground(final GuiGraphicsExtractor graphics, final int mouseX, final int mouseY, final float a) {
super.extractBackground(graphics, mouseX, mouseY, a);
@@ -181,7 +181,7 @@
if (tab != selectedTab) {
this.extractTabButton(graphics, mouseX, mouseY, tab);
}
@@ -781,6 +_,7 @@
@@ -775,6 +_,7 @@
graphics.blitSprite(RenderPipelines.GUI_TEXTURED, sprite, xscr, yscr + (int)((yscr2 - yscr - 17) * this.scrollOffs), 12, 15);
}
@@ -189,7 +189,7 @@
this.extractTabButton(graphics, mouseX, mouseY, selectedTab);
if (selectedTab.getType() == CreativeModeTab.Type.INVENTORY) {
InventoryScreen.extractEntityInInventoryFollowsMouse(
@@ -790,7 +_,7 @@
@@ -784,7 +_,7 @@
}
private int getTabX(final CreativeModeTab tab) {
@@ -198,7 +198,7 @@
int spacing = 27;
int x = 27 * pos;
if (tab.isAlignedRight()) {
@@ -802,7 +_,7 @@
@@ -796,7 +_,7 @@
private int getTabY(final CreativeModeTab tab) {
int y = 0;
@@ -207,7 +207,7 @@
y -= 32;
} else {
y += this.imageHeight;
@@ -830,8 +_,8 @@
@@ -824,8 +_,8 @@
protected void extractTabButton(final GuiGraphicsExtractor graphics, final int mouseX, final int mouseY, final CreativeModeTab tab) {
boolean selected = tab == selectedTab;
@@ -218,7 +218,7 @@
int x = this.leftPos + this.getTabX(tab);
int y = this.topPos - (isTop ? 28 : -(this.imageHeight - 4));
Identifier[] sprites;
@@ -881,6 +_,14 @@
@@ -875,6 +_,14 @@
}
}
@@ -233,7 +233,7 @@
@OnlyIn(Dist.CLIENT)
private static class CustomCreativeSlot extends Slot {
public CustomCreativeSlot(final Container container, final int slot, final int x, final int y) {
@@ -1061,6 +_,22 @@
@@ -1055,6 +_,22 @@
@Override
public boolean mayPickup(final Player player) {
return this.target.mayPickup(player);
@@ -1,11 +1,11 @@
--- a/net/minecraft/client/gui/screens/inventory/HangingSignEditScreen.java
+++ b/net/minecraft/client/gui/screens/inventory/HangingSignEditScreen.java
@@ -17,7 +_,7 @@
@@ -16,7 +_,7 @@
private static final Vector3fc TEXT_SCALE = new Vector3f(1.0F, 1.0F, 1.0F);
private static final int TEXTURE_WIDTH = 16;
private static final int TEXTURE_HEIGHT = 16;
- private final Identifier texture = Identifier.withDefaultNamespace("textures/gui/hanging_signs/" + this.woodType.name() + ".png");
+ private final Identifier texture = Identifier.parse(this.woodType.name() + ".png").withPrefix("textures/gui/hanging_signs/");
public HangingSignEditScreen(final SignBlockEntity sign, final SignTextSlot slot, final boolean shouldFilter) {
super(sign, slot, shouldFilter, Component.translatable("hanging_sign.edit"));
public HangingSignEditScreen(final SignBlockEntity sign, final boolean isFrontText, final boolean shouldFilter) {
super(sign, isFrontText, shouldFilter, Component.translatable("hanging_sign.edit"));
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/gui/screens/options/controls/KeyBindsList.java
+++ b/net/minecraft/client/gui/screens/options/controls/KeyBindsList.java
@@ -118,9 +_,10 @@
@@ -116,9 +_,10 @@
this.name = name;
this.changeButton = Button.builder(name, button -> {
KeyBindsList.this.keyBindsScreen.selectedKey = key;
@@ -12,7 +12,7 @@
.createNarration(
defaultNarrationSupplier -> key.isUnbound()
? Component.translatable("narrator.controls.unbound", name)
@@ -128,7 +_,7 @@
@@ -126,7 +_,7 @@
)
.build();
this.resetButton = Button.builder(RESET_BUTTON_TITLE, button -> {
@@ -21,7 +21,7 @@
KeyBindsList.this.resetMappingAndUpdateButtons();
}).bounds(0, 0, 50, 20).createNarration(defaultNarrationSupplier -> Component.translatable("narrator.controls.reset", name)).build();
this.refreshEntry();
@@ -169,7 +_,8 @@
@@ -167,7 +_,8 @@
MutableComponent tooltip = Component.empty();
if (!this.key.isUnbound()) {
for (KeyMapping otherKey : KeyBindsList.this.minecraft.options.keyMappings) {
@@ -9,7 +9,7 @@
}
this.keyBindsList.resetMappingAndUpdateButtons();
@@ -78,11 +_,12 @@
@@ -74,11 +_,12 @@
public boolean keyPressed(final KeyEvent event) {
if (this.selectedKey != null) {
if (event.isEscape()) {
@@ -24,7 +24,7 @@
this.selectedKey = null;
this.lastKeySelection = Util.getMillis();
this.keyBindsList.resetMappingAndUpdateButtons();
@@ -105,5 +_,18 @@
@@ -101,5 +_,18 @@
}
this.resetButton.active = canReset;
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/gui/screens/worldselection/WorldOpenFlows.java
+++ b/net/minecraft/client/gui/screens/worldselection/WorldOpenFlows.java
@@ -504,6 +_,8 @@
@@ -495,6 +_,8 @@
this.minecraft.setScreenAndShow(new GenericMessageScreen(Component.translatable("selectWorld.resource_load")));
PackRepository packRepository = ServerPacksSource.createPackRepository(worldAccess);
@@ -9,7 +9,7 @@
WorldStem worldStem;
try {
worldStem = this.loadWorldStem(worldAccess, levelDataTag, safeMode, packRepository);
@@ -546,6 +_,8 @@
@@ -537,6 +_,8 @@
WorldData data = worldDataAndGenSettings.data();
boolean oldCustomized = worldDataAndGenSettings.genSettings().options().isOldCustomizedWorld();
boolean unstable = data.worldGenSettingsLifecycle() != Lifecycle.stable();
@@ -18,7 +18,7 @@
if (!oldCustomized && !unstable) {
this.openWorldLoadBundledResourcePack(worldAccess, worldStem, packRepository, onCancel);
} else {
@@ -562,6 +_,8 @@
@@ -553,6 +_,8 @@
private void openWorldLoadBundledResourcePack(
final LevelStorageSource.LevelStorageAccess worldAccess, final WorldStem worldStem, final PackRepository packRepository, final Runnable onCancel
) {
@@ -1,24 +1,24 @@
--- a/net/minecraft/client/model/HumanoidModel.java
+++ b/net/minecraft/client/model/HumanoidModel.java
@@ -380,6 +_,8 @@
@@ -391,6 +_,8 @@
break;
case SPEAR:
SpearAnimations.thirdPersonHandUse(this.rightArm, this.head, HumanoidArm.RIGHT, state.getUseItemStackForArm(HumanoidArm.RIGHT), state);
SpearAnimations.thirdPersonHandUse(this.rightArm, this.head, true, state.getUseItemStackForArm(HumanoidArm.RIGHT), state);
+ default:
+ state.rightArmPose.applyTransform(this, state, HumanoidArm.RIGHT);
+ state.rightArmPose.applyTransform(this, state, net.minecraft.world.entity.HumanoidArm.RIGHT);
}
}
@@ -425,6 +_,8 @@
@@ -436,6 +_,8 @@
break;
case SPEAR:
SpearAnimations.thirdPersonHandUse(this.leftArm, this.head, HumanoidArm.LEFT, state.getUseItemStackForArm(HumanoidArm.LEFT), state);
SpearAnimations.thirdPersonHandUse(this.leftArm, this.head, false, state.getUseItemStackForArm(HumanoidArm.LEFT), state);
+ default:
+ state.leftArmPose.applyTransform(this, state, HumanoidArm.LEFT);
+ state.leftArmPose.applyTransform(this, state, net.minecraft.world.entity.HumanoidArm.LEFT);
}
}
@@ -487,7 +_,7 @@
@@ -497,7 +_,7 @@
}
@OnlyIn(Dist.CLIENT)
@@ -27,7 +27,7 @@
EMPTY(false, false),
ITEM(false, false),
BLOCK(false, false),
@@ -513,10 +_,29 @@
@@ -523,10 +_,29 @@
ArmPose(final boolean twoHanded, final boolean affectsOffhandPose) {
this.twoHanded = twoHanded;
this.affectsOffhandPose = affectsOffhandPose;
@@ -1,9 +1,9 @@
--- a/net/minecraft/client/model/geom/LayerDefinitions.java
+++ b/net/minecraft/client/model/geom/LayerDefinitions.java
@@ -561,6 +_,7 @@
@@ -557,6 +_,7 @@
result.put(ModelLayers.PALE_OAK_CHEST_BOAT, chestBoatModel);
result.put(ModelLayers.MANGROVE_BOAT, boatModel);
result.put(ModelLayers.MANGROVE_CHEST_BOAT, chestBoatModel);
result.put(ModelLayers.POPLAR_BOAT, boatModel);
result.put(ModelLayers.POPLAR_CHEST_BOAT, chestBoatModel);
+ net.minecraftforge.client.ForgeHooksClient.loadLayerDefinitions(result);
ImmutableMap<ModelLayerLocation, LayerDefinition> definitions = result.build();
List<ModelLayerLocation> missingDefinitions = ModelLayers.getKnownLocations().filter(l -> !definitions.containsKey(l)).toList();
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/multiplayer/ClientChunkCache.java
+++ b/net/minecraft/client/multiplayer/ClientChunkCache.java
@@ -61,6 +_,7 @@
@@ -64,6 +_,7 @@
int index = this.storage.getIndex(pos.x(), pos.z());
LevelChunk currentChunk = this.storage.getChunk(index);
if (isValidChunk(currentChunk, pos.x(), pos.z())) {
@@ -8,7 +8,7 @@
this.storage.drop(index, currentChunk);
}
}
@@ -115,6 +_,7 @@
@@ -124,6 +_,7 @@
}
this.level.onChunkLoaded(pos);
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/multiplayer/ClientCommonPacketListenerImpl.java
+++ b/net/minecraft/client/multiplayer/ClientCommonPacketListenerImpl.java
@@ -158,6 +_,7 @@
@@ -157,6 +_,7 @@
@Override
public void handleCustomPayload(final ClientboundCustomPayloadPacket packet) {
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/multiplayer/ClientLevel.java
+++ b/net/minecraft/client/multiplayer/ClientLevel.java
@@ -168,6 +_,7 @@
@@ -165,6 +_,7 @@
cache.put(BiomeColors.FOLIAGE_COLOR_RESOLVER, new BlockTintCache(pos -> this.calculateBlockTint(pos, BiomeColors.FOLIAGE_COLOR_RESOLVER)));
cache.put(BiomeColors.DRY_FOLIAGE_COLOR_RESOLVER, new BlockTintCache(pos -> this.calculateBlockTint(pos, BiomeColors.DRY_FOLIAGE_COLOR_RESOLVER)));
cache.put(BiomeColors.WATER_COLOR_RESOLVER, new BlockTintCache(pos -> this.calculateBlockTint(pos, BiomeColors.WATER_COLOR_RESOLVER)));
@@ -8,7 +8,7 @@
});
private final ClientChunkCache chunkSource;
private final Deque<Runnable> lightUpdateQueue = Queues.newArrayDeque();
@@ -181,6 +_,8 @@
@@ -178,6 +_,8 @@
private final Long2ObjectMap<SortedSet<BlockDestructionProgress>> destructionProgress = new Long2ObjectOpenHashMap<>();
private final int seaLevel;
private static final Set<Item> MARKER_PARTICLE_ITEMS = Set.of(Items.BARRIER, Items.LIGHT);
@@ -17,7 +17,7 @@
public void handleBlockChangedAck(final int sequence) {
if (SharedConstants.DEBUG_BLOCK_BREAK) {
@@ -263,6 +_,8 @@
@@ -260,6 +_,8 @@
this.serverSimulationDistance = serverSimulationDistance;
this.environmentAttributes = this.addEnvironmentAttributeLayers(EnvironmentAttributeSystem.builder()).build();
this.updateSkyBrightness();
@@ -26,15 +26,15 @@
}
private EnvironmentAttributeSystem.Builder addEnvironmentAttributeLayers(final EnvironmentAttributeSystem.Builder environmentAttributes) {
@@ -473,6 +_,7 @@
public void tickNonPassenger(final Entity entity) {
@@ -471,6 +_,7 @@
entity.setOldPosAndRot();
entity.tickCount++;
Profiler.get().push(entity.typeHolder()::getRegisteredName);
entity.commonTick();
+ if (entity.canUpdate())
entity.tick();
Profiler.get().pop();
@@ -528,8 +_,10 @@
@@ -527,8 +_,10 @@
}
public void addEntity(final Entity entity) {
@@ -45,7 +45,7 @@
}
public void removeEntity(final int id, final Entity.RemovalReason reason) {
@@ -693,8 +_,10 @@
@@ -692,8 +_,10 @@
final float pitch,
final long seed
) {
@@ -57,7 +57,7 @@
}
}
@@ -708,8 +_,10 @@
@@ -707,8 +_,10 @@
final float pitch,
final long seed
) {
@@ -69,7 +69,7 @@
}
}
@@ -1095,7 +_,7 @@
@@ -1081,7 +_,7 @@
@Override
public void addDestroyBlockEffect(final BlockPos pos, final BlockState blockState) {
@@ -78,7 +78,7 @@
VoxelShape shape = blockState.getShape(this, pos);
double density = 0.25;
shape.forAllBoxes(
@@ -1122,6 +_,7 @@
@@ -1108,6 +_,7 @@
new TerrainParticle(
this, pos.getX() + x, pos.getY() + y, pos.getZ() + z, relX - 0.5, relY - 0.5, relZ - 0.5, blockState, pos
)
@@ -86,29 +86,30 @@
);
}
}
@@ -1138,6 +_,7 @@
this.playBreakingSound(pos, blockState);
}
+ if (!net.minecraftforge.client.extensions.common.IClientBlockExtensions.of(blockState).addHitEffects(blockState, this, direction, this.minecraft.particleEngine))
if (blockState.getRenderShape() != RenderShape.INVISIBLE && blockState.shouldSpawnTerrainParticles()) {
this.addBreakingParticles(pos, direction, blockState);
}
@@ -1177,11 +_,11 @@
xp = x + shape.maxX + 0.1F;
@@ -1117,6 +_,13 @@
}
- this.minecraft.particleEngine.add(new TerrainParticle(this, xp, yp, zp, 0.0, 0.0, 0.0, blockState, pos).setPower(0.2F).scale(0.6F));
+ this.minecraft.particleEngine.add(new TerrainParticle(this, xp, yp, zp, 0.0, 0.0, 0.0, blockState, pos).updateSprite(blockState, pos).setPower(0.2F).scale(0.6F));
}
private void playBreakingSound(final BlockPos pos, final BlockState blockState) {
- SoundType soundType = blockState.getSoundType();
+ SoundType soundType = blockState.getSoundType(this, pos, this.minecraft.player);
this.minecraft
.getSoundManager()
.play(
@@ -1248,6 +_,16 @@
+ public void addBreakingBlockEffect(BlockPos pos, net.minecraft.world.phys.BlockHitResult target) {
+ var state = this.getBlockState(pos);
+ if (!net.minecraftforge.client.extensions.common.IClientBlockExtensions.of(state).addHitEffects(state, this, target, this.minecraft.particleEngine))
+ addBreakingBlockEffect(pos, target.getDirection());
+ }
+
+ /** @deprecated Forge - Use crack(BlockPos, BlockHitResult) as it has more context and gives more control to modders */
public void addBreakingBlockEffect(final BlockPos pos, final Direction direction) {
BlockState blockState = this.getBlockState(pos);
if (blockState.getRenderShape() != RenderShape.INVISIBLE && blockState.shouldSpawnTerrainParticles()) {
@@ -1152,7 +_,7 @@
xp = x + shape.maxX + 0.1F;
}
- this.minecraft.particleEngine.add(new TerrainParticle(this, xp, yp, zp, 0.0, 0.0, 0.0, blockState, pos).setPower(0.2F).scale(0.6F));
+ this.minecraft.particleEngine.add(new TerrainParticle(this, xp, yp, zp, 0.0, 0.0, 0.0, blockState, pos).updateSprite(blockState, pos).setPower(0.2F).scale(0.6F));
}
}
@@ -1218,6 +_,16 @@
this.explosionTracker.track(center, radius, blockCount, blockParticles);
}
@@ -125,7 +126,7 @@
@OnlyIn(Dist.CLIENT)
public static class ClientLevelData implements WritableLevelData {
private final boolean hardcore;
@@ -1303,6 +_,7 @@
@@ -1273,6 +_,7 @@
}
public void setDifficulty(final Difficulty difficulty) {
@@ -133,7 +134,7 @@
this.difficulty = difficulty;
}
@@ -1345,6 +_,12 @@
@@ -1315,6 +_,12 @@
break;
default:
}
@@ -146,7 +147,7 @@
}
public void onTrackingEnd(final Entity entity) {
@@ -1357,6 +_,15 @@
@@ -1327,6 +_,15 @@
ClientLevel.this.dragonParts.removeAll(Arrays.asList(dragon.getSubEntities()));
break;
default:
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/multiplayer/ClientPacketListener.java
+++ b/net/minecraft/client/multiplayer/ClientPacketListener.java
@@ -534,6 +_,7 @@
@@ -531,6 +_,7 @@
this.debugSubscriber.clear();
this.minecraft.levelExtractor.debugRenderer.refreshRendererList();
this.minecraft.player.resetPos();
@@ -8,7 +8,7 @@
this.minecraft.player.setId(packet.playerId());
this.level.addEntity(this.minecraft.player);
this.minecraft.player.input = new KeyboardInput(this.minecraft.options);
@@ -1334,6 +_,8 @@
@@ -1323,6 +_,8 @@
newPlayer.getAttributes().assignBaseValues(oldPlayer.getAttributes());
}
@@ -17,7 +17,7 @@
this.level.addEntity(newPlayer);
newPlayer.input = new KeyboardInput(this.minecraft.options);
this.minecraft.gameMode.adjustPlayer(newPlayer);
@@ -1492,7 +_,7 @@
@@ -1478,7 +_,7 @@
ProblemReporter.ScopedCollector reporter = new ProblemReporter.ScopedCollector(blockEntity.problemPath(), LOGGER);
try {
@@ -26,7 +26,7 @@
} catch (Throwable t$) {
try {
reporter.close();
@@ -1700,7 +_,9 @@
@@ -1686,7 +_,9 @@
@Override
public void handleCommands(final ClientboundCommandsPacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.minecraft.packetProcessor());
@@ -37,7 +37,7 @@
}
@Override
@@ -1801,6 +_,7 @@
@@ -1787,6 +_,7 @@
if (this.minecraft.gui.screen() instanceof RecipeUpdateListener updateListener) {
updateListener.recipesUpdated();
}
@@ -45,8 +45,8 @@
}
@Override
@@ -1843,6 +_,8 @@
@@ -1830,6 +_,8 @@
this.fuelValues = FuelValues.vanillaBurnTimes(this.registryAccess, this.enabledFeatures);
List<ItemStack> searchItems = List.copyOf(CreativeModeTabs.searchTab().getDisplayItems());
this.searchTrees.updateCreativeTags(searchItems);
+
@@ -54,7 +54,7 @@
}
@Override
@@ -2672,7 +_,9 @@
@@ -2652,7 +_,9 @@
}
}
@@ -65,7 +65,7 @@
Instant timeStamp = Instant.now();
long salt = Crypt.SaltSupplier.getLong();
LastSeenMessagesTracker.Update lastSeenUpdate = this.lastSeenMessages.generateAndApplyUpdate();
@@ -2681,6 +_,7 @@
@@ -2661,6 +_,7 @@
}
public void sendCommand(final String command) {
@@ -73,7 +73,7 @@
SignableCommand<ClientSuggestionProvider> signableCommand = SignableCommand.of(this.commands.parse(command, this.suggestionsProvider));
if (signableCommand.arguments().isEmpty()) {
this.send(new ServerboundChatCommandPacket(command));
@@ -2697,6 +_,7 @@
@@ -2677,6 +_,7 @@
}
public void sendUnattendedCommand(final String command, final @Nullable Screen screenAfterCommand) {
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/multiplayer/MultiPlayerGameMode.java
+++ b/net/minecraft/client/multiplayer/MultiPlayerGameMode.java
@@ -120,6 +_,7 @@
@@ -115,6 +_,7 @@
}
public boolean destroyBlock(final BlockPos pos) {
@@ -8,7 +8,7 @@
if (this.minecraft.player.blockActionRestricted(this.minecraft.level, pos, this.localPlayerMode)) {
return false;
}
@@ -139,9 +_,8 @@
@@ -134,9 +_,8 @@
return false;
}
@@ -19,7 +19,7 @@
if (changed) {
oldBlock.destroy(level, pos, oldState);
}
@@ -170,6 +_,7 @@
@@ -165,6 +_,7 @@
}
this.startPrediction(this.minecraft.level, sequence -> {
@@ -27,7 +27,7 @@
this.destroyBlock(pos);
return new ServerboundPlayerActionPacket(ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK, pos, direction, sequence);
});
@@ -183,6 +_,7 @@
@@ -178,6 +_,7 @@
this.connection
.send(new ServerboundPlayerActionPacket(ServerboundPlayerActionPacket.Action.ABORT_DESTROY_BLOCK, this.destroyBlockPos, direction));
}
@@ -35,7 +35,7 @@
BlockState state = this.minecraft.level.getBlockState(pos);
this.minecraft.getTutorial().onDestroyBlock(this.minecraft.level, pos, state, 0.0F);
@@ -193,9 +_,11 @@
@@ -188,9 +_,11 @@
this.startPrediction(this.minecraft.level, sequence -> {
boolean notAir = !state.isAir();
if (notAir && this.destroyProgress == 0.0F) {
@@ -47,15 +47,15 @@
if (notAir && state.getDestroyProgress(this.minecraft.player, this.minecraft.player.level(), pos) >= 1.0F) {
this.destroyBlock(pos);
} else {
@@ -208,6 +_,7 @@
@@ -201,6 +_,7 @@
this.destroyTicks = 0.0F;
this.minecraft.level.destroyBlockProgress(this.minecraft.player.getId(), this.destroyBlockPos, this.getDestroyStage());
this.minecraft.level.addBreakingBlockEffects(this.destroyBlockPos, this.destroyDirection, true);
}
+ }
return new ServerboundPlayerActionPacket(ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK, pos, direction, sequence);
});
@@ -249,6 +_,7 @@
@@ -242,6 +_,7 @@
}
this.startPrediction(this.minecraft.level, sequence -> {
@@ -63,15 +63,24 @@
this.destroyBlock(pos);
return new ServerboundPlayerActionPacket(ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK, pos, direction, sequence);
});
@@ -263,6 +_,7 @@
@@ -255,7 +_,7 @@
this.destroyProgress = this.destroyProgress + state.getDestroyProgress(this.minecraft.player, this.minecraft.player.level(), pos);
if (this.destroyTicks % 4.0F == 0.0F) {
- SoundType soundType = state.getSoundType();
+ SoundType soundType = state.getSoundType(this.minecraft.level, pos, this.minecraft.player);
this.minecraft
.getSoundManager()
.play(
@@ -272,6 +_,7 @@
this.destroyTicks++;
this.minecraft.getTutorial().onDestroyBlock(this.minecraft.level, pos, state, Mth.clamp(this.destroyProgress, 0.0F, 1.0F));
+ if (net.minecraftforge.event.ForgeEventFactory.onLeftClickBlockHold(this.minecraft.player, pos, direction).getUseItem().isDenied()) return true;
+ if (net.minecraftforge.event.ForgeEventFactory.onLeftClickBlockHold(this.minecraft.player, pos, direction).getUseItem().isDenied()) return true;
if (this.destroyProgress >= 1.0F) {
this.isDestroying = false;
if (SharedConstants.DEBUG_BLOCK_BREAK) {
@@ -270,6 +_,7 @@
@@ -279,6 +_,7 @@
}
this.startPrediction(this.minecraft.level, sequence -> {
@@ -79,7 +88,7 @@
this.destroyBlock(pos);
return new ServerboundPlayerActionPacket(ServerboundPlayerActionPacket.Action.STOP_DESTROY_BLOCK, pos, direction, sequence);
});
@@ -308,7 +_,7 @@
@@ -313,7 +_,7 @@
private boolean sameDestroyTarget(final BlockPos pos) {
ItemStack selected = this.minecraft.player.getMainHandItem();
@@ -88,7 +97,7 @@
}
private void ensureHasSentCarriedItem() {
@@ -336,13 +_,24 @@
@@ -341,13 +_,24 @@
private InteractionResult performUseItemOn(final LocalPlayer player, final InteractionHand hand, final BlockHitResult blockHit) {
BlockPos pos = blockHit.getBlockPos();
ItemStack itemStack = player.getItemInHand(hand);
@@ -115,7 +124,7 @@
BlockState blockState = this.minecraft.level.getBlockState(pos);
if (!this.connection.isFeatureEnabled(blockState.getBlock().requiredFeatures())) {
return InteractionResult.FAIL;
@@ -361,8 +_,10 @@
@@ -366,8 +_,10 @@
}
}
@@ -125,10 +134,10 @@
+ return InteractionResult.PASS;
+ }
+ if (event.getUseItem().isAllowed() || (!itemStack.isEmpty() && !player.getCooldowns().isOnCooldown(itemStack))) {
InteractionResult result;
InteractionResult success;
if (player.hasInfiniteMaterials()) {
int count = itemStack.getCount();
@@ -399,6 +_,12 @@
@@ -398,6 +_,12 @@
return packet;
}
@@ -141,7 +150,7 @@
InteractionResult resultHolder = itemStack.use(this.minecraft.level, player, hand);
ItemStack result;
if (resultHolder instanceof InteractionResult.Success success) {
@@ -409,6 +_,9 @@
@@ -408,6 +_,9 @@
if (result != itemStack) {
player.setItemInHand(hand, result);
@@ -151,7 +160,7 @@
}
interactionResult.setValue(resultHolder);
@@ -456,6 +_,10 @@
@@ -445,6 +_,10 @@
this.ensureHasSentCarriedItem();
Vec3 location = hitResult.getLocation().subtract(entity.getX(), entity.getY(), entity.getZ());
this.connection.send(new ServerboundInteractPacket(entity.getId(), hand, location, player.isShiftKeyDown()));
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/multiplayer/chat/ChatListener.java
+++ b/net/minecraft/client/multiplayer/chat/ChatListener.java
@@ -138,6 +_,8 @@
@@ -142,6 +_,8 @@
LocalPlayer receiver = this.minecraft.player;
if (receiver != null && receiver.chatAbilities().canReceivePlayerMessages()) {
Component decoratedMessage = boundChatType.decorate(message);
@@ -9,7 +9,7 @@
this.minecraft.gui.hud.getChat().addPlayerMessage(decoratedMessage, null, GuiMessageTag.system());
this.narrateChatMessage(boundChatType, message);
this.logSystemMessage(decoratedMessage, received);
@@ -173,12 +_,16 @@
@@ -177,12 +_,16 @@
MessageSignature signature = message.signature();
FilterMask filterMask = message.filterMask();
if (filterMask.isEmpty()) {
@@ -28,7 +28,7 @@
this.narrateChatMessage(boundChatType, filteredContent);
}
}
@@ -212,12 +_,14 @@
@@ -216,12 +_,14 @@
chatLog.push(LoggedChatMessage.system(message, timeStamp));
}
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/particle/FireworkParticles.java
+++ b/net/minecraft/client/particle/FireworkParticles.java
@@ -259,6 +_,10 @@
@@ -256,6 +_,10 @@
colors = IntList.of(DyeColor.BLACK.getFireworkColor());
}
@@ -8,7 +8,7 @@
private @Nullable Runnable onReload;
public ParticleResources() {
@@ -186,14 +_,17 @@
@@ -183,14 +_,17 @@
this.register(ParticleTypes.SULFUR_CUBE_GOO, BreakingItemParticle.SulfurCubeProvider::new);
}
@@ -27,7 +27,7 @@
}
@Override
@@ -284,8 +_,13 @@
@@ -281,8 +_,13 @@
}
}
@@ -1,23 +0,0 @@
--- a/net/minecraft/client/player/FirstPersonHandsAndItems.java
+++ b/net/minecraft/client/player/FirstPersonHandsAndItems.java
@@ -45,8 +_,18 @@
this.offHandHeight = Mth.clamp(this.offHandHeight - 0.4F, 0.0F, 1.0F);
} else {
float attackAnim = player.getItemSwapScale(1.0F);
- float mainHandTargetHeight = this.mainHandItem != nextMainHand ? 0.0F : attackAnim * attackAnim * attackAnim;
- float offHandTargetHeight = this.offHandItem != nextOffHand ? 0.0F : 1.0F;
+
+ boolean requipM = net.minecraftforge.client.ForgeHooksClient.shouldCauseReequipAnimation(this.mainHandItem, nextMainHand, player.getInventory().getSelectedSlot());
+ boolean requipO = net.minecraftforge.client.ForgeHooksClient.shouldCauseReequipAnimation(this.offHandItem, nextOffHand, -1);
+
+ if (!requipM && this.mainHandItem != nextMainHand)
+ this.mainHandItem = nextMainHand;
+ if (!requipO && this.offHandItem != nextOffHand)
+ this.offHandItem = nextOffHand;
+
+ float mainHandTargetHeight = requipM ? 0.0F : attackAnim * attackAnim * attackAnim;
+ float offHandTargetHeight = requipO ? 0.0F : 1.0F;
+
this.mainHandHeight = this.mainHandHeight + Mth.clamp(mainHandTargetHeight - this.mainHandHeight, -0.4F, 0.4F);
this.offHandHeight = this.offHandHeight + Mth.clamp(offHandTargetHeight - this.offHandHeight, -0.4F, 0.4F);
}
@@ -1,6 +1,14 @@
--- a/net/minecraft/client/player/LocalPlayer.java
+++ b/net/minecraft/client/player/LocalPlayer.java
@@ -560,7 +_,10 @@
@@ -318,6 +_,7 @@
ServerboundPlayerActionPacket.Action action = all
? ServerboundPlayerActionPacket.Action.DROP_ALL_ITEMS
: ServerboundPlayerActionPacket.Action.DROP_ITEM;
+ if (isUsingItem() && getUsedItemHand() == InteractionHand.MAIN_HAND && (all || getUseItem().getCount() == 1)) stopUsingItem(); // Forge: fix MC-231097 on the clientside
ItemStack prediction = this.getInventory().removeFromSelected(all);
this.connection.send(new ServerboundPlayerActionPacket(action, BlockPos.ZERO, Direction.DOWN));
return !prediction.isEmpty();
@@ -545,7 +_,10 @@
@Override
public void playSound(final SoundEvent sound, final float volume, final float pitch) {
@@ -12,7 +20,7 @@
}
@Override
@@ -803,6 +_,7 @@
@@ -787,6 +_,7 @@
&& this.canPlayerFitWithinBlocksAndEntitiesWhen(Pose.CROUCHING)
&& (this.isShiftKeyDown() || !this.isSleeping() && !this.canPlayerFitWithinBlocksAndEntitiesWhen(Pose.STANDING));
this.input.tick();
@@ -20,7 +28,7 @@
this.minecraft.getTutorial().onInput(this.input);
boolean wasAutoJump = false;
if (this.autoJumpTime > 0) {
@@ -875,8 +_,9 @@
@@ -859,8 +_,9 @@
}
this.wasFallFlying = this.isFallFlying();
@@ -32,7 +40,7 @@
}
if (this.isEyeInFluid(FluidTags.WATER)) {
@@ -944,7 +_,7 @@
@@ -928,7 +_,7 @@
}
private boolean shouldStopSwimSprinting() {
@@ -41,7 +49,7 @@
}
public Portal.Transition getActivePortalLocalTransition() {
@@ -1004,6 +_,8 @@
@@ -973,6 +_,8 @@
@Override
public void rideTick() {
super.rideTick();
@@ -50,7 +58,7 @@
this.handsBusy = false;
if (this.getControlledVehicle() instanceof AbstractBoat boat) {
boat.setInput(this.input.keyPresses.left(), this.input.keyPresses.right(), this.input.keyPresses.forward(), this.input.keyPresses.backward());
@@ -1178,7 +_,7 @@
@@ -1147,7 +_,7 @@
&& this.isSprintingPossible(this.getAbilities().flying)
&& !this.isSlowDueToUsingItem()
&& (!this.isFallFlying() || this.isUnderWater())
@@ -59,7 +67,7 @@
}
private boolean vehicleCanSprint(final Entity vehicle) {
@@ -1253,6 +_,17 @@
@@ -1222,6 +_,17 @@
@Override
public float getVisualRotationYInDegrees() {
return this.getYRot();
@@ -1,35 +0,0 @@
--- a/net/minecraft/client/renderer/FirstPersonHandsAndItemsRenderer.java
+++ b/net/minecraft/client/renderer/FirstPersonHandsAndItemsRenderer.java
@@ -352,6 +_,7 @@
if (state.handRenderSelection.renderMainHand) {
float mainHandAttack = attackHand == InteractionHand.MAIN_HAND ? attackValue : 0.0F;
float mainhandInverseArmHeight = state.mainHandSwapScale * (1.0F - Mth.lerp(partialTicks, state.oldMainHandHeight, state.mainHandHeight));
+ if (!net.minecraftforge.client.ForgeHooksClient.renderSpecificFirstPersonHand(InteractionHand.MAIN_HAND, poseStack, submitNodeCollector, playerState.avatarRenderState.lightCoords, partialTicks, xRot, mainHandAttack, mainhandInverseArmHeight, state.mainHandItem))
this.submitArmWithItem(
playerState,
state,
@@ -370,6 +_,7 @@
if (state.handRenderSelection.renderOffHand) {
float offHandAttack = attackHand == InteractionHand.OFF_HAND ? attackValue : 0.0F;
float offhandInverseArmHeight = state.offHandSwapScale * (1.0F - Mth.lerp(partialTicks, state.oldOffHandHeight, state.offHandHeight));
+ if (!net.minecraftforge.client.ForgeHooksClient.renderSpecificFirstPersonHand(InteractionHand.OFF_HAND, poseStack, submitNodeCollector, playerState.avatarRenderState.lightCoords, partialTicks, xRot, offHandAttack, offhandInverseArmHeight, state.offHandItem))
this.submitArmWithItem(
playerState,
state,
@@ -418,7 +_,7 @@
} else {
this.renderOneHandedMap(poseStack, submitNodeCollector, lightCoords, inverseArmHeight, arm, attack, itemStack, playerState, state);
}
- } else if (itemStack.is(Items.CROSSBOW)) {
+ } else if (itemStack.getItem() instanceof CrossbowItem) {
this.applyItemArmTransform(poseStack, arm, inverseArmHeight);
boolean charged = CrossbowItem.isCharged(itemStack);
boolean isRightArm = arm == HumanoidArm.RIGHT;
@@ -457,6 +_,7 @@
} else {
boolean isRightArm = arm == HumanoidArm.RIGHT;
int invert = isRightArm ? 1 : -1;
+ if (!net.minecraftforge.client.extensions.common.IClientItemExtensions.of(itemStack).applyForgeHandTransform(poseStack, minecraft.player, arm, itemStack, partialTicks, inverseArmHeight, attack)) // FORGE: Allow items to define custom arm animation
if (avatarRenderState.isUsingItem && state.useItemRemainingTicks > 0 && avatarRenderState.useItemHand == hand) {
ItemUseAnimation useAnimation = itemStack.getUseAnimation();
if (!useAnimation.hasCustomArmTransform()) {
@@ -1,41 +1,33 @@
--- a/net/minecraft/client/renderer/GameRenderer.java
+++ b/net/minecraft/client/renderer/GameRenderer.java
@@ -240,6 +_,9 @@
@@ -220,6 +_,9 @@
case null:
default:
this.clearSpectatedEntityPostEffect();
this.clearPostEffect();
+ var rl = cameraEntity == null ? null : net.minecraftforge.client.EntitySpectatorShaderManager.get(cameraEntity.getType());
+ if (rl != null)
+ this.setSpectatedEntityPostEffect(rl);
+ this.setPostEffect(rl);
}
}
@@ -430,6 +_,8 @@
ProfilerFiller profiler = Profiler.get();
profiler.push("camera");
this.mainCamera.update(deltaTracker);
+ var cameraSetup = net.minecraftforge.client.event.ForgeEventFactoryClient.fireComputeCameraAngles(this, this.mainCamera, deltaTracker.getGameTimeDeltaPartialTick(true));
+ this.mainCamera.setRotation(cameraSetup.getYaw(), cameraSetup.getPitch(), cameraSetup.getRoll());
profiler.pop();
this.requestedPostEffects.clear();
this.requestedPostEffects.add(END_OF_FRAME_POST_EFFECT);
@@ -628,6 +_,10 @@
BlockInWorld blockInWorld = new BlockInWorld(this.minecraft.level, pos, false);
@@ -515,6 +_,10 @@
Registry<Block> blockRegistry = this.minecraft.level.registryAccess().lookupOrThrow(Registries.BLOCK);
renderOutline = !itemStack.isEmpty()
&& (itemStack.canBreakBlockInAdventureMode(blockInWorld) || itemStack.canPlaceOnBlockInAdventureMode(blockInWorld));
+ if (!renderOutline && blockInWorld.getState().hasBlockEntity()) {
+ if (!renderOutline && blockState.hasBlockEntity()) {
+ var blockEntity = this.minecraft.level.getBlockEntity(pos);
+ renderOutline = blockEntity != null && blockEntity.hasCustomOutlineRendering();
+ }
}
}
}
@@ -780,6 +_,8 @@
private void extractCamera(final DeltaTracker deltaTracker, final float worldPartialTicks) {
CameraRenderState cameraState = this.gameRenderState.levelRenderState.cameraRenderState;
@@ -538,6 +_,9 @@
if (optionsState.bobView) {
this.bobView(cameraState, bobStack);
}
+
+ var cameraSetup = net.minecraftforge.client.event.ForgeEventFactoryClient.fireComputeCameraAngles(this, this.mainCamera, worldPartialTicks);
+ this.mainCamera.setRotation(cameraSetup.getYaw(), cameraSetup.getPitch(), cameraSetup.getRoll());
this.mainCamera.extractRenderState(cameraState, deltaTracker);
cameraState.fogType = this.mainCamera.getFluidInCamera();
cameraState.fogData = this.fogRenderer
projectionMatrix.mul(bobStack.last().pose());
float screenEffectScale = optionsState.screenEffectScale;
@@ -0,0 +1,57 @@
--- a/net/minecraft/client/renderer/ItemInHandRenderer.java
+++ b/net/minecraft/client/renderer/ItemInHandRenderer.java
@@ -362,6 +_,7 @@
float mainHandAttack = attackHand == InteractionHand.MAIN_HAND ? attackValue : 0.0F;
float mainhandInverseArmHeight = this.itemModelResolver.swapAnimationScale(this.mainHandItem)
* (1.0F - Mth.lerp(frameInterp, this.oMainHandHeight, this.mainHandHeight));
+ if (!net.minecraftforge.client.ForgeHooksClient.renderSpecificFirstPersonHand(InteractionHand.MAIN_HAND, poseStack, submitNodeCollector, lightCoords, frameInterp, xRot, mainHandAttack, mainhandInverseArmHeight, this.mainHandItem))
this.submitArmWithItem(
player,
frameInterp,
@@ -380,6 +_,8 @@
float offHandAttack = attackHand == InteractionHand.OFF_HAND ? attackValue : 0.0F;
float offhandInverseArmHeight = this.itemModelResolver.swapAnimationScale(this.offHandItem)
* (1.0F - Mth.lerp(frameInterp, this.oOffHandHeight, this.offHandHeight));
+
+ if (!net.minecraftforge.client.ForgeHooksClient.renderSpecificFirstPersonHand(InteractionHand.OFF_HAND, poseStack, submitNodeCollector, lightCoords, frameInterp, xRot, offHandAttack, offhandInverseArmHeight, this.offHandItem))
this.submitArmWithItem(
player,
frameInterp,
@@ -454,7 +_,7 @@
} else {
this.renderOneHandedMap(poseStack, submitNodeCollector, lightCoords, inverseArmHeight, arm, attack, itemStack);
}
- } else if (itemStack.is(Items.CROSSBOW)) {
+ } else if (itemStack.getItem() instanceof CrossbowItem) {
this.applyItemArmTransform(poseStack, arm, inverseArmHeight);
boolean charged = CrossbowItem.isCharged(itemStack);
boolean isRightArm = arm == HumanoidArm.RIGHT;
@@ -499,6 +_,7 @@
} else {
boolean isRightArm = arm == HumanoidArm.RIGHT;
int invert = isRightArm ? 1 : -1;
+ if (!net.minecraftforge.client.extensions.common.IClientItemExtensions.of(itemStack).applyForgeHandTransform(poseStack, minecraft.player, arm, itemStack, frameInterp, inverseArmHeight, attack)) // FORGE: Allow items to define custom arm animation
if (player.isUsingItem() && player.getUseItemRemainingTicks() > 0 && player.getUsedItemHand() == hand) {
ItemUseAnimation useAnimation = itemStack.getUseAnimation();
if (!useAnimation.hasCustomArmTransform()) {
@@ -647,8 +_,18 @@
this.offHandHeight = Mth.clamp(this.offHandHeight - 0.4F, 0.0F, 1.0F);
} else {
float attackAnim = player.getItemSwapScale(1.0F);
- float mainHandTargetHeight = this.mainHandItem != nextMainHand ? 0.0F : attackAnim * attackAnim * attackAnim;
- float offHandTargetHeight = this.offHandItem != nextOffHand ? 0.0F : 1.0F;
+
+ boolean requipM = net.minecraftforge.client.ForgeHooksClient.shouldCauseReequipAnimation(this.mainHandItem, nextMainHand, player.getInventory().getSelectedSlot());
+ boolean requipO = net.minecraftforge.client.ForgeHooksClient.shouldCauseReequipAnimation(this.offHandItem, nextOffHand, -1);
+
+ if (!requipM && this.mainHandItem != nextMainHand)
+ this.mainHandItem = nextMainHand;
+ if (!requipO && this.offHandItem != nextOffHand)
+ this.offHandItem = nextOffHand;
+
+ float mainHandTargetHeight = requipM ? 0.0F : attackAnim * attackAnim * attackAnim;
+ float offHandTargetHeight = requipO ? 0.0F : 1.0F;
+
this.mainHandHeight = this.mainHandHeight + Mth.clamp(mainHandTargetHeight - this.mainHandHeight, -0.4F, 0.4F);
this.offHandHeight = this.offHandHeight + Mth.clamp(offHandTargetHeight - this.offHandHeight, -0.4F, 0.4F);
}
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/renderer/LevelEventHandler.java
+++ b/net/minecraft/client/renderer/LevelEventHandler.java
@@ -312,7 +_,7 @@
@@ -305,7 +_,7 @@
case 2001:
BlockState blockState = Block.stateById(data);
if (!blockState.isAir()) {
@@ -1,16 +1,16 @@
--- a/net/minecraft/client/renderer/LevelRenderer.java
+++ b/net/minecraft/client/renderer/LevelRenderer.java
@@ -279,6 +_,7 @@
}
@@ -235,6 +_,7 @@
}
+ net.minecraftforge.client.FramePassManager.insertForgePasses(frame, targets, this.levelRenderState); // Forge: Modded passes are inserted here.
this.addAlwaysOnTopPass(frame, featureFrame, terrainFog);
+ net.minecraftforge.client.FramePassManager.insertForgePasses(frame, targets, this.levelRenderState, deltaTracker); // Forge: Modded passes are inserted here.
profiler.popPush("executeFrameGraph");
frame.execute(resourceAllocator, new FrameGraphBuilder.Inspector() {
@Override
@@ -335,7 +_,8 @@
@@ -285,7 +_,8 @@
this.submitBlockDestroyAnimation(poseStack, submitNodeCollector, levelRenderState);
levelRenderState.blockBreakingRenderStates.clear();
this.submitTransientBlocks(poseStack, submitNodeCollector, levelRenderState);
levelRenderState.particlesRenderState.submit(submitNodeCollector, levelRenderState.cameraRenderState);
- if (renderOutline) {
+ var hasCustomOutline = this.levelRenderState.blockOutlineRenderState != null && this.levelRenderState.blockOutlineRenderState.customRenderer() != null;
@@ -18,7 +18,7 @@
this.submitBlockOutline(poseStack, this.submitNodeStorage, levelRenderState);
}
@@ -1075,6 +_,10 @@
@@ -705,6 +_,10 @@
private void submitBlockOutline(final PoseStack poseStack, final SubmitNodeCollector submitNodeCollector, final LevelRenderState levelRenderState) {
BlockOutlineRenderState state = levelRenderState.blockOutlineRenderState;
if (state != null) {
@@ -29,7 +29,7 @@
Vec3 cameraPos = levelRenderState.cameraRenderState.pos;
BlockPos pos = state.pos();
poseStack.pushPose();
@@ -1331,6 +_,14 @@
@@ -979,6 +_,14 @@
public SectionOcclusionGraph sectionOcclusionGraph() {
return this.sectionOcclusionGraph;
@@ -1,43 +1,70 @@
--- a/net/minecraft/client/renderer/ScreenEffectRenderer.java
+++ b/net/minecraft/client/renderer/ScreenEffectRenderer.java
@@ -40,6 +_,9 @@
@@ -61,8 +_,9 @@
PoseStack poseStack = new PoseStack();
AvatarRenderState avatarRenderState = playerRenderState.avatarRenderState;
if (!cameraRenderState.entityRenderState.isSleeping && playerRenderState.hasPlayer && avatarRenderState != null) {
+ if (playerRenderState.customBlockOverlay != null)
+ playerRenderState.customBlockOverlay.render(poseStack, submitNodeCollector);
+ else
if (playerRenderState.blockOverlay != null) {
submitBlockSprite(
playerRenderState.blockOverlay.atlasLocation(),
@@ -54,10 +_,16 @@
}
Player player = this.minecraft.player;
if (isFirstPerson && !isSleeping) {
- BlockState blockState = getViewBlockingState(player);
- if (blockState != null) {
+ var overlay = getOverlayBlock(player);
+ BlockState blockState = overlay == null ? null : overlay.getLeft();
+ if (blockState != null && net.minecraftforge.client.ForgeHooksClient.renderBlockOverlay(player, poseStack, net.minecraftforge.client.event.RenderBlockScreenEffectEvent.OverlayType.BLOCK, overlay.getLeft(), overlay.getRight())) {
BlockStateModelSet blockStateModelSet = this.minecraft.getModelManager().getBlockStateModelSet();
TextureAtlasSprite sprite = blockStateModelSet.getParticleMaterial(blockState).sprite();
submitBlockSprite(sprite, poseStack, submitNodeCollector, -15132391);
@@ -70,11 +_,15 @@
if (cameraRenderState.isFirstPerson && !avatarRenderState.isSpectator) {
+ if (playerRenderState.customFluidOverlay != null)
+ playerRenderState.customFluidOverlay.render(poseStack, submitNodeCollector);
+ else
if (playerRenderState.waterOverlay != null) {
submitWater(playerRenderState.waterOverlay, poseStack, submitNodeCollector);
if (!this.minecraft.player.isSpectator()) {
if (this.minecraft.player.isEyeInFluid(FluidTags.WATER)) {
+ if (!net.minecraftforge.client.ForgeHooksClient.renderWaterOverlay(player, poseStack))
submitWater(this.minecraft, poseStack, submitNodeCollector);
+ } else if (!player.getEyeInFluidType().isAir()) {
+ net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions.of(player.getEyeInFluidType()).renderOverlay(this.minecraft, poseStack, submitNodeCollector);
}
+ if (playerRenderState.customFireOverlay != null)
+ playerRenderState.customFireOverlay.render(poseStack, submitNodeCollector);
+ else
if (playerRenderState.isOnFire) {
if (this.minecraft.player.isOnFire()) {
TextureAtlasSprite fireSprite = this.sprites.get(ModelBakery.FIRE_1);
+ if (!net.minecraftforge.client.ForgeHooksClient.renderFireOverlay(player, poseStack))
submitFire(poseStack, submitNodeCollector, fireSprite);
@@ -116,9 +_,12 @@
}
}
@@ -128,6 +_,11 @@
return null;
}
+ var ret = getOverlayBlock(player);
+ return ret == null ? null : ret.getLeft();
+ }
+
+ private static org.apache.commons.lang3.tuple.@Nullable Pair<BlockState, BlockPos> getOverlayBlock(Player player) {
BlockPos.MutableBlockPos testPos = new BlockPos.MutableBlockPos();
for (int i = 0; i < 8; i++) {
@@ -138,7 +_,7 @@
);
BlockState blockState = player.level().getBlockState(testPos);
if (blockState.getRenderShape() != RenderShape.INVISIBLE && blockState.isViewBlocking(player.level(), testPos)) {
- return blockState;
+ return org.apache.commons.lang3.tuple.Pair.of(blockState, testPos.immutable());
}
}
@@ -156,13 +_,17 @@
}
private static void submitWater(final PlayerRenderState.WaterOverlay waterOverlay, final PoseStack poseStack, final SubmitNodeCollector submitNodeCollector) {
+ submitFluid(waterOverlay, poseStack, submitNodeCollector, UNDERWATER_LOCATION);
private static void submitWater(final Minecraft minecraft, final PoseStack poseStack, final SubmitNodeCollector submitNodeCollector) {
+ renderFluid(minecraft, poseStack, submitNodeCollector, UNDERWATER_LOCATION);
+ }
+ public static void submitFluid(final PlayerRenderState.WaterOverlay waterOverlay, final PoseStack poseStack, final SubmitNodeCollector submitNodeCollector, Identifier texture) {
submitNodeCollector.submitCustomGeometry(
poseStack,
- RenderTypes.blockScreenEffect(UNDERWATER_LOCATION),
+ RenderTypes.blockScreenEffect(texture),
(pose, builder) -> {
float uvSize = 4.0F;
buildQuad(
+
+ public static void renderFluid(Minecraft minecraft, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, Identifier texture) {
LocalPlayer player = minecraft.player;
BlockPos pos = BlockPos.containing(player.getEyePosition());
float brightness = Lightmap.getBrightness(player.level().dimensionType(), player.level().getMaxLocalRawBrightness(pos));
int color = ARGB.colorFromFloat(0.1F, brightness, brightness, brightness);
float u0 = -player.getYRot() / 64.0F;
float v0 = player.getXRot() / 64.0F;
- submitNodeCollector.submitCustomGeometry(poseStack, RenderTypes.blockScreenEffect(UNDERWATER_LOCATION), (pose, builder) -> {
+ submitNodeCollector.submitCustomGeometry(poseStack, RenderTypes.blockScreenEffect(texture), (pose, builder) -> {
float uvSize = 4.0F;
buildQuad(builder, pose.pose(), -1.0F, -1.0F, 1.0F, 1.0F, -0.5F, u0 + 4.0F, v0 + 4.0F, u0, v0, color);
});
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/renderer/Sheets.java
+++ b/net/minecraft/client/renderer/Sheets.java
@@ -153,4 +_,13 @@
@@ -120,4 +_,13 @@
case COPPER_OXIDIZED -> (SpriteId)CHEST_COPPER.oxidized().select(type);
};
}
@@ -0,0 +1,50 @@
--- a/net/minecraft/client/renderer/SpriteCoordinateExpander.java
+++ b/net/minecraft/client/renderer/SpriteCoordinateExpander.java
@@ -17,12 +_,14 @@
@Override
public VertexConsumer addVertex(final float x, final float y, final float z) {
- return this.delegate.addVertex(x, y, z);
+ this.delegate.addVertex(x, y, z);
+ return this; // Forge: Fix MC-263524 not working with chained methods
}
@Override
public VertexConsumer setColor(final int r, final int g, final int b, final int a) {
- return this.delegate.setColor(r, g, b, a);
+ this.delegate.setColor(r, g, b, a);
+ return this; // Forge: Fix MC-263524 not working with chained methods
}
@Override
@@ -32,22 +_,26 @@
@Override
public VertexConsumer setUv(final float u, final float v) {
- return this.delegate.setUv(this.sprite.getU(u), this.sprite.getV(v));
+ this.delegate.setUv(this.sprite.getU(u), this.sprite.getV(v));
+ return this; // Forge: Fix MC-263524 not working with chained methods
}
@Override
public VertexConsumer setUv1(final int u, final int v) {
- return this.delegate.setUv1(u, v);
+ this.delegate.setUv1(u, v);
+ return this; // Forge: Fix MC-263524 not working with chained methods
}
@Override
public VertexConsumer setUv2(final int u, final int v) {
- return this.delegate.setUv2(u, v);
+ this.delegate.setUv2(u, v);
+ return this; // Forge: Fix MC-263524 not working with chained methods
}
@Override
public VertexConsumer setNormal(final float x, final float y, final float z) {
- return this.delegate.setNormal(x, y, z);
+ this.delegate.setNormal(x, y, z);
+ return this; // Forge: Fix MC-263524 not working with chained methods
}
@Override
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/renderer/culling/Frustum.java
+++ b/net/minecraft/client/renderer/culling/Frustum.java
@@ -84,6 +_,8 @@
@@ -83,6 +_,8 @@
}
public boolean isVisible(final AABB bb) {
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/renderer/debug/EntityHitboxDebugRenderer.java
+++ b/net/minecraft/client/renderer/debug/EntityHitboxDebugRenderer.java
@@ -102,8 +_,8 @@
@@ -99,8 +_,8 @@
);
}
@@ -1,7 +1,7 @@
--- a/net/minecraft/client/renderer/entity/EntityRenderDispatcher.java
+++ b/net/minecraft/client/renderer/entity/EntityRenderDispatcher.java
@@ -201,6 +_,14 @@
return this.camera.position().distanceToSqr(entity.position());
@@ -207,6 +_,14 @@
return this.itemInHandRenderer;
}
+ public Map<PlayerModelType, AvatarRenderer<AbstractClientPlayer>> getPlayerRenderers() {
@@ -15,7 +15,7 @@
@Override
public void onResourceManagerReload(final ResourceManager resourceManager) {
EntityRendererProvider.Context context = new EntityRendererProvider.Context(
@@ -219,5 +_,6 @@
@@ -224,5 +_,6 @@
this.renderers = EntityRenderers.createEntityRenderers(context);
this.playerRenderers = EntityRenderers.createAvatarRenderers(context);
this.mannequinRenderers = EntityRenderers.createAvatarRenderers(context);
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/renderer/entity/HumanoidMobRenderer.java
+++ b/net/minecraft/client/renderer/entity/HumanoidMobRenderer.java
@@ -67,7 +_,7 @@
@@ -69,7 +_,7 @@
state.isCrouching = entity.isCrouching();
state.isFallFlying = entity.isFallFlying();
state.isVisuallySwimming = entity.isVisuallySwimming();
@@ -3,9 +3,9 @@
@@ -82,6 +_,7 @@
if (state.mapId != null) {
int rotation = state.rotation % 4 * 2;
poseStack.rotateDegrees(Axis.ZP, rotation * 360.0F / 8.0F);
poseStack.mulPose(Axis.ZP.rotationDegrees(rotation * 360.0F / 8.0F));
+ if (!net.minecraftforge.client.event.ForgeEventFactoryClient.onRenderItemInFrame(state, this, poseStack, submitNodeCollector, state.lightCoords)) {
poseStack.rotateDegrees(Axis.ZP, 180.0F);
poseStack.mulPose(Axis.ZP.rotationDegrees(180.0F));
float s = 0.0078125F;
poseStack.scale(0.0078125F, 0.0078125F, 0.0078125F);
@@ -89,6 +_,7 @@
@@ -14,5 +14,5 @@
this.mapRenderer.render(state.mapRenderState, poseStack, submitNodeCollector, true, lightCoords);
+ }
} else if (!state.item.isEmpty()) {
poseStack.rotateDegrees(Axis.ZP, state.rotation * 360.0F / 8.0F);
poseStack.mulPose(Axis.ZP.rotationDegrees(state.rotation * 360.0F / 8.0F));
int lightVal = this.getLightCoords(state.isGlowFrame, 15728880, state.lightCoords);
@@ -8,7 +8,7 @@
poseStack.pushPose();
if (state.hasPose(Pose.SLEEPING)) {
Direction bedOrientation = state.bedOrientation;
@@ -108,6 +_,7 @@
@@ -110,6 +_,7 @@
poseStack.popPose();
super.submit(state, poseStack, submitNodeCollector, camera);
@@ -16,7 +16,7 @@
}
protected boolean shouldRenderLayers(final S state) {
@@ -276,7 +_,7 @@
@@ -278,7 +_,7 @@
state.isFullyFrozen = entity.isFullyFrozen();
state.isBaby = entity.isBaby();
@@ -1,24 +1,26 @@
--- a/net/minecraft/client/renderer/entity/player/AvatarRenderer.java
+++ b/net/minecraft/client/renderer/entity/player/AvatarRenderer.java
@@ -94,7 +_,7 @@
@@ -98,7 +_,7 @@
return HumanoidModel.ArmPose.EMPTY;
}
- if (!avatar.isSwinging() && itemInHand.is(Items.CROSSBOW) && CrossbowItem.isCharged(itemInHand)) {
+ if (!avatar.isSwinging() && itemInHand.getItem() instanceof CrossbowItem && CrossbowItem.isCharged(itemInHand)) {
- if (!avatar.swinging && itemInHand.is(Items.CROSSBOW) && CrossbowItem.isCharged(itemInHand)) {
+ if (!avatar.swinging && itemInHand.getItem() instanceof CrossbowItem && CrossbowItem.isCharged(itemInHand)) {
return HumanoidModel.ArmPose.CROSSBOW_HOLD;
}
@@ -135,7 +_,7 @@
return HumanoidMobRenderer.usesSpearPose(itemInHand, hand.asArm(avatar.getMainArm()), avatar)
? HumanoidModel.ArmPose.SPEAR
- : HumanoidModel.ArmPose.ITEM;
+ : net.minecraftforge.client.extensions.common.IClientItemExtensions.of(itemInHand).getArmPose(avatar, hand, itemInHand);
@@ -141,7 +_,9 @@
if (attack != null && attack.type() == SwingAnimationType.STAB && avatar.swinging) {
return HumanoidModel.ArmPose.SPEAR;
} else {
- return itemInHand.is(ItemTags.SPEARS) ? HumanoidModel.ArmPose.SPEAR : HumanoidModel.ArmPose.ITEM;
+ if (itemInHand.is(ItemTags.SPEARS)) return HumanoidModel.ArmPose.SPEAR;
+ var pose = net.minecraftforge.client.extensions.common.IClientItemExtensions.of(itemInHand).getArmPose(avatar, hand, itemInHand);
+ return pose == null ? HumanoidModel.ArmPose.ITEM : pose;
}
}
public Identifier getTextureLocation(final AvatarRenderState state) {
@@ -234,12 +_,14 @@
@@ -241,12 +_,14 @@
public void renderRightHand(
final PoseStack poseStack, final SubmitNodeCollector submitNodeCollector, final int lightCoords, final Identifier skinTexture, final boolean hasSleeve
) {
@@ -33,7 +35,7 @@
this.renderHand(poseStack, submitNodeCollector, lightCoords, skinTexture, this.model.leftArm, hasSleeve);
}
@@ -297,5 +_,12 @@
@@ -304,5 +_,12 @@
public static boolean isPlayerUpsideDown(final Player player) {
return isUpsideDownName(player.getGameProfile().name());
@@ -1,15 +1,15 @@
--- a/net/minecraft/client/renderer/extract/LevelExtractor.java
+++ b/net/minecraft/client/renderer/extract/LevelExtractor.java
@@ -188,7 +_,7 @@
@@ -172,7 +_,7 @@
profiler.popPush("entities");
this.extractVisibleEntities(camera, cullFrustum, deltaTracker, this.levelRenderState);
profiler.popPush("blockEntities");
- this.extractVisibleBlockEntities(camera, worldPartialTicks, this.levelRenderState);
+ this.extractVisibleBlockEntities(camera, worldPartialTicks, this.levelRenderState, cullFrustum);
- this.extractVisibleBlockEntities(camera, deltaPartialTick, this.levelRenderState);
+ this.extractVisibleBlockEntities(camera, deltaPartialTick, this.levelRenderState, cullFrustum);
profiler.popPush("blockOutline");
this.extractBlockOutline(camera, this.levelRenderState);
profiler.popPush("blockBreaking");
@@ -311,7 +_,7 @@
@@ -264,7 +_,7 @@
return this.levelRenderer.entityRenderDispatcher().extractEntity(entity, partialTickTime);
}
@@ -18,15 +18,15 @@
Vec3 cameraPos = camera.position();
double camX = cameraPos.x();
double camY = cameraPos.y();
@@ -323,6 +_,7 @@
@@ -275,6 +_,7 @@
List<BlockEntity> renderableBlockEntities = section.getSectionMesh().getRenderableBlockEntities();
if (!renderableBlockEntities.isEmpty() && !(section.getVisibility(Util.getMillis(), chunkFadeDuration) < 0.3F)) {
if (!renderableBlockEntities.isEmpty() && !(section.getVisibility(Util.getMillis()) < 0.3F)) {
for (BlockEntity blockEntity : renderableBlockEntities) {
+ if (!frustum.isVisible(blockEntity.getRenderBoundingBox())) continue;
BlockPos blockPos = blockEntity.getBlockPos();
SortedSet<BlockDestructionProgress> progresses = this.level.destructionProgress().get(blockPos.asLong());
ModelFeatureRenderer.CrumblingOverlay breakProgress;
@@ -352,6 +_,7 @@
@@ -304,6 +_,7 @@
if (blockEntity.isRemoved()) {
iterator.remove();
} else {
@@ -34,7 +34,7 @@
BlockEntityRenderState state = this.levelRenderer
.blockEntityRenderDispatcher()
.tryExtractRenderState(blockEntity, deltaPartialTick, null, true);
@@ -375,7 +_,7 @@
@@ -327,7 +_,7 @@
SortedSet<BlockDestructionProgress> progresses = entry.getValue();
if (progresses != null && !progresses.isEmpty()) {
int progress = progresses.last().getProgress();
@@ -43,7 +43,7 @@
}
}
}
@@ -383,6 +_,12 @@
@@ -335,6 +_,12 @@
private void extractBlockOutline(final Camera camera, final LevelRenderState levelRenderState) {
levelRenderState.blockOutlineRenderState = null;
@@ -56,60 +56,3 @@
if (this.minecraft.hitResult instanceof BlockHitResult blockHitResult) {
if (blockHitResult.getType() != HitResult.Type.MISS) {
BlockPos pos = blockHitResult.getBlockPos();
@@ -444,24 +_,32 @@
}
if (!(camera.entity() instanceof LivingEntity livingEntity && livingEntity.isSleeping())) {
- BlockState viewBlockingState = getViewBlockingState(player, camera.getCullFrustum());
+ var overlay = getOverlayBlock(player, camera.getCullFrustum());
+ BlockState viewBlockingState = overlay == null ? null : overlay.state();
if (viewBlockingState != null) {
TextureAtlasSprite sprite = this.minecraft.getModelManager().getBlockStateModelSet().getParticleMaterial(viewBlockingState).sprite();
state.blockOverlay = new PlayerRenderState.BlockOverlay(
sprite.atlasLocation(), sprite.getU0(), sprite.getV0(), sprite.getU1(), sprite.getV1()
);
+ state.customBlockOverlay = net.minecraftforge.client.ForgeHooksClient.renderBlockOverlay(player, overlay.state(), overlay.pos());
}
if (this.minecraft.options.getCameraType().isFirstPerson()) {
state.isEyeInWater = player.isEyeInFluid(FluidTags.WATER);
state.isOnFire = player.isOnFire();
- if (state.isEyeInWater) {
+ if (state.isEyeInWater || !player.getEyeInFluidType().isAir()) {
BlockPos eyePos = BlockPos.containing(player.getEyePosition());
float brightness = Lightmap.getBrightness(player.level().dimensionType(), player.level().getMaxLocalRawBrightness(eyePos));
state.waterOverlay = new PlayerRenderState.WaterOverlay(
ARGB.colorFromFloat(0.1F, brightness, brightness, brightness), -player.getYRot() / 64.0F, player.getXRot() / 64.0F
);
+ if (state.isEyeInWater)
+ state.customFluidOverlay = net.minecraftforge.client.ForgeHooksClient.renderWaterOverlay(player, state);
+ else
+ state.customFluidOverlay = net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions.of(player.getEyeInFluidType()).renderOverlay(this.minecraft, state);
}
+ if (state.isOnFire)
+ state.customFireOverlay = net.minecraftforge.client.ForgeHooksClient.renderFireOverlay(player);
}
}
} else {
@@ -475,6 +_,12 @@
return null;
}
+ var ret = getOverlayBlock(player, frustum);
+ return ret == null ? null : ret.state();
+ }
+
+ private record OverlayInfo(BlockState state, BlockPos pos) {}
+ private static @Nullable OverlayInfo getOverlayBlock(final LocalPlayer player, final Frustum frustum) {
AABB nearPlaneBB = frustum.getNearPlaneBounds().move(player.getEyePosition());
BlockPos.MutableBlockPos testPos = new BlockPos.MutableBlockPos();
@@ -486,7 +_,7 @@
);
BlockState blockState = player.level().getBlockState(testPos);
if (blockState.getRenderShape() != RenderShape.INVISIBLE && blockState.isViewBlocking(player.level(), testPos, nearPlaneBB)) {
- return blockState;
+ return new OverlayInfo(blockState, testPos.immutable());
}
}
@@ -1,7 +1,7 @@
--- a/net/minecraft/client/renderer/fog/FogRenderer.java
+++ b/net/minecraft/client/renderer/fog/FogRenderer.java
@@ -154,6 +_,12 @@
fogBlue = Mth.lerp(brightenFactor, fogBlue, fogBlue * targetScale);
@@ -159,6 +_,12 @@
fogBlue = Mth.lerp(brightenFactor, fogBlue, fogBlue * scale);
}
+ var fogColor = net.minecraftforge.client.ForgeHooksClient.getFogColor(camera, partialTicks, level, renderDistance, darkenWorldAmount, fogRed, fogGreen, fogBlue);
@@ -13,7 +13,7 @@
dest.set(fogRed, fogGreen, fogBlue, 1.0F);
}
@@ -181,6 +_,7 @@
@@ -186,6 +_,7 @@
float renderDistanceFogSpan = Mth.clamp(renderDistanceInBlocks / 10.0F, 4.0F, 64.0F);
fog.renderDistanceStart = renderDistanceInBlocks - renderDistanceFogSpan;
fog.renderDistanceEnd = renderDistanceInBlocks;
@@ -1,15 +1,15 @@
--- a/net/minecraft/client/renderer/rendertype/RenderTypes.java
+++ b/net/minecraft/client/renderer/rendertype/RenderTypes.java
@@ -674,7 +_,7 @@
@@ -574,7 +_,7 @@
}
public static RenderType eyes(final Identifier texture) {
- return EYES.apply(texture);
public static RenderType text(final Identifier texture) {
- return TEXT.apply(texture);
+ return net.minecraftforge.client.ForgeRenderTypes.getText(texture);
}
public static RenderType breezeEyes(final Identifier texture) {
@@ -737,23 +_,23 @@
public static RenderType textBackground() {
@@ -582,19 +_,19 @@
}
public static RenderType textGrayscale(final Identifier texture) {
@@ -32,6 +32,10 @@
+ return net.minecraftforge.client.ForgeRenderTypes.getTextSeeThrough(texture);
}
public static RenderType textBackgroundSeeThrough() {
@@ -602,7 +_,7 @@
}
public static RenderType textGrayscaleSeeThrough(final Identifier texture) {
- return TEXT_GRAYSCALE_SEE_THROUGH.apply(texture);
+ return net.minecraftforge.client.ForgeRenderTypes.getTextGrayscaleSeeThrough(texture);
@@ -1,22 +0,0 @@
--- a/net/minecraft/client/renderer/state/level/PlayerRenderState.java
+++ b/net/minecraft/client/renderer/state/level/PlayerRenderState.java
@@ -24,12 +_,19 @@
public PlayerRenderState.@Nullable WaterOverlay waterOverlay;
public PlayerRenderState.@Nullable ItemActivationRenderState itemActivation;
+ public net.minecraftforge.client.@Nullable IRenderCallback customBlockOverlay;
+ public net.minecraftforge.client.@Nullable IRenderCallback customFluidOverlay;
+ public net.minecraftforge.client.@Nullable IRenderCallback customFireOverlay;
+
public void reset() {
this.hasPlayer = false;
this.avatarRenderState = null;
this.blockOverlay = null;
this.waterOverlay = null;
this.itemActivation = null;
+ this.customBlockOverlay = null;
+ this.customFluidOverlay = null;
+ this.customFireOverlay = null;
}
@OnlyIn(Dist.CLIENT)
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/renderer/texture/TextureAtlasSprite.java
+++ b/net/minecraft/client/renderer/texture/TextureAtlasSprite.java
@@ -24,7 +_,7 @@
@@ -26,7 +_,7 @@
private final float v1;
private final int padding;
@@ -9,7 +9,7 @@
final Identifier atlasLocation, final SpriteContents contents, final int atlasWidth, final int atlasHeight, final int x, final int y, final int padding
) {
this.atlasLocation = atlasLocation;
@@ -123,5 +_,14 @@
@@ -127,5 +_,14 @@
@Override
public void close() {
this.contents.close();
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/resources/language/ClientLanguage.java
+++ b/net/minecraft/client/resources/language/ClientLanguage.java
@@ -83,4 +_,9 @@
@@ -78,4 +_,9 @@
public FormattedCharSequence getVisualOrder(final FormattedText logicalOrderText) {
return FormattedBidiReorder.reorder(logicalOrderText, this.defaultRightToLeft);
}
@@ -1,17 +1,17 @@
--- a/net/minecraft/client/resources/language/LanguageManager.java
+++ b/net/minecraft/client/resources/language/LanguageManager.java
@@ -34,8 +_,8 @@
@@ -29,8 +_,8 @@
private final Consumer<ClientLanguage> reloadCallback;
public LanguageManager(final Minecraft minecraft, final String languageCode, final Consumer<ClientLanguage> reloadCallback) {
this.minecraft = minecraft;
public LanguageManager(final String languageCode, final Consumer<ClientLanguage> reloadCallback) {
- this.currentCode = languageCode;
this.reloadCallback = reloadCallback;
+ setSelected(languageCode);
}
private static Map<String, LanguageInfo> extractLanguages(final Stream<PackResources> resourcePacks) {
@@ -86,8 +_,12 @@
}
@@ -67,8 +_,12 @@
this.reloadCallback.accept(locale);
}
+ private java.util.Locale javaLocale; // Forge: add locale information for modders
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/resources/model/ModelManager.java
+++ b/net/minecraft/client/resources/model/ModelManager.java
@@ -60,6 +_,7 @@
@@ -61,6 +_,7 @@
private static final Logger LOGGER = LogUtils.getLogger();
private static final FileToIdConverter MODEL_LISTER = FileToIdConverter.json("models");
private Map<Identifier, ItemModel> bakedItemStackModels = Map.of();
@@ -8,7 +8,7 @@
private Map<Identifier, ClientItem.Properties> itemProperties = Map.of();
private final AtlasManager atlasManager;
private final PlayerSkinRenderCache playerSkinRenderCache;
@@ -70,6 +_,7 @@
@@ -71,6 +_,7 @@
private @Nullable BlockModelSet blockModelSet;
private @Nullable FluidStateModelSet fluidStateModelSet;
private Object2IntMap<BlockState> modelGroups = Object2IntMaps.emptyMap();
@@ -16,7 +16,7 @@
public ModelManager(final BlockColors blockColors, final AtlasManager atlasManager, final PlayerSkinRenderCache playerSkinRenderCache) {
this.blockColors = blockColors;
@@ -81,6 +_,18 @@
@@ -82,6 +_,18 @@
return this.bakedItemStackModels.getOrDefault(id, this.missingModels.item());
}
@@ -35,7 +35,7 @@
public ClientItem.Properties getItemProperties(final Identifier id) {
return this.itemProperties.getOrDefault(id, ClientItem.Properties.DEFAULT);
}
@@ -104,6 +_,7 @@
@@ -105,6 +_,7 @@
final PreparableReloadListener.PreparationBarrier preparationBarrier,
final Executor reloadExecutor
) {
@@ -43,13 +43,13 @@
ResourceManager manager = currentReload.resourceManager();
CompletableFuture<EntityModelSet> entityModelSet = CompletableFuture.supplyAsync(EntityModelSet::vanilla, taskExecutor);
CompletableFuture<Map<Identifier, UnbakedModel>> modelCache = loadBlockModels(manager, taskExecutor);
@@ -221,12 +_,14 @@
bakedModelsFuture,
@@ -224,12 +_,14 @@
(bakingResult, bakedModels) -> {
Map<Fluid, FluidModel> fluidModels = FluidStateModelSet.bake(materialBaker);
+ fluidModels = net.minecraftforge.client.ForgeHooksClient.onFluidModelBake(bakery, materialBaker, fluidModels);
blockItemMaterialBaker.logMissingTextures();
Map<Fluid, FluidModel> fluidModels = FluidStateModelSet.bake(blockOnlyMaterialBaker);
+ fluidModels = net.minecraftforge.client.ForgeHooksClient.onFluidModelBake(bakery, blockOnlyMaterialBaker, fluidModels);
+ net.minecraftforge.client.ForgeHooksClient.onModifyBakingResult(bakery, bakingResult);
materialBaker.logMissingTextures();
blockOnlyMaterialBaker.logMissingTextures();
Map<BlockState, BlockStateModel> modelByStateCache = createBlockStateToModelDispatch(
bakingResult.blockStateModels(), bakingResult.missingModels().block()
);
@@ -59,7 +59,7 @@
);
}
);
@@ -258,10 +_,15 @@
@@ -261,10 +_,15 @@
private void apply(final ModelManager.ReloadState preparations) {
ModelBakery.BakingResult bakedModels = preparations.bakedModels;
@@ -75,7 +75,7 @@
this.blockStateModelSet = new BlockStateModelSet(preparations.blockStateModels, this.missingModels.block());
this.blockModelSet = new BlockModelSet(this.blockStateModelSet, preparations.blockModels, this.blockColors);
this.fluidStateModelSet = new FluidStateModelSet(preparations.fluidModels, this.missingModels.fluid());
@@ -297,7 +_,8 @@
@@ -333,7 +_,8 @@
Map<BlockState, BlockStateModel> blockStateModels,
Map<BlockState, BlockModel> blockModels,
Map<Fluid, FluidModel> fluidModels,
@@ -29,9 +29,9 @@
- Material.Baked material = modelBaker.materials().resolveSlot(textures, face.texture(), name);
+ Material.Baked material = materialMapper.apply(face.texture());
BakedQuad quad = FaceBakery.bakeQuad(
modelBaker,
from,
@@ -85,7 +_,5 @@
modelBaker, from, to, face, material, facing, modelState, element.rotation(), element.shade(), element.lightEmission()
);
@@ -76,7 +_,5 @@
}
}
}
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/resources/sounds/SoundInstance.java
+++ b/net/minecraft/client/resources/sounds/SoundInstance.java
@@ -56,4 +_,8 @@
@@ -54,4 +_,8 @@
NONE,
LINEAR;
}
@@ -15,7 +15,7 @@
}
@Override
@@ -397,6 +_,7 @@
@@ -371,6 +_,7 @@
@Override
public void halt(final boolean wait) {
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/sounds/SoundEngine.java
+++ b/net/minecraft/client/sounds/SoundEngine.java
@@ -83,6 +_,7 @@
@@ -82,6 +_,7 @@
this.options = options;
this.soundBuffers = new SoundBufferLibrary(resourceProvider);
this.lastSeenDevices = this.deviceTracker.currentDevices();
@@ -8,7 +8,7 @@
}
public void reload() {
@@ -100,6 +_,7 @@
@@ -99,6 +_,7 @@
this.destroy();
this.loadLibrary();
@@ -16,30 +16,28 @@
}
private synchronized void loadLibrary() {
@@ -363,15 +_,18 @@
@@ -340,7 +_,7 @@
}
}
- public SoundEngine.PlayResult play(final SoundInstance instance) {
+ public SoundEngine.PlayResult play(final SoundInstance instanceArg) {
+ public SoundEngine.PlayResult play(SoundInstance instance) {
if (!this.loaded) {
return SoundEngine.PlayResult.NOT_STARTED;
}
- if (!instance.canPlaySound()) {
+ if (!instanceArg.canPlaySound()) {
@@ -349,6 +_,9 @@
return SoundEngine.PlayResult.NOT_STARTED;
}
+ final var instance = net.minecraftforge.client.ForgeHooksClient.playSound(this, instanceArg);
+ instance = net.minecraftforge.client.ForgeHooksClient.playSound(this, instance);
+ if (instance == null || !instance.canPlaySound())
+ return SoundEngine.PlayResult.NOT_STARTED;
WeighedSoundEvents soundEvent = instance.getOrResolve(this.soundManager);
WeighedSoundEvents soundEvent = instance.resolve(this.soundManager);
Identifier eventLocation = instance.getIdentifier();
if (soundEvent == null) {
@@ -447,15 +_,18 @@
@@ -430,15 +_,18 @@
channel.setSelfPosition(position);
channel.setRelative(instance.isRelative());
channel.setRelative(isRelative);
});
+ SoundInstance soundinstance = instance;
if (!isStreaming) {
Loaded 100 of 620 files, more files were not shown because too many files have changed in this diff. Show more