mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-14 09:05:17 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4f2f5c02a0 | ||
|
|
7a6843fa4a | ||
|
|
f0ecf16c6b | ||
|
|
8998fa71b2 | ||
|
|
4e677a7558 | ||
|
|
07254b36d7 | ||
|
|
a51b8d256d | ||
|
|
75fcd9448e | ||
|
|
6b45999702 | ||
|
|
a4f52f4057 | ||
|
|
b8b3201372 | ||
|
|
41deadc1e2 | ||
|
|
82e8d06e54 | ||
|
|
51db5f2ff7 | ||
|
|
2ec9e515ff | ||
|
|
0579572148 | ||
|
|
83f4e6353c | ||
|
|
130953e519 | ||
|
|
7981093591 | ||
|
|
79112d6208 | ||
|
|
a3eb6263f4 | ||
|
|
d91bc9c73d | ||
|
|
c807665ab9 | ||
|
|
7b97c181b9 | ||
|
|
c42b0847d2 | ||
|
|
f182cb00c1 | ||
|
|
3181b5da23 | ||
|
|
983c119477 | ||
|
|
874ff1bba2 | ||
|
|
06d9d89f98 | ||
|
|
c713bad8c3 | ||
|
|
fe19491822 | ||
|
|
c80e8a1aca |
No files matched your search
+8
-6
@@ -36,14 +36,14 @@ ext {
|
||||
]
|
||||
}
|
||||
MAPPING_CHANNEL = 'official'
|
||||
MAPPING_VERSION = '1.19.1'
|
||||
MC_VERSION = '1.19.1'
|
||||
MAPPING_VERSION = '1.19.2'
|
||||
MC_VERSION = '1.19.2'
|
||||
MC_NEXT_VERSION = '1.20'
|
||||
MCP_VERSION = '20220727.212338'
|
||||
MCP_VERSION = '20220805.130853'
|
||||
SPI_VERSION = '6.0.0'
|
||||
ACCESSTRANSFORMERS_VERSION = '8.0.4'
|
||||
COREMODS_VERSION = '5.0.1'
|
||||
EVENTBUS_VERSION = '6.0.0'
|
||||
EVENTBUS_VERSION = '6.0.3'
|
||||
MODLAUNCHER_VERSION = '10.0.8'
|
||||
SECUREJARHANDLER_VERSION = '2.1.4'
|
||||
BOOTSTRAPLAUNCHER_VERSION = '1.1.2'
|
||||
@@ -66,7 +66,7 @@ ext {
|
||||
APACHE_COMMONS_LANG3_VERSION = '3.12.0'
|
||||
JOPT_SIMPLE_VERSION = '5.0.4'
|
||||
COMMONS_IO_VERSION = '2.11.0'
|
||||
JARJAR_VERSION = '0.3.9'
|
||||
JARJAR_VERSION = '0.3.16'
|
||||
|
||||
GIT_INFO = gradleutils.gitInfo
|
||||
VERSION = gradleutils.getFilteredMCTagOffsetBranchVersion(true, '[0-9]', MC_VERSION)
|
||||
@@ -262,6 +262,7 @@ def sharedDeps = {
|
||||
moduleonly "org.ow2.asm:asm-util:${ASM_VERSION}"
|
||||
moduleonly "org.ow2.asm:asm-analysis:${ASM_VERSION}"
|
||||
moduleonly "cpw.mods:bootstraplauncher:${BOOTSTRAPLAUNCHER_VERSION}"
|
||||
moduleonly "net.minecraftforge:JarJarFileSystems:${JARJAR_VERSION}"
|
||||
|
||||
installer "cpw.mods:securejarhandler:${SECUREJARHANDLER_VERSION}"
|
||||
installer "org.ow2.asm:asm:${ASM_VERSION}"
|
||||
@@ -285,7 +286,8 @@ def sharedDeps = {
|
||||
installer "org.jline:jline-terminal:${JLINE_VERSION}" // Dep of TerminalConsoleAppender
|
||||
installer "org.spongepowered:mixin:${MIXIN_VERSION}"
|
||||
installer 'org.openjdk.nashorn:nashorn-core:15.3'
|
||||
installer "net.minecraftforge:JarJar:${JARJAR_VERSION}"
|
||||
installer "net.minecraftforge:JarJarSelector:${JARJAR_VERSION}"
|
||||
installer "net.minecraftforge:JarJarMetadata:${JARJAR_VERSION}"
|
||||
|
||||
/*
|
||||
installer 'org.lwjgl:lwjgl:3.2.2'
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
MinecraftForge
|
||||
=============
|
||||
[](https://files.minecraftforge.net)
|
||||
[](https://files.minecraftforge.net)
|
||||
[](https://files.minecraftforge.net) [](https://discord.gg/UvedJ9m) [](https://www.patreon.com/LexManos)
|
||||
|
||||
Forge is a free, open-source modding API all of your favourite mods use!
|
||||
|
||||
@@ -28,7 +28,8 @@ dependencies {
|
||||
api("cpw.mods:modlauncher:${MODLAUNCHER_VERSION}")
|
||||
api("net.minecraftforge:coremods:${COREMODS_VERSION}")
|
||||
api("com.mojang:logging:${MOJANG_LOGGING_VERSION}")
|
||||
api "net.minecraftforge:JarJar:${JARJAR_VERSION}"
|
||||
api "net.minecraftforge:JarJarSelector:${JARJAR_VERSION}"
|
||||
api "net.minecraftforge:JarJarMetadata:${JARJAR_VERSION}"
|
||||
|
||||
implementation("net.sf.jopt-simple:jopt-simple:${JOPT_SIMPLE_VERSION}")
|
||||
implementation("cpw.mods:securejarhandler:${SECUREJARHANDLER_VERSION}")
|
||||
|
||||
@@ -106,16 +106,17 @@ public class UniqueModListBuilder
|
||||
if (modInfoList.size() > 1) {
|
||||
LOGGER.debug("Found {} mods for first modid {}, selecting most recent based on version data", modInfoList.size(), fullList.getKey());
|
||||
modInfoList.sort(Comparator.comparing(this::getVersion).reversed());
|
||||
LOGGER.debug("Selected file {} for modid {} with version {}", modInfoList.get(0).getFileName(), fullList.getKey(), modInfoList.get(0).getModInfos().get(0).getVersion());
|
||||
LOGGER.debug("Selected file {} for modid {} with version {}", modInfoList.get(0).getFileName(), fullList.getKey(), this.getVersion(modInfoList.get(0)));
|
||||
}
|
||||
return modInfoList.get(0);
|
||||
}
|
||||
|
||||
private ArtifactVersion getVersion(final ModFile mf)
|
||||
{
|
||||
if (mf.getModFileInfo() == null) {
|
||||
if (mf.getModFileInfo() == null || mf.getModInfos() == null || mf.getModInfos().isEmpty()) {
|
||||
return mf.getJarVersion();
|
||||
}
|
||||
|
||||
return mf.getModInfos().get(0).getVersion();
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
package net.minecraftforge.fml.loading;
|
||||
|
||||
import net.minecraftforge.forgespi.language.MavenVersionAdapter;
|
||||
import org.apache.maven.artifact.versioning.ArtifactVersion;
|
||||
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
|
||||
import org.apache.maven.artifact.versioning.VersionRange;
|
||||
@@ -18,16 +19,12 @@ public class VersionSupportMatrix {
|
||||
private static final HashMap<String, List<ArtifactVersion>> overrideVersions = new HashMap<>();
|
||||
static {
|
||||
final ArtifactVersion version = new DefaultArtifactVersion(FMLLoader.versionInfo().mcVersion());
|
||||
// if (MavenVersionAdapter.createFromVersionSpec("[1.16.4,1.16.5]").containsVersion(version)) {
|
||||
// // 1.16.4 is Compatible with 1.16.3
|
||||
// add("languageloader.javafml", "34");
|
||||
// add("mod.minecraft", "1.16.3");
|
||||
// add("mod.forge", "34.1.42");
|
||||
// // 1.16.5 is Compatible with 1.16.4, and thus 1.16.3
|
||||
// add("languageloader.javafml", "35");
|
||||
// add("mod.minecraft", "1.16.4");
|
||||
// add("mod.forge", "35.1.37");
|
||||
// }
|
||||
if (MavenVersionAdapter.createFromVersionSpec("[1.19.2]").containsVersion(version)) {
|
||||
// 1.19.2 is Compatible with 1.19.1
|
||||
add("languageloader.javafml", "42");
|
||||
add("mod.minecraft", "1.19.1");
|
||||
add("mod.forge", "42.0.9");
|
||||
}
|
||||
}
|
||||
private static void add(String key, String value) {
|
||||
overrideVersions.computeIfAbsent(key, k -> new ArrayList<>()).add(new DefaultArtifactVersion(value));
|
||||
|
||||
-1
@@ -46,7 +46,6 @@ public class JarInJarDependencyLocator extends AbstractJarFileDependencyLocator
|
||||
final List<IModFile> sources = Lists.newArrayList();
|
||||
loadedMods.forEach(sources::add);
|
||||
|
||||
|
||||
final List<IModFile> dependenciesToLoad = JarSelector.detectAndSelect(sources, this::loadResourceFromModFile, this::loadModFileFrom, this::identifyMod, this::exception);
|
||||
|
||||
if (dependenciesToLoad.isEmpty())
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ public class FMLModContainer extends ModContainer
|
||||
LOGGER.debug(LOADING,"Creating FMLModContainer instance for {}", className);
|
||||
this.scanResults = modFileScanResults;
|
||||
activityMap.put(ModLoadingStage.CONSTRUCT, this::constructMod);
|
||||
this.eventBus = BusBuilder.builder().setExceptionHandler(this::onEventFailed).setTrackPhases(false).markerType(IModBusEvent.class).build();
|
||||
this.eventBus = BusBuilder.builder().setExceptionHandler(this::onEventFailed).setTrackPhases(false).markerType(IModBusEvent.class).useModLauncher().build();
|
||||
this.configHandler = Optional.of(ce->this.eventBus.post(ce.self()));
|
||||
final FMLJavaModLoadingContext contextExtension = new FMLJavaModLoadingContext(this);
|
||||
this.contextExtension = () -> contextExtension;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/client/Minecraft.java
|
||||
+++ b/net/minecraft/client/Minecraft.java
|
||||
@@ -243,7 +_,7 @@
|
||||
@@ -244,7 +_,7 @@
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
@@ -9,7 +9,7 @@
|
||||
static Minecraft f_90981_;
|
||||
private static final Logger f_90982_ = LogUtils.getLogger();
|
||||
public static final boolean f_91002_ = Util.m_137581_() == Util.OS.OSX;
|
||||
@@ -397,7 +_,7 @@
|
||||
@@ -398,7 +_,7 @@
|
||||
this.f_91029_ = p_91084_.f_101908_.f_101928_;
|
||||
this.f_90986_ = p_91084_.f_101905_.f_101944_;
|
||||
this.f_91037_ = new ClientPackSource(new File(this.f_91069_, "server-resource-packs"), p_91084_.f_101907_.m_101925_());
|
||||
@@ -18,7 +18,7 @@
|
||||
this.f_91030_ = p_91084_.f_101905_.f_101945_;
|
||||
this.f_231338_ = new YggdrasilAuthenticationService(this.f_91030_);
|
||||
this.f_91048_ = this.f_231338_.createMinecraftSessionService();
|
||||
@@ -405,7 +_,6 @@
|
||||
@@ -406,7 +_,6 @@
|
||||
this.f_231339_ = SignatureValidator.m_216358_(this.f_231338_.getServicesKey());
|
||||
this.f_90998_ = p_91084_.f_101905_.f_101942_;
|
||||
f_90982_.info("Setting user: {}", (Object)this.f_90998_.m_92546_());
|
||||
@@ -26,7 +26,7 @@
|
||||
this.f_91033_ = p_91084_.f_101908_.f_101926_;
|
||||
this.f_91034_ = !p_91084_.f_101908_.f_101929_;
|
||||
this.f_91035_ = !p_91084_.f_101908_.f_101930_;
|
||||
@@ -457,7 +_,7 @@
|
||||
@@ -458,7 +_,7 @@
|
||||
|
||||
this.f_90990_.m_85380_(this.f_91066_.m_232035_().m_231551_());
|
||||
this.f_91067_ = new MouseHandler(this);
|
||||
@@ -35,7 +35,7 @@
|
||||
this.f_91068_ = new KeyboardHandler(this);
|
||||
this.f_91068_.m_90887_(this.f_90990_.m_85439_());
|
||||
RenderSystem.m_69580_(this.f_91066_.f_92035_, false);
|
||||
@@ -465,6 +_,7 @@
|
||||
@@ -466,6 +_,7 @@
|
||||
this.f_91042_.m_83931_(0.0F, 0.0F, 0.0F, 0.0F);
|
||||
this.f_91042_.m_83954_(f_91002_);
|
||||
this.f_91036_ = new ReloadableResourceManager(PackType.CLIENT_RESOURCES);
|
||||
@@ -43,7 +43,7 @@
|
||||
this.f_91038_.m_10506_();
|
||||
this.f_91066_.m_92145_(this.f_91038_);
|
||||
this.f_91039_ = new LanguageManager(this.f_91066_.f_92075_);
|
||||
@@ -509,10 +_,12 @@
|
||||
@@ -510,10 +_,12 @@
|
||||
this.f_91063_ = new GameRenderer(this, this.f_90994_.m_234586_(), this.f_91036_, this.f_90993_);
|
||||
this.f_91036_.m_7217_(this.f_91063_);
|
||||
this.f_91060_ = new LevelRenderer(this, this.f_90994_, this.f_167845_, this.f_90993_);
|
||||
@@ -56,7 +56,7 @@
|
||||
this.f_91036_.m_7217_(this.f_91061_);
|
||||
this.f_91053_ = new PaintingTextureManager(this.f_90987_);
|
||||
this.f_91036_.m_7217_(this.f_91053_);
|
||||
@@ -521,7 +_,9 @@
|
||||
@@ -522,7 +_,9 @@
|
||||
this.f_91047_ = new GpuWarnlistManager();
|
||||
this.f_91036_.m_7217_(this.f_91047_);
|
||||
this.f_91036_.m_7217_(this.f_205120_);
|
||||
@@ -67,7 +67,7 @@
|
||||
this.f_91064_ = new DebugRenderer(this);
|
||||
this.f_238717_ = new RealmsDataFetcher(RealmsClient.m_239151_(this));
|
||||
RenderSystem.m_69900_(this::m_91113_);
|
||||
@@ -540,6 +_,19 @@
|
||||
@@ -541,6 +_,21 @@
|
||||
TinyFileDialogs.tinyfd_messageBox("Minecraft", stringbuilder.toString(), "ok", "error", false);
|
||||
}
|
||||
|
||||
@@ -83,11 +83,13 @@
|
||||
+ net.minecraftforge.client.gui.overlay.GuiOverlayManager.init();
|
||||
+ net.minecraftforge.client.DimensionSpecialEffectsManager.init();
|
||||
+ net.minecraftforge.client.NamedRenderTypeManager.init();
|
||||
+ net.minecraftforge.client.ColorResolverManager.init();
|
||||
+ net.minecraftforge.client.ItemDecoratorHandler.init();
|
||||
+
|
||||
this.f_90990_.m_85409_(this.f_91066_.m_231817_().m_231551_());
|
||||
this.f_90990_.m_85424_(this.f_91066_.m_232123_().m_231551_());
|
||||
this.f_90990_.m_85426_();
|
||||
@@ -562,23 +_,23 @@
|
||||
@@ -563,23 +_,23 @@
|
||||
}
|
||||
|
||||
this.f_167847_.m_168556_();
|
||||
@@ -126,7 +128,7 @@
|
||||
|
||||
}
|
||||
|
||||
@@ -621,6 +_,8 @@
|
||||
@@ -622,6 +_,8 @@
|
||||
|
||||
private UserApiService m_193585_(YggdrasilAuthenticationService p_193586_, GameConfig p_193587_) {
|
||||
try {
|
||||
@@ -135,7 +137,7 @@
|
||||
return p_193586_.createUserApiService(p_193587_.f_101905_.f_101942_.m_92547_());
|
||||
} catch (AuthenticationException authenticationexception) {
|
||||
f_90982_.error("Failed to verify authentication", (Throwable)authenticationexception);
|
||||
@@ -633,7 +_,7 @@
|
||||
@@ -634,7 +_,7 @@
|
||||
}
|
||||
|
||||
private void m_91239_(Throwable p_91240_) {
|
||||
@@ -144,7 +146,7 @@
|
||||
this.m_91241_(p_91240_, (Component)null);
|
||||
} else {
|
||||
Util.m_137559_(p_91240_);
|
||||
@@ -791,13 +_,13 @@
|
||||
@@ -792,13 +_,13 @@
|
||||
Bootstrap.m_135875_(p_91333_.m_127526_());
|
||||
if (p_91333_.m_127527_() != null) {
|
||||
Bootstrap.m_135875_("#@!@# Game crashed! Crash report saved to: #@!@# " + p_91333_.m_127527_());
|
||||
@@ -161,7 +163,7 @@
|
||||
}
|
||||
|
||||
}
|
||||
@@ -921,10 +_,6 @@
|
||||
@@ -922,10 +_,6 @@
|
||||
f_90982_.error("setScreen called from non-game thread");
|
||||
}
|
||||
|
||||
@@ -172,7 +174,7 @@
|
||||
if (p_91153_ == null && this.f_91073_ == null) {
|
||||
p_91153_ = new TitleScreen();
|
||||
} else if (p_91153_ == null && this.f_91074_.m_21224_()) {
|
||||
@@ -935,6 +_,19 @@
|
||||
@@ -936,6 +_,19 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,7 +194,7 @@
|
||||
this.f_91080_ = p_91153_;
|
||||
BufferUploader.m_166835_();
|
||||
if (p_91153_ != null) {
|
||||
@@ -1078,11 +_,14 @@
|
||||
@@ -1079,11 +_,14 @@
|
||||
RenderSystem.m_69481_();
|
||||
this.f_91026_.m_7238_();
|
||||
if (!this.f_91079_) {
|
||||
@@ -207,7 +209,7 @@
|
||||
}
|
||||
|
||||
if (this.f_91056_ != null) {
|
||||
@@ -1209,10 +_,12 @@
|
||||
@@ -1210,10 +_,12 @@
|
||||
this.f_90990_.m_85378_((double)i);
|
||||
if (this.f_91080_ != null) {
|
||||
this.f_91080_.m_6574_(this, this.f_90990_.m_85445_(), this.f_90990_.m_85446_());
|
||||
@@ -220,7 +222,7 @@
|
||||
this.f_91063_.m_109097_(this.f_90990_.m_85441_(), this.f_90990_.m_85442_());
|
||||
this.f_91067_.m_91599_();
|
||||
}
|
||||
@@ -1490,6 +_,7 @@
|
||||
@@ -1491,6 +_,7 @@
|
||||
}
|
||||
|
||||
public void m_91395_() {
|
||||
@@ -228,7 +230,7 @@
|
||||
this.f_91019_ = false;
|
||||
}
|
||||
|
||||
@@ -1519,10 +_,18 @@
|
||||
@@ -1520,10 +_,18 @@
|
||||
if (p_91387_ && this.f_91077_ != null && this.f_91077_.m_6662_() == HitResult.Type.BLOCK) {
|
||||
BlockHitResult blockhitresult = (BlockHitResult)this.f_91077_;
|
||||
BlockPos blockpos = blockhitresult.m_82425_();
|
||||
@@ -250,7 +252,7 @@
|
||||
this.f_91074_.m_6674_(InteractionHand.MAIN_HAND);
|
||||
}
|
||||
}
|
||||
@@ -1547,14 +_,20 @@
|
||||
@@ -1548,14 +_,20 @@
|
||||
return false;
|
||||
} else {
|
||||
boolean flag = false;
|
||||
@@ -269,22 +271,22 @@
|
||||
BlockHitResult blockhitresult = (BlockHitResult)this.f_91077_;
|
||||
BlockPos blockpos = blockhitresult.m_82425_();
|
||||
- if (!this.f_91073_.m_8055_(blockpos).m_60795_()) {
|
||||
+ if (!this.f_91073_.m_46859_(blockpos)) {
|
||||
+ if (!this.f_91073_.m_46859_(blockpos)) {
|
||||
this.f_91072_.m_105269_(blockpos, blockhitresult.m_82434_());
|
||||
if (this.f_91073_.m_8055_(blockpos).m_60795_()) {
|
||||
flag = true;
|
||||
@@ -1567,8 +_,10 @@
|
||||
@@ -1568,8 +_,10 @@
|
||||
}
|
||||
|
||||
this.f_91074_.m_36334_();
|
||||
+ net.minecraftforge.common.ForgeHooks.onEmptyLeftClick(this.f_91074_);
|
||||
+ net.minecraftforge.common.ForgeHooks.onEmptyLeftClick(this.f_91074_);
|
||||
}
|
||||
|
||||
+ if (inputEvent.shouldSwingHand())
|
||||
this.f_91074_.m_6674_(InteractionHand.MAIN_HAND);
|
||||
return flag;
|
||||
}
|
||||
@@ -1583,6 +_,11 @@
|
||||
@@ -1584,6 +_,11 @@
|
||||
}
|
||||
|
||||
for(InteractionHand interactionhand : InteractionHand.values()) {
|
||||
@@ -296,31 +298,32 @@
|
||||
ItemStack itemstack = this.f_91074_.m_21120_(interactionhand);
|
||||
if (this.f_91077_ != null) {
|
||||
switch (this.f_91077_.m_6662_()) {
|
||||
@@ -1593,6 +_,7 @@
|
||||
@@ -1594,13 +_,14 @@
|
||||
return;
|
||||
}
|
||||
|
||||
+ if(!this.f_91074_.canInteractWith(entityhitresult.m_82443_(), 0)) return; //Forge: Entity may be traced via attack range, but the player may not have sufficient reach. No padding in client code.
|
||||
+ if(!this.f_91074_.canInteractWith(entityhitresult.m_82443_(), 0)) return; //Forge: Entity may be traced via attack range, but the player may not have sufficient reach. No padding in client code.
|
||||
InteractionResult interactionresult = this.f_91072_.m_105230_(this.f_91074_, entity, entityhitresult, interactionhand);
|
||||
if (!interactionresult.m_19077_()) {
|
||||
interactionresult = this.f_91072_.m_105226_(this.f_91074_, entity, interactionhand);
|
||||
@@ -1600,6 +_,7 @@
|
||||
}
|
||||
|
||||
if (interactionresult.m_19077_()) {
|
||||
if (interactionresult.m_19080_()) {
|
||||
+ if (inputEvent.shouldSwingHand())
|
||||
- if (interactionresult.m_19080_()) {
|
||||
+ if (interactionresult.m_19080_() && inputEvent.shouldSwingHand()) {
|
||||
this.f_91074_.m_6674_(interactionhand);
|
||||
}
|
||||
|
||||
@@ -1612,6 +_,7 @@
|
||||
@@ -1612,7 +_,7 @@
|
||||
int i = itemstack.m_41613_();
|
||||
InteractionResult interactionresult1 = this.f_91072_.m_233732_(this.f_91074_, interactionhand, blockhitresult);
|
||||
if (interactionresult1.m_19077_()) {
|
||||
if (interactionresult1.m_19080_()) {
|
||||
+ if (inputEvent.shouldSwingHand())
|
||||
- if (interactionresult1.m_19080_()) {
|
||||
+ if (interactionresult1.m_19080_() && inputEvent.shouldSwingHand()) {
|
||||
this.f_91074_.m_6674_(interactionhand);
|
||||
if (!itemstack.m_41619_() && (itemstack.m_41613_() != i || this.f_91072_.m_105290_())) {
|
||||
this.f_91063_.f_109055_.m_109320_(interactionhand);
|
||||
@@ -1627,6 +_,9 @@
|
||||
@@ -1628,6 +_,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -330,7 +333,7 @@
|
||||
if (!itemstack.m_41619_()) {
|
||||
InteractionResult interactionresult2 = this.f_91072_.m_233721_(this.f_91074_, interactionhand);
|
||||
if (interactionresult2.m_19077_()) {
|
||||
@@ -1653,6 +_,8 @@
|
||||
@@ -1654,6 +_,8 @@
|
||||
--this.f_91011_;
|
||||
}
|
||||
|
||||
@@ -339,7 +342,7 @@
|
||||
this.f_91026_.m_6180_("gui");
|
||||
this.f_240378_.m_240688_();
|
||||
this.f_91065_.m_193832_(this.f_91012_);
|
||||
@@ -1782,6 +_,8 @@
|
||||
@@ -1783,6 +_,8 @@
|
||||
this.f_91026_.m_6182_("keyboard");
|
||||
this.f_91068_.m_90931_();
|
||||
this.f_91026_.m_7238_();
|
||||
@@ -348,7 +351,7 @@
|
||||
}
|
||||
|
||||
private boolean m_91278_() {
|
||||
@@ -1976,6 +_,7 @@
|
||||
@@ -1978,6 +_,7 @@
|
||||
}
|
||||
|
||||
public void m_91156_(ClientLevel p_91157_) {
|
||||
@@ -356,7 +359,7 @@
|
||||
ProgressScreen progressscreen = new ProgressScreen(true);
|
||||
progressscreen.m_6309_(Component.m_237115_("connect.joining"));
|
||||
this.m_91362_(progressscreen);
|
||||
@@ -2009,10 +_,12 @@
|
||||
@@ -2011,10 +_,12 @@
|
||||
IntegratedServer integratedserver = this.f_91007_;
|
||||
this.f_91007_ = null;
|
||||
this.f_91063_.m_109150_();
|
||||
@@ -369,7 +372,7 @@
|
||||
if (integratedserver != null) {
|
||||
this.f_91026_.m_6180_("waitForServer");
|
||||
|
||||
@@ -2027,6 +_,7 @@
|
||||
@@ -2029,6 +_,7 @@
|
||||
this.f_91065_.m_93089_();
|
||||
this.f_91008_ = null;
|
||||
this.f_91010_ = false;
|
||||
@@ -377,7 +380,7 @@
|
||||
this.f_91004_.m_90740_();
|
||||
}
|
||||
|
||||
@@ -2122,6 +_,7 @@
|
||||
@@ -2124,6 +_,7 @@
|
||||
|
||||
private void m_91280_() {
|
||||
if (this.f_91077_ != null && this.f_91077_.m_6662_() != HitResult.Type.MISS) {
|
||||
@@ -385,7 +388,7 @@
|
||||
boolean flag = this.f_91074_.m_150110_().f_35937_;
|
||||
BlockEntity blockentity = null;
|
||||
HitResult.Type hitresult$type = this.f_91077_.m_6662_();
|
||||
@@ -2134,10 +_,7 @@
|
||||
@@ -2136,10 +_,7 @@
|
||||
}
|
||||
|
||||
Block block = blockstate.m_60734_();
|
||||
@@ -397,7 +400,7 @@
|
||||
|
||||
if (flag && Screen.m_96637_() && blockstate.m_155947_()) {
|
||||
blockentity = this.f_91073_.m_7702_(blockpos);
|
||||
@@ -2148,7 +_,7 @@
|
||||
@@ -2150,7 +_,7 @@
|
||||
}
|
||||
|
||||
Entity entity = ((EntityHitResult)this.f_91077_).m_82443_();
|
||||
@@ -406,7 +409,7 @@
|
||||
if (itemstack == null) {
|
||||
return;
|
||||
}
|
||||
@@ -2686,8 +_,8 @@
|
||||
@@ -2688,8 +_,8 @@
|
||||
return this.f_90993_;
|
||||
}
|
||||
|
||||
@@ -417,7 +420,7 @@
|
||||
Supplier<PackResources> supplier = p_167937_;
|
||||
if (i <= 3) {
|
||||
supplier = m_91330_(p_167937_);
|
||||
@@ -2697,7 +_,7 @@
|
||||
@@ -2699,7 +_,7 @@
|
||||
supplier = m_91352_(supplier);
|
||||
}
|
||||
|
||||
@@ -426,10 +429,12 @@
|
||||
}
|
||||
|
||||
private static Supplier<PackResources> m_91330_(Supplier<PackResources> p_91331_) {
|
||||
@@ -2716,6 +_,14 @@
|
||||
this.f_91051_.m_119410_(p_91313_);
|
||||
}
|
||||
@@ -2716,6 +_,19 @@
|
||||
|
||||
public void m_91312_(int p_91313_) {
|
||||
this.f_91051_.m_119410_(p_91313_);
|
||||
+ }
|
||||
+
|
||||
+ public ItemColors getItemColors() {
|
||||
+ return this.f_91041_;
|
||||
+ }
|
||||
@@ -438,18 +443,9 @@
|
||||
+ return this.f_90997_;
|
||||
+ }
|
||||
+
|
||||
public EntityModelSet m_167973_() {
|
||||
return this.f_167844_;
|
||||
}
|
||||
@@ -2789,4 +_,11 @@
|
||||
|
||||
public abstract boolean m_142594_(boolean p_168035_);
|
||||
}
|
||||
+
|
||||
+ // FORGE START
|
||||
+ private float realPartialTick;
|
||||
+ public float getPartialTick() {
|
||||
+ return realPartialTick;
|
||||
+ }
|
||||
+ // FORGE END
|
||||
}
|
||||
}
|
||||
|
||||
public EntityModelSet m_167973_() {
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
--- a/net/minecraft/client/gui/components/toasts/ToastComponent.java
|
||||
+++ b/net/minecraft/client/gui/components/toasts/ToastComponent.java
|
||||
@@ -103,6 +_,7 @@
|
||||
}
|
||||
|
||||
public void m_94922_(Toast p_94923_) {
|
||||
+ if (net.minecraftforge.client.ForgeHooksClient.onToastAdd(p_94923_)) return;
|
||||
this.f_94916_.add(p_94923_);
|
||||
}
|
||||
|
||||
+5
-4
@@ -1,12 +1,13 @@
|
||||
--- a/net/minecraft/client/gui/screens/inventory/EffectRenderingInventoryScreen.java
|
||||
+++ b/net/minecraft/client/gui/screens/inventory/EffectRenderingInventoryScreen.java
|
||||
@@ -42,12 +_,16 @@
|
||||
@@ -42,12 +_,17 @@
|
||||
if (!collection.isEmpty() && j >= 32) {
|
||||
RenderSystem.m_157429_(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
boolean flag = j >= 120;
|
||||
+ var event = net.minecraftforge.client.ForgeHooksClient.onScreenPotionSize(this, j, !flag);
|
||||
+ if (event == 0) return; // 0 = cancel rendering
|
||||
+ flag = event == 2; // 2 = full-size / 1 = compact
|
||||
+ var event = net.minecraftforge.client.ForgeHooksClient.onScreenPotionSize(this, j, !flag, i);
|
||||
+ if (event.isCanceled()) return;
|
||||
+ flag = !event.isCompact();
|
||||
+ i = event.getHorizontalOffset();
|
||||
int k = 33;
|
||||
if (collection.size() > 5) {
|
||||
k = 132 / (collection.size() - 1);
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
--- a/net/minecraft/client/gui/screens/inventory/InventoryScreen.java
|
||||
+++ b/net/minecraft/client/gui/screens/inventory/InventoryScreen.java
|
||||
@@ -100,6 +_,11 @@
|
||||
public static void m_98850_(int p_98851_, int p_98852_, int p_98853_, float p_98854_, float p_98855_, LivingEntity p_98856_) {
|
||||
float f = (float)Math.atan((double)(p_98854_ / 40.0F));
|
||||
float f1 = (float)Math.atan((double)(p_98855_ / 40.0F));
|
||||
+ renderEntityInInventoryRaw(p_98851_, p_98852_, p_98853_, f, f1, p_98856_);
|
||||
+ }
|
||||
+ public static void renderEntityInInventoryRaw(int p_98851_, int p_98852_, int p_98853_, float angleXComponent, float angleYComponent, LivingEntity p_98856_) {
|
||||
+ float f = angleXComponent;
|
||||
+ float f1 = angleYComponent;
|
||||
PoseStack posestack = RenderSystem.m_157191_();
|
||||
posestack.m_85836_();
|
||||
posestack.m_85837_((double)p_98851_, (double)p_98852_, 1050.0D);
|
||||
@@ -0,0 +1,60 @@
|
||||
--- a/net/minecraft/client/model/HumanoidModel.java
|
||||
+++ b/net/minecraft/client/model/HumanoidModel.java
|
||||
@@ -264,6 +_,8 @@
|
||||
case TOOT_HORN:
|
||||
this.f_102811_.f_104203_ = Mth.m_14036_(this.f_102808_.f_104203_, -1.2F, 1.2F) - 1.4835298F;
|
||||
this.f_102811_.f_104204_ = this.f_102808_.f_104204_ - ((float)Math.PI / 6F);
|
||||
+ default:
|
||||
+ this.f_102816_.applyTransform(this, p_102876_, net.minecraft.world.entity.HumanoidArm.RIGHT);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -304,6 +_,8 @@
|
||||
case TOOT_HORN:
|
||||
this.f_102812_.f_104203_ = Mth.m_14036_(this.f_102808_.f_104203_, -1.2F, 1.2F) - 1.4835298F;
|
||||
this.f_102812_.f_104204_ = this.f_102808_.f_104204_ + ((float)Math.PI / 6F);
|
||||
+ default:
|
||||
+ this.f_102815_.applyTransform(this, p_102879_, net.minecraft.world.entity.HumanoidArm.LEFT);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -396,7 +_,7 @@
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
- public static enum ArmPose {
|
||||
+ public static enum ArmPose implements net.minecraftforge.common.IExtensibleEnum {
|
||||
EMPTY(false),
|
||||
ITEM(false),
|
||||
BLOCK(false),
|
||||
@@ -411,10 +_,30 @@
|
||||
|
||||
private ArmPose(boolean p_102896_) {
|
||||
this.f_102890_ = p_102896_;
|
||||
+ this.forgeArmPose = null;
|
||||
}
|
||||
|
||||
public boolean m_102897_() {
|
||||
return this.f_102890_;
|
||||
}
|
||||
+ // FORGE START
|
||||
+ @javax.annotation.Nullable
|
||||
+ private final net.minecraftforge.client.IArmPoseTransformer forgeArmPose;
|
||||
+
|
||||
+ private ArmPose(boolean twoHanded, @javax.annotation.Nonnull net.minecraftforge.client.IArmPoseTransformer forgeArmPose) {
|
||||
+ this.f_102890_ = twoHanded;
|
||||
+ com.google.common.base.Preconditions.checkNotNull(forgeArmPose, "Cannot create new ArmPose with null transformer!");
|
||||
+ this.forgeArmPose = forgeArmPose;
|
||||
+ }
|
||||
+
|
||||
+ public static ArmPose create(String name, boolean twoHanded, @javax.annotation.Nonnull net.minecraftforge.client.IArmPoseTransformer forgeArmPose) {
|
||||
+ throw new IllegalStateException("Enum not extended");
|
||||
+ }
|
||||
+
|
||||
+ public <T extends LivingEntity> void applyTransform(HumanoidModel<T> model, T entity, net.minecraft.world.entity.HumanoidArm arm) {
|
||||
+ com.google.common.base.Preconditions.checkNotNull(this.forgeArmPose, "applyTransform() must not be called on a vanilla ArmPose!");
|
||||
+ this.forgeArmPose.applyTransform(model, entity, arm);
|
||||
+ }
|
||||
+ // FORGE END
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,13 @@
|
||||
--- a/net/minecraft/client/multiplayer/ClientLevel.java
|
||||
+++ b/net/minecraft/client/multiplayer/ClientLevel.java
|
||||
@@ -121,6 +_,8 @@
|
||||
@@ -115,12 +_,15 @@
|
||||
p_194170_.put(BiomeColors.f_108791_, new BlockTintCache((p_194168_) -> {
|
||||
return this.m_104762_(p_194168_, BiomeColors.f_108791_);
|
||||
}));
|
||||
+ net.minecraftforge.client.ColorResolverManager.registerBlockTintCaches(ClientLevel.this, p_194170_);
|
||||
});
|
||||
private final ClientChunkCache f_104559_;
|
||||
private final Deque<Runnable> f_194122_ = Queues.newArrayDeque();
|
||||
private int f_194123_;
|
||||
private final BlockStatePredictionHandler f_233599_ = new BlockStatePredictionHandler();
|
||||
private static final Set<Item> f_194124_ = Set.of(Items.f_42127_, Items.f_151033_);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/client/multiplayer/PlayerInfo.java
|
||||
+++ b/net/minecraft/client/multiplayer/PlayerInfo.java
|
||||
@@ -84,6 +_,7 @@
|
||||
@@ -82,6 +_,7 @@
|
||||
}
|
||||
|
||||
protected void m_105317_(GameType p_105318_) {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
--- a/net/minecraft/client/multiplayer/ProfileKeyPairManager.java
|
||||
+++ b/net/minecraft/client/multiplayer/ProfileKeyPairManager.java
|
||||
@@ -70,6 +_,8 @@
|
||||
@@ -76,6 +_,8 @@
|
||||
this.m_233776_(profilekeypair);
|
||||
return Optional.of(profilekeypair);
|
||||
} catch (CryptException | MinecraftClientException | IOException ioexception) {
|
||||
+ // Forge: The offline user api service always returns a null profile key pair, so let's hide this useless exception if in dev
|
||||
+ if (net.minecraftforge.fml.loading.FMLLoader.isProduction() || p_233781_ != UserApiService.OFFLINE)
|
||||
+ if (net.minecraftforge.fml.loading.FMLLoader.isProduction() || this.f_243348_ != UserApiService.OFFLINE)
|
||||
f_233765_.error("Failed to retrieve profile key pair", (Throwable)ioexception);
|
||||
this.m_233776_((ProfileKeyPair)null);
|
||||
return optional;
|
||||
return p_243401_;
|
||||
@@ -0,0 +1,10 @@
|
||||
--- a/net/minecraft/client/particle/EnchantmentTableParticle.java
|
||||
+++ b/net/minecraft/client/particle/EnchantmentTableParticle.java
|
||||
@@ -73,6 +_,7 @@
|
||||
this.f_107212_ = this.f_106461_ + this.f_107215_ * (double)f;
|
||||
this.f_107213_ = this.f_106462_ + this.f_107216_ * (double)f - (double)(f1 * 1.2F);
|
||||
this.f_107214_ = this.f_106460_ + this.f_107217_ * (double)f;
|
||||
+ this.m_107264_(this.f_107212_, this.f_107213_, this.f_107214_); // FORGE: update the particle's bounding box
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
--- a/net/minecraft/client/particle/PortalParticle.java
|
||||
+++ b/net/minecraft/client/particle/PortalParticle.java
|
||||
@@ -75,6 +_,7 @@
|
||||
this.f_107212_ = this.f_107548_ + this.f_107215_ * (double)f2;
|
||||
this.f_107213_ = this.f_107549_ + this.f_107216_ * (double)f2 + (double)(1.0F - f);
|
||||
this.f_107214_ = this.f_107547_ + this.f_107217_ * (double)f2;
|
||||
+ this.m_107264_(this.f_107212_, this.f_107213_, this.f_107214_); // FORGE: update the particle's bounding box
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
--- a/net/minecraft/client/particle/ReversePortalParticle.java
|
||||
+++ b/net/minecraft/client/particle/ReversePortalParticle.java
|
||||
@@ -29,6 +_,7 @@
|
||||
this.f_107212_ += this.f_107215_ * (double)f;
|
||||
this.f_107213_ += this.f_107216_ * (double)f;
|
||||
this.f_107214_ += this.f_107217_ * (double)f;
|
||||
+ this.m_107264_(this.f_107212_, this.f_107213_, this.f_107214_); // FORGE: update the particle's bounding box
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
--- a/net/minecraft/client/particle/VibrationSignalParticle.java
|
||||
+++ b/net/minecraft/client/particle/VibrationSignalParticle.java
|
||||
@@ -100,6 +_,7 @@
|
||||
this.f_107212_ = Mth.m_14139_(d0, this.f_107212_, vec3.m_7096_());
|
||||
this.f_107213_ = Mth.m_14139_(d0, this.f_107213_, vec3.m_7098_());
|
||||
this.f_107214_ = Mth.m_14139_(d0, this.f_107214_, vec3.m_7094_());
|
||||
+ this.m_107264_(this.f_107212_, this.f_107213_, this.f_107214_); // FORGE: update the particle's bounding box
|
||||
this.f_172460_ = this.f_172462_;
|
||||
this.f_172462_ = (float)Mth.m_14136_(this.f_107212_ - vec3.m_7096_(), this.f_107214_ - vec3.m_7094_());
|
||||
}
|
||||
@@ -24,6 +24,14 @@
|
||||
boolean flag1 = CrossbowItem.m_40932_(p_109377_);
|
||||
boolean flag2 = humanoidarm == HumanoidArm.RIGHT;
|
||||
int i = flag2 ? 1 : -1;
|
||||
@@ -384,6 +_,7 @@
|
||||
this.m_109322_(p_109372_, p_109377_, flag2 ? ItemTransforms.TransformType.FIRST_PERSON_RIGHT_HAND : ItemTransforms.TransformType.FIRST_PERSON_LEFT_HAND, !flag2, p_109379_, p_109380_, p_109381_);
|
||||
} else {
|
||||
boolean flag3 = humanoidarm == HumanoidArm.RIGHT;
|
||||
+ if (!net.minecraftforge.client.extensions.common.IClientItemExtensions.of(p_109377_).applyForgeHandTransform(p_109379_, f_109299_.f_91074_, humanoidarm, p_109377_, p_109373_, p_109378_, p_109376_)) // FORGE: Allow items to define custom arm animation
|
||||
if (p_109372_.m_6117_() && p_109372_.m_21212_() > 0 && p_109372_.m_7655_() == p_109375_) {
|
||||
int k = flag3 ? 1 : -1;
|
||||
switch (p_109377_.m_41780_()) {
|
||||
@@ -487,8 +_,16 @@
|
||||
this.f_109304_ = Mth.m_14036_(this.f_109304_ - 0.4F, 0.0F, 1.0F);
|
||||
} else {
|
||||
|
||||
@@ -51,6 +51,16 @@
|
||||
++this.f_109439_;
|
||||
if (entity.f_19797_ == 0) {
|
||||
entity.f_19790_ = entity.m_20185_();
|
||||
@@ -1206,6 +_,9 @@
|
||||
int i1 = i & 255;
|
||||
outlinebuffersource.m_109929_(k, l, i1, 255);
|
||||
} else {
|
||||
+ if (this.m_109817_() && entity.hasCustomOutlineRendering(this.f_109461_.f_91074_)) { // FORGE: allow custom outline rendering
|
||||
+ flag3 = true;
|
||||
+ }
|
||||
multibuffersource = multibuffersource$buffersource;
|
||||
}
|
||||
|
||||
@@ -1226,6 +_,7 @@
|
||||
List<BlockEntity> list = levelrenderer$renderchunkinfo.f_109839_.m_112835_().m_112773_();
|
||||
if (!list.isEmpty()) {
|
||||
@@ -59,7 +69,17 @@
|
||||
BlockPos blockpos4 = blockentity1.m_58899_();
|
||||
MultiBufferSource multibuffersource1 = multibuffersource$buffersource;
|
||||
p_109600_.m_85836_();
|
||||
@@ -1251,6 +_,7 @@
|
||||
@@ -1242,6 +_,9 @@
|
||||
};
|
||||
}
|
||||
}
|
||||
+ if (this.m_109817_() && blockentity1.hasCustomOutlineRendering(this.f_109461_.f_91074_)) { // FORGE: allow custom outline rendering
|
||||
+ flag3 = true;
|
||||
+ }
|
||||
|
||||
this.f_172946_.m_112267_(blockentity1, p_109601_, p_109600_, multibuffersource1);
|
||||
p_109600_.m_85849_();
|
||||
@@ -1251,9 +_,13 @@
|
||||
|
||||
synchronized(this.f_109468_) {
|
||||
for(BlockEntity blockentity : this.f_109468_) {
|
||||
@@ -67,6 +87,12 @@
|
||||
BlockPos blockpos3 = blockentity.m_58899_();
|
||||
p_109600_.m_85836_();
|
||||
p_109600_.m_85837_((double)blockpos3.m_123341_() - d0, (double)blockpos3.m_123342_() - d1, (double)blockpos3.m_123343_() - d2);
|
||||
+ if (this.m_109817_() && blockentity.hasCustomOutlineRendering(this.f_109461_.f_91074_)) { // FORGE: allow custom outline rendering
|
||||
+ flag3 = true;
|
||||
+ }
|
||||
this.f_172946_.m_112267_(blockentity, p_109601_, p_109600_, multibuffersource$buffersource);
|
||||
p_109600_.m_85849_();
|
||||
}
|
||||
@@ -1290,7 +_,8 @@
|
||||
p_109600_.m_85837_((double)blockpos2.m_123341_() - d0, (double)blockpos2.m_123342_() - d1, (double)blockpos2.m_123343_() - d2);
|
||||
PoseStack.Pose posestack$pose = p_109600_.m_85850_();
|
||||
|
||||
+5
-4
@@ -1,11 +1,12 @@
|
||||
--- a/net/minecraft/client/renderer/entity/ItemEntityRenderer.java
|
||||
+++ b/net/minecraft/client/renderer/entity/ItemEntityRenderer.java
|
||||
@@ -62,17 +_,14 @@
|
||||
@@ -61,18 +_,15 @@
|
||||
boolean flag = bakedmodel.m_7539_();
|
||||
int j = this.m_115042_(itemstack);
|
||||
float f = 0.25F;
|
||||
float f1 = Mth.m_14031_(((float)p_115036_.m_32059_() + p_115038_) / 10.0F + p_115036_.f_31983_) * 0.1F + 0.1F;
|
||||
- float f2 = bakedmodel.m_7442_().m_111808_(ItemTransforms.TransformType.GROUND).f_111757_.m_122260_();
|
||||
+ float f2 = shouldBob() ? bakedmodel.m_7442_().m_111808_(ItemTransforms.TransformType.GROUND).f_111757_.m_122260_() : 0;
|
||||
- float f1 = Mth.m_14031_(((float)p_115036_.m_32059_() + p_115038_) / 10.0F + p_115036_.f_31983_) * 0.1F + 0.1F;
|
||||
+ float f1 = shouldBob() ? Mth.m_14031_(((float)p_115036_.m_32059_() + p_115038_) / 10.0F + p_115036_.f_31983_) * 0.1F + 0.1F : 0;
|
||||
float f2 = bakedmodel.m_7442_().m_111808_(ItemTransforms.TransformType.GROUND).f_111757_.m_122260_();
|
||||
p_115039_.m_85837_(0.0D, (double)(f1 + 0.25F * f2), 0.0D);
|
||||
float f3 = p_115036_.m_32008_(p_115038_);
|
||||
p_115039_.m_85845_(Vector3f.f_122225_.m_122270_(f3));
|
||||
|
||||
@@ -60,6 +60,14 @@
|
||||
crashreportcategory.m_128165_("Item Damage", () -> {
|
||||
return String.valueOf(p_174237_.m_41773_());
|
||||
});
|
||||
@@ -362,6 +_,7 @@
|
||||
RenderSystem.m_69482_();
|
||||
}
|
||||
|
||||
+ net.minecraftforge.client.ItemDecoratorHandler.of(p_115176_).render(p_115175_, p_115176_, p_115177_, p_115178_, f_115093_);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,5 +_,9 @@
|
||||
|
||||
public void m_6213_(ResourceManager p_115105_) {
|
||||
|
||||
+7
-1
@@ -10,7 +10,7 @@
|
||||
}
|
||||
|
||||
public Vec3 m_7860_(AbstractClientPlayer p_117785_, float p_117786_) {
|
||||
@@ -126,7 +_,7 @@
|
||||
@@ -126,10 +_,13 @@
|
||||
if (useanim == UseAnim.TOOT_HORN) {
|
||||
return HumanoidModel.ArmPose.TOOT_HORN;
|
||||
}
|
||||
@@ -19,6 +19,12 @@
|
||||
return HumanoidModel.ArmPose.CROSSBOW_HOLD;
|
||||
}
|
||||
|
||||
+ HumanoidModel.ArmPose forgeArmPose = net.minecraftforge.client.extensions.common.IClientItemExtensions.of(itemstack).getArmPose(p_117795_, p_117796_, itemstack);
|
||||
+ if (forgeArmPose != null) return forgeArmPose;
|
||||
+
|
||||
return HumanoidModel.ArmPose.ITEM;
|
||||
}
|
||||
}
|
||||
@@ -161,10 +_,12 @@
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
--- a/net/minecraft/commands/arguments/EntityArgument.java
|
||||
+++ b/net/minecraft/commands/arguments/EntityArgument.java
|
||||
@@ -115,7 +_,7 @@
|
||||
if (s instanceof SharedSuggestionProvider sharedsuggestionprovider) {
|
||||
StringReader stringreader = new StringReader(p_91483_.getInput());
|
||||
stringreader.setCursor(p_91483_.getStart());
|
||||
- EntitySelectorParser entityselectorparser = new EntitySelectorParser(stringreader, sharedsuggestionprovider.m_6761_(2));
|
||||
+ EntitySelectorParser entityselectorparser = new EntitySelectorParser(stringreader, net.minecraftforge.common.ForgeHooks.canUseEntitySelectors(sharedsuggestionprovider));
|
||||
|
||||
try {
|
||||
entityselectorparser.m_121377_();
|
||||
@@ -0,0 +1,11 @@
|
||||
--- a/net/minecraft/commands/arguments/MessageArgument.java
|
||||
+++ b/net/minecraft/commands/arguments/MessageArgument.java
|
||||
@@ -134,7 +_,7 @@
|
||||
}
|
||||
|
||||
Component m_232196_(CommandSourceStack p_232197_) throws CommandSyntaxException {
|
||||
- return this.m_96849_(p_232197_, p_232197_.m_6761_(2));
|
||||
+ return this.m_96849_(p_232197_, net.minecraftforge.common.ForgeHooks.canUseEntitySelectors(p_232197_));
|
||||
}
|
||||
|
||||
public Component m_96849_(CommandSourceStack p_96850_, boolean p_96851_) throws CommandSyntaxException {
|
||||
@@ -0,0 +1,11 @@
|
||||
--- a/net/minecraft/commands/arguments/selector/EntitySelector.java
|
||||
+++ b/net/minecraft/commands/arguments/selector/EntitySelector.java
|
||||
@@ -87,7 +_,7 @@
|
||||
}
|
||||
|
||||
private void m_121168_(CommandSourceStack p_121169_) throws CommandSyntaxException {
|
||||
- if (this.f_121123_ && !p_121169_.m_6761_(2)) {
|
||||
+ if (this.f_121123_ && !net.minecraftforge.common.ForgeHooks.canUseEntitySelectors(p_121169_)) {
|
||||
throw EntityArgument.f_91441_.create();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
--- a/net/minecraft/core/HolderSet.java
|
||||
+++ b/net/minecraft/core/HolderSet.java
|
||||
@@ -14,7 +_,7 @@
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
-public interface HolderSet<T> extends Iterable<Holder<T>> {
|
||||
+public interface HolderSet<T> extends Iterable<Holder<T>>, net.minecraftforge.common.extensions.IForgeHolderSet<T> {
|
||||
Stream<Holder<T>> m_203614_();
|
||||
|
||||
int m_203632_();
|
||||
@@ -120,6 +_,9 @@
|
||||
|
||||
public void m_205835_(List<Holder<T>> p_205836_) {
|
||||
this.f_205830_ = List.copyOf(p_205836_);
|
||||
+ for (Runnable runnable : this.invalidationCallbacks) {
|
||||
+ runnable.run(); // FORGE: invalidate listeners when tags rebind
|
||||
+ }
|
||||
}
|
||||
|
||||
public TagKey<T> m_205839_() {
|
||||
@@ -144,6 +_,11 @@
|
||||
|
||||
public boolean m_207277_(Registry<T> p_211049_) {
|
||||
return this.f_211044_ == p_211049_;
|
||||
+ }
|
||||
+ // FORGE: Keep a list of invalidation callbacks so they can be run when tags rebind
|
||||
+ private List<Runnable> invalidationCallbacks = new java.util.ArrayList<>();
|
||||
+ public void addInvalidationListener(Runnable runnable) {
|
||||
+ invalidationCallbacks.add(runnable);
|
||||
}
|
||||
}
|
||||
}
|
||||
+14
-2
@@ -25,7 +25,7 @@
|
||||
}
|
||||
|
||||
public ClientboundCustomPayloadPacket(FriendlyByteBuf p_178836_) {
|
||||
@@ -43,6 +_,7 @@
|
||||
@@ -43,15 +_,17 @@
|
||||
} else {
|
||||
throw new IllegalArgumentException("Payload may not be larger than 1048576 bytes");
|
||||
}
|
||||
@@ -33,7 +33,10 @@
|
||||
}
|
||||
|
||||
public void m_5779_(FriendlyByteBuf p_132044_) {
|
||||
@@ -52,6 +_,7 @@
|
||||
p_132044_.m_130085_(this.f_132029_);
|
||||
- p_132044_.writeBytes(this.f_132030_.copy());
|
||||
+ p_132044_.writeBytes(this.f_132030_.slice()); // Use Slice instead of copy, to not update the read index, allowing packet to be sent multiple times.
|
||||
}
|
||||
|
||||
public void m_5797_(ClientGamePacketListener p_132041_) {
|
||||
p_132041_.m_7413_(this);
|
||||
@@ -41,3 +44,12 @@
|
||||
}
|
||||
|
||||
public ResourceLocation m_132042_() {
|
||||
@@ -61,4 +_,8 @@
|
||||
public FriendlyByteBuf m_132045_() {
|
||||
return new FriendlyByteBuf(this.f_132030_.copy());
|
||||
}
|
||||
+
|
||||
+ @Override public int getIndex() { return Integer.MAX_VALUE; }
|
||||
+ @Override public ResourceLocation getName() { return m_132042_(); }
|
||||
+ @org.jetbrains.annotations.Nullable @Override public FriendlyByteBuf getInternalData() { return this.f_132030_; }
|
||||
}
|
||||
+10
-1
@@ -14,7 +14,16 @@
|
||||
public void m_5779_(FriendlyByteBuf p_133994_) {
|
||||
p_133994_.m_130085_(this.f_133980_);
|
||||
- p_133994_.writeBytes((ByteBuf)this.f_133981_);
|
||||
+ p_133994_.writeBytes((ByteBuf)this.f_133981_.copy()); //This may be access multiple times, from multiple threads, lets be safe like the S->C packet
|
||||
+ p_133994_.writeBytes((ByteBuf)this.f_133981_.slice()); // Use Slice instead of copy, to not update the read index, allowing packet to be sent multiple times.
|
||||
}
|
||||
|
||||
public void m_5797_(ServerGamePacketListener p_133992_) {
|
||||
@@ -43,4 +_,8 @@
|
||||
public FriendlyByteBuf m_179590_() {
|
||||
return this.f_133981_;
|
||||
}
|
||||
+
|
||||
+ @Override public int getIndex() { return Integer.MAX_VALUE; }
|
||||
+ @Override public ResourceLocation getName() { return m_179589_(); }
|
||||
+ @org.jetbrains.annotations.Nullable @Override public FriendlyByteBuf getInternalData() { return m_179590_(); }
|
||||
}
|
||||
+18
@@ -9,3 +9,21 @@
|
||||
private static final int f_179804_ = 1048576;
|
||||
private final int f_134745_;
|
||||
private final ResourceLocation f_134746_;
|
||||
@@ -30,7 +_,7 @@
|
||||
public void m_5779_(FriendlyByteBuf p_134757_) {
|
||||
p_134757_.m_130130_(this.f_134745_);
|
||||
p_134757_.m_130085_(this.f_134746_);
|
||||
- p_134757_.writeBytes(this.f_134747_.copy());
|
||||
+ p_134757_.writeBytes(this.f_134747_.slice()); // Use Slice instead of copy, to not update the read index, allowing packet to be sent multiple times.
|
||||
}
|
||||
|
||||
public void m_5797_(ClientLoginPacketListener p_134754_) {
|
||||
@@ -48,4 +_,8 @@
|
||||
public FriendlyByteBuf m_179812_() {
|
||||
return this.f_134747_;
|
||||
}
|
||||
+
|
||||
+ @Override public int getIndex() { return m_134755_(); }
|
||||
+ @Override public ResourceLocation getName() { return m_179811_(); }
|
||||
+ @org.jetbrains.annotations.Nullable @Override public FriendlyByteBuf getInternalData() { return m_179812_(); }
|
||||
}
|
||||
+9
@@ -10,3 +10,12 @@
|
||||
private static final int f_179821_ = 1048576;
|
||||
private final int f_134825_;
|
||||
@Nullable
|
||||
@@ -46,4 +_,8 @@
|
||||
public FriendlyByteBuf m_179825_() {
|
||||
return this.f_134826_;
|
||||
}
|
||||
+
|
||||
+ @Override public int getIndex() { return m_179824_(); }
|
||||
+ @Override public net.minecraft.resources.ResourceLocation getName() { return net.minecraftforge.network.LoginWrapper.WRAPPER; }
|
||||
+ @org.jetbrains.annotations.Nullable @Override public FriendlyByteBuf getInternalData() { return m_179825_(); }
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
--- a/net/minecraft/resources/HolderSetCodec.java
|
||||
+++ b/net/minecraft/resources/HolderSetCodec.java
|
||||
@@ -20,6 +_,8 @@
|
||||
private final Codec<Holder<E>> f_206656_;
|
||||
private final Codec<List<Holder<E>>> f_206657_;
|
||||
private final Codec<Either<TagKey<E>, List<Holder<E>>>> f_206658_;
|
||||
+ private final Codec<net.minecraftforge.registries.holdersets.ICustomHolderSet<E>> forgeDispatchCodec;
|
||||
+ private final Codec<Either<net.minecraftforge.registries.holdersets.ICustomHolderSet<E>, Either<TagKey<E>, List<Holder<E>>>>> combinedCodec;
|
||||
|
||||
private static <E> Codec<List<Holder<E>>> m_206667_(Codec<Holder<E>> p_206668_, boolean p_206669_) {
|
||||
Function<List<Holder<E>>, DataResult<List<Holder<E>>>> function = ExtraCodecs.m_203984_(Holder::m_203376_);
|
||||
@@ -42,6 +_,10 @@
|
||||
this.f_206656_ = p_206661_;
|
||||
this.f_206657_ = m_206667_(p_206661_, p_206662_);
|
||||
this.f_206658_ = Codec.either(TagKey.m_203886_(p_206660_), this.f_206657_);
|
||||
+ // FORGE: make registry-specific dispatch codec and make forge-or-vanilla either codec
|
||||
+ this.forgeDispatchCodec = ExtraCodecs.m_184415_(() -> net.minecraftforge.registries.ForgeRegistries.HOLDER_SET_TYPES.get().getCodec())
|
||||
+ .dispatch(net.minecraftforge.registries.holdersets.ICustomHolderSet::type, type -> type.makeCodec(p_206660_, p_206661_, p_206662_));
|
||||
+ this.combinedCodec = new ExtraCodecs.EitherCodec<>(this.forgeDispatchCodec, this.f_206658_);
|
||||
}
|
||||
|
||||
public <T> DataResult<Pair<HolderSet<E>, T>> decode(DynamicOps<T> p_206696_, T p_206697_) {
|
||||
@@ -49,9 +_,10 @@
|
||||
Optional<? extends Registry<E>> optional = registryops.m_206826_(this.f_206655_);
|
||||
if (optional.isPresent()) {
|
||||
Registry<E> registry = optional.get();
|
||||
- return this.f_206658_.decode(p_206696_, p_206697_).map((p_206682_) -> {
|
||||
+ // FORGE: use the wrapped codec to decode custom/tag/list instead of just tag/list
|
||||
+ return this.combinedCodec.decode(p_206696_, p_206697_).map((p_206682_) -> {
|
||||
return p_206682_.mapFirst((p_206679_) -> {
|
||||
- return p_206679_.map(registry::m_203561_, HolderSet::m_205800_);
|
||||
+ return p_206679_.map(java.util.function.Function.identity(), tagOrList -> tagOrList.map(registry::m_203561_, HolderSet::m_205800_));
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -68,6 +_,9 @@
|
||||
return DataResult.error("HolderSet " + p_206674_ + " is not valid in current registry set");
|
||||
}
|
||||
|
||||
+ // FORGE: use the dispatch codec to encode custom holdersets, otherwise fall back to vanilla tag/list
|
||||
+ if (p_206674_ instanceof net.minecraftforge.registries.holdersets.ICustomHolderSet<E> customHolderSet)
|
||||
+ return this.forgeDispatchCodec.encode(customHolderSet, p_206675_, p_206676_);
|
||||
return this.f_206658_.encode(p_206674_.m_203440_().mapRight(List::copyOf), p_206675_, p_206676_);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
--- a/net/minecraft/resources/RegistryLoader.java
|
||||
+++ b/net/minecraft/resources/RegistryLoader.java
|
||||
@@ -48,7 +_,12 @@
|
||||
if (dataresult != null) {
|
||||
return dataresult;
|
||||
} else {
|
||||
- Holder<E> holder = p_214229_.m_214121_(p_214232_);
|
||||
+ // Prevents an exception from disrupting codec decoding when calling this with prematurely frozen registries - see comment in LevelStorageSource
|
||||
+ DataResult<Holder<E>> maybeHolder = p_214229_.m_214185_(p_214232_);
|
||||
+ if (maybeHolder.error().isPresent()) {
|
||||
+ return maybeHolder;
|
||||
+ }
|
||||
+ Holder<E> holder = maybeHolder.result().get();
|
||||
readcache.f_206803_.put(p_214232_, DataResult.success(holder));
|
||||
DataResult<Holder<E>> dataresult1;
|
||||
if (p_214233_.isEmpty()) {
|
||||
@@ -1,5 +1,13 @@
|
||||
--- a/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -385,6 +_,7 @@
|
||||
this.f_140140_ = true;
|
||||
}
|
||||
|
||||
+ net.minecraftforge.event.ForgeEventFactory.fireChunkTicketLevelUpdated(this.f_140133_, p_140177_, p_140180_, p_140178_, p_140179_);
|
||||
return p_140179_;
|
||||
}
|
||||
}
|
||||
@@ -490,6 +_,7 @@
|
||||
if (this.f_140131_.remove(p_140182_, p_140183_) && p_203002_ != null) {
|
||||
if (p_203002_ instanceof LevelChunk) {
|
||||
|
||||
+7
-7
@@ -67,7 +67,7 @@
|
||||
this.m_243086_(playerchatmessage1);
|
||||
}, this.f_9745_);
|
||||
});
|
||||
@@ -1375,7 +_,7 @@
|
||||
@@ -1383,7 +_,7 @@
|
||||
|
||||
private CompletableFuture<Component> m_215246_(String p_215247_) {
|
||||
Component component = Component.m_237113_(p_215247_);
|
||||
@@ -76,7 +76,7 @@
|
||||
return !component.equals(p_238202_) ? p_238202_ : null;
|
||||
});
|
||||
completablefuture.thenAcceptAsync((p_242747_) -> {
|
||||
@@ -1524,11 +_,13 @@
|
||||
@@ -1532,11 +_,13 @@
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -91,16 +91,16 @@
|
||||
if (interactionresult.m_19077_()) {
|
||||
CriteriaTriggers.f_10565_.m_61494_(ServerGamePacketListenerImpl.this.f_9743_, itemstack, entity);
|
||||
if (interactionresult.m_19080_()) {
|
||||
@@ -1550,7 +_,7 @@
|
||||
@@ -1558,6 +_,8 @@
|
||||
|
||||
public void m_141994_() {
|
||||
if (!(entity instanceof ItemEntity) && !(entity instanceof ExperienceOrb) && !(entity instanceof AbstractArrow) && entity != ServerGamePacketListenerImpl.this.f_9743_) {
|
||||
- ServerGamePacketListenerImpl.this.f_9743_.m_5706_(entity);
|
||||
+ if(ServerGamePacketListenerImpl.this.f_9743_.canHit(entity, 3)) ServerGamePacketListenerImpl.this.f_9743_.m_5706_(entity); //Forge: Perform attack range check. Original check was dist < 6, range is 3, so vanilla used padding=3
|
||||
+ //Forge: Perform attack range check. Original check was dist < 6, range is 3, so vanilla used padding=3
|
||||
+ if(ServerGamePacketListenerImpl.this.f_9743_.canHit(entity, 3))
|
||||
ServerGamePacketListenerImpl.this.f_9743_.m_5706_(entity);
|
||||
} else {
|
||||
ServerGamePacketListenerImpl.this.m_9942_(Component.m_237115_("multiplayer.disconnect.invalid_entity_attacked"));
|
||||
ServerGamePacketListenerImpl.f_9744_.warn("Player {} tried to attack an invalid entity", (Object)ServerGamePacketListenerImpl.this.f_9743_.m_7755_().getString());
|
||||
@@ -1749,6 +_,7 @@
|
||||
@@ -1757,6 +_,7 @@
|
||||
}
|
||||
|
||||
public void m_7423_(ServerboundCustomPayloadPacket p_9860_) {
|
||||
|
||||
+6
-6
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
@@ -69,7 +_,13 @@
|
||||
@@ -65,7 +_,13 @@
|
||||
}
|
||||
|
||||
public void m_9933_() {
|
||||
@@ -15,7 +15,7 @@
|
||||
this.m_10055_();
|
||||
} else if (this.f_10019_ == ServerLoginPacketListenerImpl.State.DELAY_ACCEPT) {
|
||||
ServerPlayer serverplayer = this.f_10018_.m_6846_().m_11259_(this.f_10021_.getId());
|
||||
@@ -194,14 +_,14 @@
|
||||
@@ -178,14 +_,14 @@
|
||||
GameProfile gameprofile = this.f_10018_.m_236731_();
|
||||
if (gameprofile != null && p_10047_.f_238040_().equalsIgnoreCase(gameprofile.getName())) {
|
||||
this.f_10021_ = gameprofile;
|
||||
@@ -32,7 +32,7 @@
|
||||
}
|
||||
|
||||
}
|
||||
@@ -238,7 +_,7 @@
|
||||
@@ -222,7 +_,7 @@
|
||||
throw new IllegalStateException("Protocol error", cryptexception);
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
public void run() {
|
||||
GameProfile gameprofile = ServerLoginPacketListenerImpl.this.f_10021_;
|
||||
|
||||
@@ -246,11 +_,11 @@
|
||||
@@ -230,11 +_,11 @@
|
||||
ServerLoginPacketListenerImpl.this.f_10021_ = ServerLoginPacketListenerImpl.this.f_10018_.m_129925_().hasJoinedServer(new GameProfile((UUID)null, gameprofile.getName()), s, this.m_10064_());
|
||||
if (ServerLoginPacketListenerImpl.this.f_10021_ != null) {
|
||||
ServerLoginPacketListenerImpl.f_10015_.info("UUID of player {} is {}", ServerLoginPacketListenerImpl.this.f_10021_.getName(), ServerLoginPacketListenerImpl.this.f_10021_.getId());
|
||||
@@ -55,7 +55,7 @@
|
||||
} else {
|
||||
ServerLoginPacketListenerImpl.this.m_10053_(Component.m_237115_("multiplayer.disconnect.unverified_username"));
|
||||
ServerLoginPacketListenerImpl.f_10015_.error("Username '{}' tried to join with an invalid session", (Object)gameprofile.getName());
|
||||
@@ -259,7 +_,7 @@
|
||||
@@ -243,7 +_,7 @@
|
||||
if (ServerLoginPacketListenerImpl.this.f_10018_.m_129792_()) {
|
||||
ServerLoginPacketListenerImpl.f_10015_.warn("Authentication servers are down but will let them in anyway!");
|
||||
ServerLoginPacketListenerImpl.this.f_10021_ = gameprofile;
|
||||
@@ -64,7 +64,7 @@
|
||||
} else {
|
||||
ServerLoginPacketListenerImpl.this.m_10053_(Component.m_237115_("multiplayer.disconnect.authservers_down"));
|
||||
ServerLoginPacketListenerImpl.f_10015_.error("Couldn't verify username because servers are unavailable");
|
||||
@@ -279,6 +_,7 @@
|
||||
@@ -263,6 +_,7 @@
|
||||
}
|
||||
|
||||
public void m_7223_(ServerboundCustomQueryPacket p_10045_) {
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
--- a/net/minecraft/util/datafix/schemas/V2832.java
|
||||
+++ b/net/minecraft/util/datafix/schemas/V2832.java
|
||||
@@ -19,7 +_,7 @@
|
||||
return DSL.fields("Level", DSL.optionalFields("Entities", DSL.list(References.f_16785_.in(p_185234_)), "TileEntities", DSL.list(DSL.or(References.f_16781_.in(p_185234_), DSL.remainder())), "TileTicks", DSL.list(DSL.fields("i", References.f_16787_.in(p_185234_))), "Sections", DSL.list(DSL.optionalFields("biomes", DSL.optionalFields("palette", DSL.list(References.f_16794_.in(p_185234_))), "block_states", DSL.optionalFields("palette", DSL.list(References.f_16783_.in(p_185234_))))), "Structures", DSL.optionalFields("Starts", DSL.compoundList(References.f_16790_.in(p_185234_)))));
|
||||
});
|
||||
p_185234_.registerType(false, References.f_16795_, () -> {
|
||||
- return DSL.fields("dimensions", DSL.compoundList(DSL.constType(m_17310_()), DSL.fields("generator", DSL.taggedChoiceLazy("type", DSL.string(), ImmutableMap.of("minecraft:debug", DSL::remainder, "minecraft:flat", () -> {
|
||||
+ return DSL.fields("dimensions", DSL.compoundList(DSL.constType(m_17310_()), DSL.fields("generator", DSL.or(DSL.taggedChoiceLazy("type", DSL.string(), ImmutableMap.of("minecraft:debug", DSL::remainder, "minecraft:flat", () -> {
|
||||
return DSL.optionalFields("settings", DSL.optionalFields("biome", References.f_16794_.in(p_185234_), "layers", DSL.list(DSL.optionalFields("block", References.f_16787_.in(p_185234_)))));
|
||||
}, "minecraft:noise", () -> {
|
||||
return DSL.optionalFields("biome_source", DSL.taggedChoiceLazy("type", DSL.string(), ImmutableMap.of("minecraft:fixed", () -> {
|
||||
@@ -29,7 +_,7 @@
|
||||
}, "minecraft:checkerboard", () -> {
|
||||
return DSL.fields("biomes", DSL.list(References.f_16794_.in(p_185234_)));
|
||||
}, "minecraft:the_end", DSL::remainder)), "settings", DSL.or(DSL.constType(DSL.string()), DSL.optionalFields("default_block", References.f_16787_.in(p_185234_), "default_fluid", References.f_16787_.in(p_185234_))));
|
||||
- })))));
|
||||
+ })), DSL.remainder()))));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -590,6 +590,15 @@
|
||||
if (this.f_20935_.m_41781_()) {
|
||||
this.m_21329_();
|
||||
}
|
||||
@@ -2989,7 +_,7 @@
|
||||
public boolean m_21254_() {
|
||||
if (this.m_6117_() && !this.f_20935_.m_41619_()) {
|
||||
Item item = this.f_20935_.m_41720_();
|
||||
- if (item.m_6164_(this.f_20935_) != UseAnim.BLOCK) {
|
||||
+ if (item.m_6164_(this.f_20935_) != UseAnim.BLOCK && !this.f_20935_.canPerformAction(net.minecraftforge.common.ToolActions.SHIELD_BLOCK)) { // TODO 1.20 only use the tool action
|
||||
return false;
|
||||
} else {
|
||||
return item.m_8105_(this.f_20935_) - this.f_20936_ >= 5;
|
||||
@@ -3115,8 +_,8 @@
|
||||
}
|
||||
|
||||
|
||||
@@ -194,33 +194,14 @@
|
||||
this.m_21008_(p_36159_, ItemStack.f_41583_);
|
||||
}
|
||||
|
||||
@@ -1020,7 +_,7 @@
|
||||
double d1 = p_36201_.f_82481_;
|
||||
double d2 = 0.05D;
|
||||
@@ -1014,6 +_,7 @@
|
||||
return !this.f_36077_.f_35935_;
|
||||
}
|
||||
|
||||
- while(d0 != 0.0D && this.f_19853_.m_45756_(this, this.m_20191_().m_82386_(d0, (double)(-this.f_19793_), 0.0D))) {
|
||||
+ while(d0 != 0.0D && this.f_19853_.m_45756_(this, this.m_20191_().m_82386_(d0, (double)(-this.getStepHeight()), 0.0D))) {
|
||||
if (d0 < 0.05D && d0 >= -0.05D) {
|
||||
d0 = 0.0D;
|
||||
} else if (d0 > 0.0D) {
|
||||
@@ -1030,7 +_,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
- while(d1 != 0.0D && this.f_19853_.m_45756_(this, this.m_20191_().m_82386_(0.0D, (double)(-this.f_19793_), d1))) {
|
||||
+ while(d1 != 0.0D && this.f_19853_.m_45756_(this, this.m_20191_().m_82386_(0.0D, (double)(-this.getStepHeight()), d1))) {
|
||||
if (d1 < 0.05D && d1 >= -0.05D) {
|
||||
d1 = 0.0D;
|
||||
} else if (d1 > 0.0D) {
|
||||
@@ -1040,7 +_,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
- while(d0 != 0.0D && d1 != 0.0D && this.f_19853_.m_45756_(this, this.m_20191_().m_82386_(d0, (double)(-this.f_19793_), d1))) {
|
||||
+ while(d0 != 0.0D && d1 != 0.0D && this.f_19853_.m_45756_(this, this.m_20191_().m_82386_(d0, (double)(-this.getStepHeight()), d1))) {
|
||||
if (d0 < 0.05D && d0 >= -0.05D) {
|
||||
d0 = 0.0D;
|
||||
} else if (d0 > 0.0D) {
|
||||
+ // Forge: Don't update this method to use IForgeEntity#getStepHeight() - https://github.com/MinecraftForge/MinecraftForge/issues/8922
|
||||
protected Vec3 m_5763_(Vec3 p_36201_, MoverType p_36202_) {
|
||||
if (!this.f_36077_.f_35935_ && p_36201_.f_82480_ <= 0.0D && (p_36202_ == MoverType.SELF || p_36202_ == MoverType.PLAYER) && this.m_36343_() && this.m_36386_()) {
|
||||
double d0 = p_36201_.f_82479_;
|
||||
@@ -1065,10 +_,11 @@
|
||||
}
|
||||
|
||||
|
||||
@@ -24,9 +24,9 @@
|
||||
this.f_39000_ = 0;
|
||||
+ boolean flag = false;
|
||||
+
|
||||
+ if (!net.minecraftforge.common.ForgeHooks.onAnvilChange(this, itemstack, itemstack2, f_39768_, f_39001_, j, this.f_39771_)) return;
|
||||
if (!itemstack2.m_41619_()) {
|
||||
- boolean flag = itemstack2.m_150930_(Items.f_42690_) && !EnchantedBookItem.m_41163_(itemstack2).isEmpty();
|
||||
+ if (!net.minecraftforge.common.ForgeHooks.onAnvilChange(this, itemstack, itemstack2, f_39768_, f_39001_, j, this.f_39771_)) return;
|
||||
+ flag = itemstack2.m_41720_() == Items.f_42690_ && !EnchantedBookItem.m_41163_(itemstack2).isEmpty();
|
||||
if (itemstack1.m_41763_() && itemstack1.m_41720_().m_6832_(itemstack, itemstack2)) {
|
||||
int l2 = Math.min(itemstack1.m_41773_(), itemstack1.m_41776_() / 4);
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
--- a/net/minecraft/world/item/UseAnim.java
|
||||
+++ b/net/minecraft/world/item/UseAnim.java
|
||||
@@ -9,5 +_,10 @@
|
||||
SPEAR,
|
||||
CROSSBOW,
|
||||
SPYGLASS,
|
||||
- TOOT_HORN;
|
||||
+ TOOT_HORN,
|
||||
+ /**
|
||||
+ * Items with custom arm animation should return this in `Item#getUseAnimation`
|
||||
+ * to prevent vanilla from also trying to animate same item
|
||||
+ */
|
||||
+ CUSTOM
|
||||
}
|
||||
@@ -38,6 +38,22 @@
|
||||
}, p_44834_);
|
||||
return mutablefloat.floatValue();
|
||||
}
|
||||
@@ -168,6 +_,7 @@
|
||||
m_44853_(enchantmenthelper$enchantmentvisitor, p_44824_.m_20158_());
|
||||
}
|
||||
|
||||
+ if(false) // Forge: Fix MC-248272
|
||||
if (p_44825_ instanceof Player) {
|
||||
m_44850_(enchantmenthelper$enchantmentvisitor, p_44824_.m_21205_());
|
||||
}
|
||||
@@ -182,6 +_,7 @@
|
||||
m_44853_(enchantmenthelper$enchantmentvisitor, p_44897_.m_20158_());
|
||||
}
|
||||
|
||||
+ if(false) // Forge: Fix MC-248272
|
||||
if (p_44897_ instanceof Player) {
|
||||
m_44850_(enchantmenthelper$enchantmentvisitor, p_44897_.m_21205_());
|
||||
}
|
||||
@@ -302,7 +_,7 @@
|
||||
|
||||
public static int m_220287_(RandomSource p_220288_, int p_220289_, int p_220290_, ItemStack p_220291_) {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
+// TODO: ForgeEventFactory.getPotentialSpawns, ForgeHooks.canEntitySpawn
|
||||
+// TODO: ForgeHooks.canEntitySpawn
|
||||
public final class NaturalSpawner {
|
||||
private static final Logger f_46977_ = LogUtils.getLogger();
|
||||
private static final int f_151589_ = 24;
|
||||
@@ -35,12 +35,13 @@
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -266,7 +_,7 @@
|
||||
@@ -266,7 +_,8 @@
|
||||
}
|
||||
|
||||
private static WeightedRandomList<MobSpawnSettings.SpawnerData> m_220443_(ServerLevel p_220444_, StructureManager p_220445_, ChunkGenerator p_220446_, MobCategory p_220447_, BlockPos p_220448_, @Nullable Holder<Biome> p_220449_) {
|
||||
- return m_220455_(p_220448_, p_220444_, p_220447_, p_220445_) ? NetherFortressStructure.f_228517_ : p_220446_.m_223133_(p_220449_ != null ? p_220449_ : p_220444_.m_204166_(p_220448_), p_220445_, p_220447_, p_220448_);
|
||||
+ return m_220455_(p_220448_, p_220444_, p_220447_, p_220445_) ? p_220445_.m_220521_().m_175515_(Registry.f_235725_).m_123013_(BuiltinStructures.f_209859_).m_226612_().get(MobCategory.MONSTER).f_210044_() : p_220446_.m_223133_(p_220449_ != null ? p_220449_ : p_220444_.m_204166_(p_220448_), p_220445_, p_220447_, p_220448_);
|
||||
+ // Forge: Add in potential spawns, and replace hardcoded nether fortress mob list
|
||||
+ return net.minecraftforge.event.ForgeEventFactory.getPotentialSpawns(p_220444_, p_220447_, p_220448_, m_220455_(p_220448_, p_220444_, p_220447_, p_220445_) ? p_220445_.m_220521_().m_175515_(Registry.f_235725_).m_123013_(BuiltinStructures.f_209859_).m_226612_().get(MobCategory.MONSTER).f_210044_() : p_220446_.m_223133_(p_220449_ != null ? p_220449_ : p_220444_.m_204166_(p_220448_), p_220445_, p_220447_, p_220448_));
|
||||
}
|
||||
|
||||
public static boolean m_220455_(BlockPos p_220456_, ServerLevel p_220457_, MobCategory p_220458_, StructureManager p_220459_) {
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
--- a/net/minecraft/world/level/storage/LevelStorageSource.java
|
||||
+++ b/net/minecraft/world/level/storage/LevelStorageSource.java
|
||||
@@ -96,6 +_,13 @@
|
||||
}
|
||||
|
||||
Dynamic<T> dynamic1 = p_78206_.update(References.f_16795_, dynamic, p_78207_, SharedConstants.m_183709_().getWorldVersion());
|
||||
+ // The above line is modified (via the patch in V2832), such that the data fixer upper will retain dimensions that don't exist in the schema, in the dynamic.
|
||||
+ // When we parse the WorldGenSettings below, in vanilla, this uses the same call paths that can cause things to register (such as dimension types).
|
||||
+ // However, since at this point all resource data will have been loaded, anything that *would* register now is going to error later, because it'll create a Holder<> reference, that is not bound to anything. This unbound reference will then throw an error when the registries are frozen.
|
||||
+ // So, we freeze the registries before this call to parse(). This prevents them from leaking any new unbound holders into the registry.
|
||||
+ // Attempting to register to a frozen registry throws an exception, which we resolve via a patch in RegistryLoader, causing it to return DataResult.error() instead, and prevent the faulty dimension from registering without aborting the parsing of the WorldGenSettings
|
||||
+ // Finally, the resultOrPartial() promotes only the dimensions which successfully parsed, and the LenientUnboundedMapCodec which is patched into the WorldGenSettings codec ensures that *only* the invalid dimensions will fail to parse (see MC-197860), and not discard other dimensions as well.
|
||||
+ if (p_78205_.getOps() instanceof net.minecraft.resources.RegistryOps<T> ops) ops.f_206806_.m_203610_().forEach(e -> e.f_206234_().m_203521_());
|
||||
DataResult<WorldGenSettings> dataresult = WorldGenSettings.f_64600_.parse(dynamic1);
|
||||
return Pair.of(dataresult.resultOrPartial(Util.m_137489_("WorldGenSettings: ", f_78191_::error)).orElseGet(() -> {
|
||||
RegistryAccess registryaccess = RegistryAccess.m_206154_(dynamic1);
|
||||
@@ -372,6 +_,19 @@
|
||||
return LevelStorageSource.this.m_230817_(this.f_230867_, LevelStorageSource.m_211737_(p_211748_, p_211749_, p_211750_));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"values": [
|
||||
"#forge:armors/helmets",
|
||||
"#forge:armors/chestplates",
|
||||
"#forge:armors/leggings",
|
||||
"#forge:armors/boots"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"values": [
|
||||
"minecraft:leather_boots",
|
||||
"minecraft:chainmail_boots",
|
||||
"minecraft:iron_boots",
|
||||
"minecraft:golden_boots",
|
||||
"minecraft:diamond_boots",
|
||||
"minecraft:netherite_boots"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"values": [
|
||||
"minecraft:leather_chestplate",
|
||||
"minecraft:chainmail_chestplate",
|
||||
"minecraft:iron_chestplate",
|
||||
"minecraft:golden_chestplate",
|
||||
"minecraft:diamond_chestplate",
|
||||
"minecraft:netherite_chestplate"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"values": [
|
||||
"minecraft:leather_helmet",
|
||||
"minecraft:turtle_helmet",
|
||||
"minecraft:chainmail_helmet",
|
||||
"minecraft:iron_helmet",
|
||||
"minecraft:golden_helmet",
|
||||
"minecraft:diamond_helmet",
|
||||
"minecraft:netherite_helmet"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"values": [
|
||||
"minecraft:leather_leggings",
|
||||
"minecraft:chainmail_leggings",
|
||||
"minecraft:iron_leggings",
|
||||
"minecraft:golden_leggings",
|
||||
"minecraft:diamond_leggings",
|
||||
"minecraft:netherite_leggings"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"values": [
|
||||
"#forge:tools/swords",
|
||||
"#forge:tools/axes",
|
||||
"#forge:tools/pickaxes",
|
||||
"#forge:tools/shovels",
|
||||
"#forge:tools/hoes",
|
||||
"#forge:tools/shields",
|
||||
"#forge:tools/bows",
|
||||
"#forge:tools/crossbows",
|
||||
"#forge:tools/fishing_rods",
|
||||
"#forge:tools/tridents"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"values": [
|
||||
"minecraft:wooden_axe",
|
||||
"minecraft:stone_axe",
|
||||
"minecraft:iron_axe",
|
||||
"minecraft:golden_axe",
|
||||
"minecraft:diamond_axe",
|
||||
"minecraft:netherite_axe"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"values": [
|
||||
"minecraft:bow"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"values": [
|
||||
"minecraft:crossbow"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"values": [
|
||||
"minecraft:fishing_rod"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"values": [
|
||||
"minecraft:wooden_hoe",
|
||||
"minecraft:stone_hoe",
|
||||
"minecraft:iron_hoe",
|
||||
"minecraft:golden_hoe",
|
||||
"minecraft:diamond_hoe",
|
||||
"minecraft:netherite_hoe"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"values": [
|
||||
"minecraft:wooden_pickaxe",
|
||||
"minecraft:stone_pickaxe",
|
||||
"minecraft:iron_pickaxe",
|
||||
"minecraft:golden_pickaxe",
|
||||
"minecraft:diamond_pickaxe",
|
||||
"minecraft:netherite_pickaxe"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"values": [
|
||||
"minecraft:shield"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"values": [
|
||||
"minecraft:wooden_shovel",
|
||||
"minecraft:stone_shovel",
|
||||
"minecraft:iron_shovel",
|
||||
"minecraft:golden_shovel",
|
||||
"minecraft:diamond_shovel",
|
||||
"minecraft:netherite_shovel"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"values": [
|
||||
"minecraft:wooden_sword",
|
||||
"minecraft:stone_sword",
|
||||
"minecraft:iron_sword",
|
||||
"minecraft:golden_sword",
|
||||
"minecraft:diamond_sword",
|
||||
"minecraft:netherite_sword"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"values": [
|
||||
"minecraft:trident"
|
||||
]
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"values": [
|
||||
"minecraft:desert",
|
||||
"minecraft:beach",
|
||||
"minecraft:badlands",
|
||||
"minecraft:wooded_badlands"
|
||||
]
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
"minecraft:swamp",
|
||||
"minecraft:jungle",
|
||||
"minecraft:sparse_jungle",
|
||||
"minecraft:beach",
|
||||
"minecraft:bamboo_jungle",
|
||||
"minecraft:lush_caves",
|
||||
"minecraft:mangrove_swamp"
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) Forge Development LLC and contributors
|
||||
* SPDX-License-Identifier: LGPL-2.1-only
|
||||
*/
|
||||
|
||||
package net.minecraftforge.client;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import net.minecraft.client.color.block.BlockTintCache;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.world.level.ColorResolver;
|
||||
import net.minecraftforge.client.event.RegisterColorHandlersEvent;
|
||||
import net.minecraftforge.fml.ModLoader;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Manager for custom {@link ColorResolver} instances, collected via {@link RegisterColorHandlersEvent.ColorResolvers}.
|
||||
*/
|
||||
public final class ColorResolverManager
|
||||
{
|
||||
|
||||
private static ImmutableList<ColorResolver> colorResolvers;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static void init()
|
||||
{
|
||||
ImmutableList.Builder<ColorResolver> builder = ImmutableList.builder();
|
||||
ModLoader.get().postEvent(new RegisterColorHandlersEvent.ColorResolvers(builder));
|
||||
colorResolvers = builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a {@link BlockTintCache} for every registered {@link ColorResolver} into the given target map.
|
||||
*
|
||||
* @param level the level to use
|
||||
* @param target the map to populate
|
||||
*/
|
||||
public static void registerBlockTintCaches(ClientLevel level, Map<ColorResolver, BlockTintCache> target)
|
||||
{
|
||||
for (var resolver : colorResolvers)
|
||||
{
|
||||
target.put(resolver, new BlockTintCache(pos -> level.calculateBlockTint(pos, resolver)));
|
||||
}
|
||||
}
|
||||
|
||||
private ColorResolverManager()
|
||||
{
|
||||
}
|
||||
}
|
||||
Executable → Regular
+11
-3
@@ -27,6 +27,7 @@ import net.minecraft.client.color.item.ItemColors;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.GuiComponent;
|
||||
import net.minecraft.client.gui.components.LerpingBossEvent;
|
||||
import net.minecraft.client.gui.components.toasts.Toast;
|
||||
import net.minecraft.client.gui.screens.ConfirmScreen;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.gui.screens.TitleScreen;
|
||||
@@ -128,6 +129,7 @@ import net.minecraftforge.client.event.RenderTooltipEvent;
|
||||
import net.minecraftforge.client.event.ScreenEvent;
|
||||
import net.minecraftforge.client.event.ScreenshotEvent;
|
||||
import net.minecraftforge.client.event.TextureStitchEvent;
|
||||
import net.minecraftforge.client.event.ToastAddEvent;
|
||||
import net.minecraftforge.client.event.ViewportEvent;
|
||||
import net.minecraftforge.client.event.sound.PlaySoundEvent;
|
||||
import net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions;
|
||||
@@ -1091,10 +1093,16 @@ public class ForgeHooksClient
|
||||
};
|
||||
}
|
||||
|
||||
public static int onScreenPotionSize(Screen screen, int availableSpace, boolean compact)
|
||||
public static ScreenEvent.RenderInventoryMobEffects onScreenPotionSize(Screen screen, int availableSpace, boolean compact, int horizontalOffset)
|
||||
{
|
||||
final ScreenEvent.RenderInventoryMobEffects event = new ScreenEvent.RenderInventoryMobEffects(screen, availableSpace, compact);
|
||||
return MinecraftForge.EVENT_BUS.post(event) ? 0 : (event.isCompact() ? 1 : 2);
|
||||
final ScreenEvent.RenderInventoryMobEffects event = new ScreenEvent.RenderInventoryMobEffects(screen, availableSpace, compact, horizontalOffset);
|
||||
MinecraftForge.EVENT_BUS.post(event);
|
||||
return event;
|
||||
}
|
||||
|
||||
public static boolean onToastAdd(Toast toast)
|
||||
{
|
||||
return MinecraftForge.EVENT_BUS.post(new ToastAddEvent(toast));
|
||||
}
|
||||
|
||||
public static boolean isBlockInSolidLayer(BlockState state)
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) Forge Development LLC and contributors
|
||||
* SPDX-License-Identifier: LGPL-2.1-only
|
||||
*/
|
||||
|
||||
package net.minecraftforge.client;
|
||||
|
||||
import net.minecraft.client.model.HumanoidModel;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.entity.HumanoidArm;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraftforge.client.extensions.common.IClientItemExtensions;
|
||||
|
||||
/**
|
||||
* An ArmPose that can be defined by the user.
|
||||
* Register one by creating a custom {@link net.minecraft.client.model.HumanoidModel.ArmPose}
|
||||
* and returning it in {@link IClientItemExtensions#getArmPose(LivingEntity, InteractionHand, ItemStack)}.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface IArmPoseTransformer
|
||||
{
|
||||
|
||||
/**
|
||||
* This method should be used to apply all wanted transformations to the player when the ArmPose is active.
|
||||
* You can use {@link LivingEntity#getTicksUsingItem()} and {@link LivingEntity#getUseItemRemainingTicks()} for moving animations.
|
||||
*
|
||||
* @param model The humanoid model
|
||||
* @param entity The humanoid entity
|
||||
* @param arm Arm to pose
|
||||
*/
|
||||
void applyTransform(HumanoidModel<?> model, LivingEntity entity, HumanoidArm arm);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) Forge Development LLC and contributors
|
||||
* SPDX-License-Identifier: LGPL-2.1-only
|
||||
*/
|
||||
|
||||
package net.minecraftforge.client;
|
||||
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.renderer.entity.ItemRenderer;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.ItemLike;
|
||||
import net.minecraftforge.client.event.RegisterItemDecorationsEvent;
|
||||
|
||||
/**
|
||||
* An ItemDecorator that is used to render something on specific items, when the DurabilityBar and StackCount is rendered.
|
||||
* Add it to an item using {@linkplain RegisterItemDecorationsEvent#register(ItemLike, IItemDecorator)}.
|
||||
*/
|
||||
public interface IItemDecorator
|
||||
{
|
||||
|
||||
/**
|
||||
* Is called after {@linkplain ItemRenderer#renderGuiItemDecorations(Font, ItemStack, int, int, String)} is done rendering.
|
||||
* The StackCount is rendered at blitOffset+200 so use the blitOffset with caution.
|
||||
* <p>
|
||||
* The RenderState during this call will be: enableTexture, enableDepthTest, enableBlend and defaultBlendFunc
|
||||
* @return true if you have modified the RenderState and it has to be reset for other ItemDecorators
|
||||
*/
|
||||
boolean render(Font font, ItemStack stack, int xOffset, int yOffset, float blitOffset);
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) Forge Development LLC and contributors
|
||||
* SPDX-License-Identifier: LGPL-2.1-only
|
||||
*/
|
||||
|
||||
package net.minecraftforge.client;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraftforge.client.event.RegisterItemDecorationsEvent;
|
||||
import net.minecraftforge.fml.ModLoader;
|
||||
import net.minecraftforge.fml.ModLoadingContext;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public final class ItemDecoratorHandler
|
||||
{
|
||||
private final List<IItemDecorator> itemDecorators;
|
||||
|
||||
private static Map<Item, ItemDecoratorHandler> DECORATOR_LOOKUP = ImmutableMap.of();
|
||||
|
||||
private static final ItemDecoratorHandler EMPTY = new ItemDecoratorHandler();
|
||||
private ItemDecoratorHandler()
|
||||
{
|
||||
this.itemDecorators = ImmutableList.of();
|
||||
}
|
||||
private ItemDecoratorHandler(List<IItemDecorator> itemDecorators)
|
||||
{
|
||||
this.itemDecorators = ImmutableList.copyOf(itemDecorators);
|
||||
}
|
||||
|
||||
public static void init()
|
||||
{
|
||||
var decorators = new HashMap<Item, List<IItemDecorator>>();
|
||||
var event = new RegisterItemDecorationsEvent(decorators);
|
||||
ModLoader.get().postEventWithWrapInModOrder(event, (mc, e) -> ModLoadingContext.get().setActiveContainer(mc), (mc, e) -> ModLoadingContext.get().setActiveContainer(null));
|
||||
var builder = new ImmutableMap.Builder<Item, ItemDecoratorHandler>();
|
||||
decorators.forEach((item, itemDecorators) -> builder.put(item, new ItemDecoratorHandler(itemDecorators)));
|
||||
DECORATOR_LOOKUP = builder.build();
|
||||
}
|
||||
|
||||
public static ItemDecoratorHandler of(ItemStack stack)
|
||||
{
|
||||
return DECORATOR_LOOKUP.getOrDefault(stack.getItem(), EMPTY);
|
||||
}
|
||||
|
||||
public void render(Font font, ItemStack stack, int xOffset, int yOffset, float blitOffset)
|
||||
{
|
||||
resetRenderState();
|
||||
for (IItemDecorator itemDecorator : itemDecorators)
|
||||
{
|
||||
if (itemDecorator.render(font, stack, xOffset, yOffset, blitOffset))
|
||||
resetRenderState();
|
||||
}
|
||||
}
|
||||
|
||||
private void resetRenderState()
|
||||
{
|
||||
RenderSystem.enableTexture();
|
||||
RenderSystem.enableDepthTest();
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.defaultBlendFunc();
|
||||
}
|
||||
}
|
||||
@@ -5,10 +5,13 @@
|
||||
|
||||
package net.minecraftforge.client.event;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import net.minecraft.client.color.block.BlockColor;
|
||||
import net.minecraft.client.color.block.BlockColors;
|
||||
import net.minecraft.client.color.item.ItemColor;
|
||||
import net.minecraft.client.color.item.ItemColors;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.ColorResolver;
|
||||
import net.minecraft.world.level.ItemLike;
|
||||
import net.minecraftforge.eventbus.api.Cancelable;
|
||||
import net.minecraftforge.eventbus.api.Event;
|
||||
@@ -127,4 +130,26 @@ public abstract class RegisterColorHandlersEvent extends Event implements IModBu
|
||||
itemColors.register(itemColor, items);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows registration of custom {@link ColorResolver} implementations to be used with
|
||||
* {@link net.minecraft.world.level.BlockAndTintGetter#getBlockTint(BlockPos, ColorResolver)}.
|
||||
*/
|
||||
public static class ColorResolvers extends RegisterColorHandlersEvent
|
||||
{
|
||||
private final ImmutableList.Builder<ColorResolver> builder;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public ColorResolvers(ImmutableList.Builder<ColorResolver> builder)
|
||||
{
|
||||
this.builder = builder;
|
||||
}
|
||||
|
||||
public void register(ColorResolver resolver)
|
||||
{
|
||||
this.builder.add(resolver);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) Forge Development LLC and contributors
|
||||
* SPDX-License-Identifier: LGPL-2.1-only
|
||||
*/
|
||||
package net.minecraftforge.client.event;
|
||||
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.ItemLike;
|
||||
import net.minecraftforge.client.IItemDecorator;
|
||||
|
||||
import net.minecraftforge.eventbus.api.Cancelable;
|
||||
import net.minecraftforge.eventbus.api.Event;
|
||||
import net.minecraftforge.fml.LogicalSide;
|
||||
import net.minecraftforge.fml.event.IModBusEvent;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Allows users to register custom {@linkplain IItemDecorator IItemDecorator} to Items.
|
||||
*
|
||||
* <p>This event is not {@linkplain Cancelable cancelable}, and does not {@linkplain HasResult have a result}.
|
||||
*
|
||||
* <p>This event is fired on the {@linkplain FMLJavaModLoadingContext#getModEventBus() mod-specific event bus},
|
||||
* only on the {@linkplain LogicalSide#CLIENT logical client}.</p>
|
||||
*/
|
||||
public class RegisterItemDecorationsEvent extends Event implements IModBusEvent
|
||||
{
|
||||
|
||||
private final Map<Item, List<IItemDecorator>> decorators;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public RegisterItemDecorationsEvent(Map<Item, List<IItemDecorator>> decorators)
|
||||
{
|
||||
this.decorators = decorators;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an ItemDecorator to an Item
|
||||
*/
|
||||
public void register(ItemLike itemLike, IItemDecorator decorator)
|
||||
{
|
||||
List<IItemDecorator> itemDecoratorList = decorators.computeIfAbsent(itemLike.asItem(), item -> new ArrayList<>());
|
||||
itemDecoratorList.add(decorator);
|
||||
}
|
||||
}
|
||||
@@ -275,6 +275,7 @@ public abstract class ScreenEvent extends Event
|
||||
/**
|
||||
* Fired ahead of rendering any active mob effects in the {@link EffectRenderingInventoryScreen inventory screen}.
|
||||
* Can be used to select the size of the effects display (full or compact) or even hide or replace vanilla's rendering entirely.
|
||||
* This event can also be used to modify the horizontal position of the stack of effects being rendered.
|
||||
*
|
||||
* <p>This event is {@linkplain Cancelable cancellable} and does not {@linkplain HasResult have a result}.
|
||||
* Cancelling this event will prevent vanilla rendering.</p>
|
||||
@@ -287,13 +288,15 @@ public abstract class ScreenEvent extends Event
|
||||
{
|
||||
private final int availableSpace;
|
||||
private boolean compact;
|
||||
private int horizontalOffset;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public RenderInventoryMobEffects(Screen screen, int availableSpace, boolean compact)
|
||||
public RenderInventoryMobEffects(Screen screen, int availableSpace, boolean compact, int horizontalOffset)
|
||||
{
|
||||
super(screen);
|
||||
this.availableSpace = availableSpace;
|
||||
this.compact = compact;
|
||||
this.horizontalOffset = horizontalOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -312,6 +315,30 @@ public abstract class ScreenEvent extends Event
|
||||
return compact;
|
||||
}
|
||||
|
||||
/**
|
||||
* The distance from the left side of the screen that the effect stack is rendered. Positive values shift this more to the right.
|
||||
*/
|
||||
public int getHorizontalOffset()
|
||||
{
|
||||
return horizontalOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the horizontal offset of the effect stack
|
||||
*/
|
||||
public void setHorizontalOffset(int offset)
|
||||
{
|
||||
horizontalOffset = offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds to the horizontal offset of the effect stack. Negative values are acceptable.
|
||||
*/
|
||||
public void addHorizontalOffset(int offset)
|
||||
{
|
||||
horizontalOffset += offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the effects should be rendered in compact mode (only icons, no text), or the default full size.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) Forge Development LLC and contributors
|
||||
* SPDX-License-Identifier: LGPL-2.1-only
|
||||
*/
|
||||
|
||||
package net.minecraftforge.client.event;
|
||||
|
||||
import net.minecraft.client.gui.components.toasts.Toast;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.eventbus.api.Cancelable;
|
||||
import net.minecraftforge.eventbus.api.Event;
|
||||
import net.minecraftforge.fml.LogicalSide;
|
||||
|
||||
/**
|
||||
* Fired when the client queues a {@link Toast} message to be shown onscreen.
|
||||
* Toasts are small popups that appear on the top right of the screen, for certain actions such as unlocking Advancements and Recipes.
|
||||
*
|
||||
* <p>This event is {@linkplain Cancelable cancellable}, and does not {@linkplain HasResult have a result}.
|
||||
* Cancelling the event stops the toast from being queued, which means it never renders.</p>
|
||||
*
|
||||
* <p>This event is fired on the {@linkplain MinecraftForge#EVENT_BUS main Forge event bus},
|
||||
* only on the {@linkplain LogicalSide#CLIENT logical client}.</p>
|
||||
*/
|
||||
@Cancelable
|
||||
public class ToastAddEvent extends Event
|
||||
{
|
||||
private final Toast toast;
|
||||
|
||||
public ToastAddEvent(Toast toast)
|
||||
{
|
||||
this.toast = toast;
|
||||
}
|
||||
|
||||
public Toast getToast()
|
||||
{
|
||||
return toast;
|
||||
}
|
||||
}
|
||||
@@ -5,19 +5,24 @@
|
||||
|
||||
package net.minecraftforge.client.extensions.common;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.model.HumanoidModel;
|
||||
import net.minecraft.client.model.Model;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.entity.HumanoidArm;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.client.ForgeHooksClient;
|
||||
import net.minecraftforge.client.IArmPoseTransformer;
|
||||
import net.minecraftforge.fml.LogicalSide;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -57,6 +62,37 @@ public interface IClientItemExtensions
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns an ArmPose that can be defined using the {@link net.minecraft.client.model.HumanoidModel.ArmPose#create(String, boolean, IArmPoseTransformer)} method.
|
||||
* This allows for creating custom item use animations.
|
||||
*
|
||||
* @param entityLiving The entity holding the item
|
||||
* @param hand The hand the ArmPose will be applied to
|
||||
* @param itemStack The stack being held
|
||||
* @return A custom ArmPose that can be used to define movement of the arm
|
||||
*/
|
||||
@Nullable
|
||||
default HumanoidModel.ArmPose getArmPose(LivingEntity entityLiving, InteractionHand hand, ItemStack itemStack)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called right before when client applies transformations to item in hand and render it.
|
||||
*
|
||||
* @param poseStack The pose stack
|
||||
* @param player The player holding the item, it's always main client player
|
||||
* @param arm The arm holding the item
|
||||
* @param itemInHand The held item
|
||||
* @param partialTick Partial tick time, useful for interpolation
|
||||
* @param equipProcess Equip process time, Ranging from 0.0 to 1.0. 0.0 when it's done equipping
|
||||
* @param swingProcess Swing process time, Ranging from 0.0 to 1.0. 0.0 when it's done swinging
|
||||
* @return true if it should skip applying other transforms and go straight to rendering
|
||||
*/
|
||||
default boolean applyForgeHandTransform(PoseStack poseStack, LocalPlayer player, HumanoidArm arm, ItemStack itemInHand, float partialTick, float equipProcess, float swingProcess) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries the humanoid armor model for this item when it's equipped.
|
||||
*
|
||||
|
||||
@@ -516,7 +516,7 @@ public class ForgeGui extends Gui
|
||||
RenderSystem.defaultBlendFunc();
|
||||
int color = (animateOverlayMessageColor ? Mth.hsvToRgb(hue / 50.0F, 0.7F, 0.6F) & WHITE : WHITE);
|
||||
drawBackdrop(pStack, font, -4, font.width(overlayMessageString), 16777215 | (opacity << 24));
|
||||
font.draw(pStack, overlayMessageString.getVisualOrderText(), -font.width(overlayMessageString) / 2, -4, color | (opacity << 24));
|
||||
font.drawShadow(pStack, overlayMessageString.getVisualOrderText(), -font.width(overlayMessageString) / 2, -4, color | (opacity << 24));
|
||||
RenderSystem.disableBlend();
|
||||
pStack.popPose();
|
||||
}
|
||||
|
||||
@@ -25,12 +25,16 @@ import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.minecraft.ResourceLocationException;
|
||||
import net.minecraft.advancements.Advancement;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.commands.Commands;
|
||||
import net.minecraft.commands.SharedSuggestionProvider;
|
||||
import net.minecraft.core.*;
|
||||
import net.minecraft.network.chat.*;
|
||||
import net.minecraft.network.chat.contents.LiteralContents;
|
||||
@@ -145,6 +149,8 @@ import net.minecraftforge.registries.ForgeRegistries;
|
||||
import net.minecraftforge.registries.ForgeRegistry;
|
||||
import net.minecraftforge.registries.GameData;
|
||||
import net.minecraftforge.registries.RegistryManager;
|
||||
import net.minecraftforge.registries.holdersets.ICustomHolderSet;
|
||||
import net.minecraftforge.server.permission.PermissionAPI;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
@@ -152,6 +158,7 @@ import org.apache.logging.log4j.Marker;
|
||||
import org.apache.logging.log4j.MarkerManager;
|
||||
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.resources.HolderSetCodec;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
@@ -1488,4 +1495,13 @@ public class ForgeHooks
|
||||
{
|
||||
return registryKey.getNamespace().equals("minecraft") ? registryKey.getPath() : registryKey.getNamespace() + "/" + registryKey.getPath();
|
||||
}
|
||||
|
||||
public static boolean canUseEntitySelectors(SharedSuggestionProvider provider)
|
||||
{
|
||||
if (provider instanceof CommandSourceStack source && source.getEntity() instanceof ServerPlayer player)
|
||||
{
|
||||
return PermissionAPI.getPermission(player, ForgeMod.USE_SELECTORS_PERMISSION);
|
||||
}
|
||||
return provider.hasPermission(Commands.LEVEL_GAMEMASTERS);
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
import net.minecraft.commands.Commands;
|
||||
import net.minecraft.world.entity.ai.attributes.Attribute;
|
||||
import net.minecraft.world.entity.ai.attributes.RangedAttribute;
|
||||
import net.minecraft.world.entity.item.ItemEntity;
|
||||
@@ -61,6 +62,11 @@ import net.minecraftforge.fml.*;
|
||||
import net.minecraftforge.fml.config.ModConfig;
|
||||
import net.minecraftforge.fml.event.lifecycle.*;
|
||||
import net.minecraftforge.registries.*;
|
||||
import net.minecraftforge.registries.holdersets.AndHolderSet;
|
||||
import net.minecraftforge.registries.holdersets.AnyHolderSet;
|
||||
import net.minecraftforge.registries.holdersets.HolderSetType;
|
||||
import net.minecraftforge.registries.holdersets.NotHolderSet;
|
||||
import net.minecraftforge.registries.holdersets.OrHolderSet;
|
||||
import net.minecraftforge.network.NetworkConstants;
|
||||
import net.minecraftforge.event.server.ServerStoppingEvent;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
@@ -68,6 +74,9 @@ import net.minecraftforge.data.event.GatherDataEvent;
|
||||
import net.minecraftforge.network.filters.VanillaPacketSplitter;
|
||||
import net.minecraftforge.server.command.EnumArgument;
|
||||
import net.minecraftforge.server.command.ModIdArgument;
|
||||
import net.minecraftforge.server.permission.events.PermissionGatherEvent;
|
||||
import net.minecraftforge.server.permission.nodes.PermissionNode;
|
||||
import net.minecraftforge.server.permission.nodes.PermissionTypes;
|
||||
import net.minecraftforge.versions.forge.ForgeVersion;
|
||||
import net.minecraftforge.versions.mcp.MCPVersion;
|
||||
|
||||
@@ -120,6 +129,7 @@ public class ForgeMod
|
||||
private static final DeferredRegister<ArgumentTypeInfo<?, ?>> COMMAND_ARGUMENT_TYPES = DeferredRegister.create(Registry.COMMAND_ARGUMENT_TYPE_REGISTRY, "forge");
|
||||
private static final DeferredRegister<Codec<? extends BiomeModifier>> BIOME_MODIFIER_SERIALIZERS = DeferredRegister.create(ForgeRegistries.Keys.BIOME_MODIFIER_SERIALIZERS, "forge");
|
||||
private static final DeferredRegister<Codec<? extends StructureModifier>> STRUCTURE_MODIFIER_SERIALIZERS = DeferredRegister.create(ForgeRegistries.Keys.STRUCTURE_MODIFIER_SERIALIZERS, "forge");
|
||||
private static final DeferredRegister<HolderSetType> HOLDER_SET_TYPES = DeferredRegister.create(ForgeRegistries.Keys.HOLDER_SET_TYPES, "forge");
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
private static final RegistryObject<EnumArgument.Info> ENUM_COMMAND_ARGUMENT_TYPE = COMMAND_ARGUMENT_TYPES.register("enum", () ->
|
||||
@@ -212,6 +222,27 @@ public class ForgeMod
|
||||
*/
|
||||
public static final RegistryObject<Codec<NoneStructureModifier>> NONE_STRUCTURE_MODIFIER_TYPE = STRUCTURE_MODIFIER_SERIALIZERS.register("none", () -> Codec.unit(NoneStructureModifier.INSTANCE));
|
||||
|
||||
/**
|
||||
* Stock holder set type that represents any/all values in a registry. Can be used in a holderset object with {@code { "type": "forge:any" }}
|
||||
*/
|
||||
public static final RegistryObject<HolderSetType> ANY_HOLDER_SET = HOLDER_SET_TYPES.register("any", () -> AnyHolderSet::codec);
|
||||
|
||||
/**
|
||||
* Stock holder set type that represents an intersection of other holdersets. Can be used in a holderset object with {@code { "type": "forge:and", "values": [list of holdersets] }}
|
||||
*/
|
||||
public static final RegistryObject<HolderSetType> AND_HOLDER_SET = HOLDER_SET_TYPES.register("and", () -> AndHolderSet::codec);
|
||||
|
||||
/**
|
||||
* Stock holder set type that represents a union of other holdersets. Can be used in a holderset object with {@code { "type": "forge:or", "values": [list of holdersets] }}
|
||||
*/
|
||||
public static final RegistryObject<HolderSetType> OR_HOLDER_SET = HOLDER_SET_TYPES.register("or", () -> OrHolderSet::codec);
|
||||
|
||||
/**
|
||||
* <p>Stock holder set type that represents all values in a registry except those in another given set.
|
||||
* Can be used in a holderset object with {@code { "type": "forge:not", "value": holderset }}</p>
|
||||
*/
|
||||
public static final RegistryObject<HolderSetType> NOT_HOLDER_SET = HOLDER_SET_TYPES.register("not", () -> NotHolderSet::codec);
|
||||
|
||||
private static final DeferredRegister<FluidType> VANILLA_FLUID_TYPES = DeferredRegister.create(ForgeRegistries.Keys.FLUID_TYPES, "minecraft");
|
||||
|
||||
public static final RegistryObject<FluidType> EMPTY_TYPE = VANILLA_FLUID_TYPES.register("empty", () ->
|
||||
@@ -418,6 +449,7 @@ public class ForgeMod
|
||||
COMMAND_ARGUMENT_TYPES.register(modEventBus);
|
||||
BIOME_MODIFIER_SERIALIZERS.register(modEventBus);
|
||||
STRUCTURE_MODIFIER_SERIALIZERS.register(modEventBus);
|
||||
HOLDER_SET_TYPES.register(modEventBus);
|
||||
VANILLA_FLUID_TYPES.register(modEventBus);
|
||||
MinecraftForge.EVENT_BUS.addListener(this::serverStopping);
|
||||
MinecraftForge.EVENT_BUS.addListener(this::missingSoundMapping);
|
||||
@@ -433,6 +465,7 @@ public class ForgeMod
|
||||
MinecraftForge.EVENT_BUS.addListener(VillagerTradingManager::loadTrades);
|
||||
MinecraftForge.EVENT_BUS.register(MinecraftForge.INTERNAL_HANDLER);
|
||||
MinecraftForge.EVENT_BUS.addListener(this::mappingChanged);
|
||||
MinecraftForge.EVENT_BUS.addListener(this::registerPermissionNodes);
|
||||
|
||||
ForgeRegistries.ITEMS.tags().addOptionalTagDefaults(Tags.Items.ENCHANTING_FUELS, Set.of(ForgeRegistries.ITEMS.getDelegateOrThrow(Items.LAPIS_LAZULI)));
|
||||
}
|
||||
@@ -574,4 +607,12 @@ public class ForgeMod
|
||||
event.register(Registry.LOOT_ITEM_REGISTRY, new ResourceLocation("forge:loot_table_id"), () -> LootTableIdCondition.LOOT_TABLE_ID);
|
||||
event.register(Registry.LOOT_ITEM_REGISTRY, new ResourceLocation("forge:can_tool_perform_action"), () -> CanToolPerformAction.LOOT_CONDITION_TYPE);
|
||||
}
|
||||
|
||||
public static final PermissionNode<Boolean> USE_SELECTORS_PERMISSION = new PermissionNode<>("forge", "use_entity_selectors",
|
||||
PermissionTypes.BOOLEAN, (player, uuid, contexts) -> player != null && player.hasPermissions(Commands.LEVEL_GAMEMASTERS));
|
||||
|
||||
public void registerPermissionNodes(PermissionGatherEvent.Nodes event)
|
||||
{
|
||||
event.addNodes(USE_SELECTORS_PERMISSION);
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,7 @@ public class MinecraftForge
|
||||
* ORE_GEN_BUS for ore gen events
|
||||
* EVENT_BUS for everything else
|
||||
*/
|
||||
public static final IEventBus EVENT_BUS = BusBuilder.builder().startShutdown().build();
|
||||
public static final IEventBus EVENT_BUS = BusBuilder.builder().startShutdown().useModLauncher().build();
|
||||
|
||||
static final ForgeInternalHandler INTERNAL_HANDLER = new ForgeInternalHandler();
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
@@ -394,6 +394,125 @@ public class Tags
|
||||
public static final TagKey<Item> STORAGE_BLOCKS_RAW_IRON = tag("storage_blocks/raw_iron");
|
||||
public static final TagKey<Item> STORAGE_BLOCKS_REDSTONE = tag("storage_blocks/redstone");
|
||||
public static final TagKey<Item> STRING = tag("string");
|
||||
/**
|
||||
* A tag containing all existing tools.
|
||||
*
|
||||
* Note: This tag is not an alternative or a substitute to {@link net.minecraftforge.common.ToolActions}.
|
||||
*
|
||||
* @see net.minecraftforge.common.ToolAction
|
||||
* @see net.minecraftforge.common.ToolActions
|
||||
*/
|
||||
public static final TagKey<Item> TOOLS = tag("tools");
|
||||
/**
|
||||
* A tag containing all existing swords.
|
||||
*
|
||||
* Note: This tag is not an alternative or a substitute to {@link net.minecraftforge.common.ToolActions}.
|
||||
*
|
||||
* @see net.minecraftforge.common.ToolAction
|
||||
* @see net.minecraftforge.common.ToolActions
|
||||
*/
|
||||
public static final TagKey<Item> TOOLS_SWORDS = tag("tools/swords");
|
||||
/**
|
||||
* A tag containing all existing axes.
|
||||
*
|
||||
* Note: This tag is not an alternative or a substitute to {@link net.minecraftforge.common.ToolActions}.
|
||||
*
|
||||
* @see net.minecraftforge.common.ToolAction
|
||||
* @see net.minecraftforge.common.ToolActions
|
||||
*/
|
||||
public static final TagKey<Item> TOOLS_AXES = tag("tools/axes");
|
||||
/**
|
||||
* A tag containing all existing pickaxes.
|
||||
*
|
||||
* Note: This tag is not an alternative or a substitute to {@link net.minecraftforge.common.ToolActions}.
|
||||
*
|
||||
* @see net.minecraftforge.common.ToolAction
|
||||
* @see net.minecraftforge.common.ToolActions
|
||||
*/
|
||||
public static final TagKey<Item> TOOLS_PICKAXES = tag("tools/pickaxes");
|
||||
/**
|
||||
* A tag containing all existing shovels.
|
||||
*
|
||||
* Note: This tag is not an alternative or a substitute to {@link net.minecraftforge.common.ToolActions}.
|
||||
*
|
||||
* @see net.minecraftforge.common.ToolAction
|
||||
* @see net.minecraftforge.common.ToolActions
|
||||
*/
|
||||
public static final TagKey<Item> TOOLS_SHOVELS = tag("tools/shovels");
|
||||
/**
|
||||
* A tag containing all existing hoes.
|
||||
*
|
||||
* Note: This tag is not an alternative or a substitute to {@link net.minecraftforge.common.ToolActions}.
|
||||
*
|
||||
* @see net.minecraftforge.common.ToolAction
|
||||
* @see net.minecraftforge.common.ToolActions
|
||||
*/
|
||||
public static final TagKey<Item> TOOLS_HOES = tag("tools/hoes");
|
||||
/**
|
||||
* A tag containing all existing shields.
|
||||
*
|
||||
* Note: This tag is not an alternative or a substitute to {@link net.minecraftforge.common.ToolActions}.
|
||||
*
|
||||
* @see net.minecraftforge.common.ToolAction
|
||||
* @see net.minecraftforge.common.ToolActions
|
||||
*/
|
||||
public static final TagKey<Item> TOOLS_SHIELDS = tag("tools/shields");
|
||||
/**
|
||||
* A tag containing all existing bows.
|
||||
*
|
||||
* Note: This tag is not an alternative or a substitute to {@link net.minecraftforge.common.ToolActions}.
|
||||
*
|
||||
* @see net.minecraftforge.common.ToolAction
|
||||
* @see net.minecraftforge.common.ToolActions
|
||||
*/
|
||||
public static final TagKey<Item> TOOLS_BOWS = tag("tools/bows");
|
||||
/**
|
||||
* A tag containing all existing crossbows.
|
||||
*
|
||||
* Note: This tag is not an alternative or a substitute to {@link net.minecraftforge.common.ToolActions}.
|
||||
*
|
||||
* @see net.minecraftforge.common.ToolAction
|
||||
* @see net.minecraftforge.common.ToolActions
|
||||
*/
|
||||
public static final TagKey<Item> TOOLS_CROSSBOWS = tag("tools/crossbows");
|
||||
/**
|
||||
* A tag containing all existing fishing rods.
|
||||
*
|
||||
* Note: This tag is not an alternative or a substitute to {@link net.minecraftforge.common.ToolActions}.
|
||||
*
|
||||
* @see net.minecraftforge.common.ToolAction
|
||||
* @see net.minecraftforge.common.ToolActions
|
||||
*/
|
||||
public static final TagKey<Item> TOOLS_FISHING_RODS = tag("tools/fishing_rods");
|
||||
/**
|
||||
* A tag containing all existing tridents.
|
||||
*
|
||||
* Note: This tag is not an alternative or a substitute to {@link net.minecraftforge.common.ToolActions}.
|
||||
*
|
||||
* @see net.minecraftforge.common.ToolAction
|
||||
* @see net.minecraftforge.common.ToolActions
|
||||
*/
|
||||
public static final TagKey<Item> TOOLS_TRIDENTS = tag("tools/tridents");
|
||||
/**
|
||||
* A tag containing all existing armors.
|
||||
*/
|
||||
public static final TagKey<Item> ARMORS = tag("armors");
|
||||
/**
|
||||
* A tag containing all existing helmets.
|
||||
*/
|
||||
public static final TagKey<Item> ARMORS_HELMETS = tag("armors/helmets");
|
||||
/**
|
||||
* A tag containing all chestplates.
|
||||
*/
|
||||
public static final TagKey<Item> ARMORS_CHESTPLATES = tag("armors/chestplates");
|
||||
/**
|
||||
* A tag containing all existing leggings.
|
||||
*/
|
||||
public static final TagKey<Item> ARMORS_LEGGINGS = tag("armors/leggings");
|
||||
/**
|
||||
* A tag containing all existing boots.
|
||||
*/
|
||||
public static final TagKey<Item> ARMORS_BOOTS = tag("armors/boots");
|
||||
|
||||
private static TagKey<Item> tag(String name)
|
||||
{
|
||||
|
||||
@@ -37,6 +37,7 @@ public final class ForgeBiomeTagsProvider extends BiomeTagsProvider
|
||||
tag(Biomes.MUSHROOM_FIELDS, Tags.Biomes.IS_MUSHROOM, Tags.Biomes.IS_RARE);
|
||||
tag(Biomes.JUNGLE, Tags.Biomes.IS_HOT_OVERWORLD, Tags.Biomes.IS_WET_OVERWORLD, Tags.Biomes.IS_DENSE_OVERWORLD);
|
||||
tag(Biomes.SPARSE_JUNGLE, Tags.Biomes.IS_HOT_OVERWORLD, Tags.Biomes.IS_WET_OVERWORLD, Tags.Biomes.IS_RARE);
|
||||
tag(Biomes.BEACH, Tags.Biomes.IS_WET_OVERWORLD, Tags.Biomes.IS_SANDY);
|
||||
tag(Biomes.SNOWY_BEACH, Tags.Biomes.IS_COLD_OVERWORLD, Tags.Biomes.IS_SNOWY);
|
||||
tag(Biomes.DARK_FOREST, Tags.Biomes.IS_SPOOKY, Tags.Biomes.IS_DENSE_OVERWORLD);
|
||||
tag(Biomes.SNOWY_TAIGA, Tags.Biomes.IS_COLD_OVERWORLD, Tags.Biomes.IS_CONIFEROUS, Tags.Biomes.IS_SNOWY);
|
||||
|
||||
@@ -153,6 +153,22 @@ public final class ForgeItemTagsProvider extends ItemTagsProvider
|
||||
copy(Tags.Blocks.STORAGE_BLOCKS_RAW_IRON, Tags.Items.STORAGE_BLOCKS_RAW_IRON);
|
||||
copy(Tags.Blocks.STORAGE_BLOCKS_NETHERITE, Tags.Items.STORAGE_BLOCKS_NETHERITE);
|
||||
tag(Tags.Items.STRING).add(Items.STRING);
|
||||
tag(Tags.Items.TOOLS_SWORDS).add(Items.WOODEN_SWORD, Items.STONE_SWORD, Items.IRON_SWORD, Items.GOLDEN_SWORD, Items.DIAMOND_SWORD, Items.NETHERITE_SWORD);
|
||||
tag(Tags.Items.TOOLS_AXES).add(Items.WOODEN_AXE, Items.STONE_AXE, Items.IRON_AXE, Items.GOLDEN_AXE, Items.DIAMOND_AXE, Items.NETHERITE_AXE);
|
||||
tag(Tags.Items.TOOLS_PICKAXES).add(Items.WOODEN_PICKAXE, Items.STONE_PICKAXE, Items.IRON_PICKAXE, Items.GOLDEN_PICKAXE, Items.DIAMOND_PICKAXE, Items.NETHERITE_PICKAXE);
|
||||
tag(Tags.Items.TOOLS_SHOVELS).add(Items.WOODEN_SHOVEL, Items.STONE_SHOVEL, Items.IRON_SHOVEL, Items.GOLDEN_SHOVEL, Items.DIAMOND_SHOVEL, Items.NETHERITE_SHOVEL);
|
||||
tag(Tags.Items.TOOLS_HOES).add(Items.WOODEN_HOE, Items.STONE_HOE, Items.IRON_HOE, Items.GOLDEN_HOE, Items.DIAMOND_HOE, Items.NETHERITE_HOE);
|
||||
tag(Tags.Items.TOOLS_SHIELDS).add(Items.SHIELD);
|
||||
tag(Tags.Items.TOOLS_BOWS).add(Items.BOW);
|
||||
tag(Tags.Items.TOOLS_CROSSBOWS).add(Items.CROSSBOW);
|
||||
tag(Tags.Items.TOOLS_FISHING_RODS).add(Items.FISHING_ROD);
|
||||
tag(Tags.Items.TOOLS_TRIDENTS).add(Items.TRIDENT);
|
||||
tag(Tags.Items.TOOLS).addTags(Tags.Items.TOOLS_SWORDS, Tags.Items.TOOLS_AXES, Tags.Items.TOOLS_PICKAXES, Tags.Items.TOOLS_SHOVELS, Tags.Items.TOOLS_HOES, Tags.Items.TOOLS_SHIELDS, Tags.Items.TOOLS_BOWS, Tags.Items.TOOLS_CROSSBOWS, Tags.Items.TOOLS_FISHING_RODS, Tags.Items.TOOLS_TRIDENTS);
|
||||
tag(Tags.Items.ARMORS_HELMETS).add(Items.LEATHER_HELMET, Items.TURTLE_HELMET, Items.CHAINMAIL_HELMET, Items.IRON_HELMET, Items.GOLDEN_HELMET, Items.DIAMOND_HELMET, Items.NETHERITE_HELMET);
|
||||
tag(Tags.Items.ARMORS_CHESTPLATES).add(Items.LEATHER_CHESTPLATE, Items.CHAINMAIL_CHESTPLATE, Items.IRON_CHESTPLATE, Items.GOLDEN_CHESTPLATE, Items.DIAMOND_CHESTPLATE, Items.NETHERITE_CHESTPLATE);
|
||||
tag(Tags.Items.ARMORS_LEGGINGS).add(Items.LEATHER_LEGGINGS, Items.CHAINMAIL_LEGGINGS, Items.IRON_LEGGINGS, Items.GOLDEN_LEGGINGS, Items.DIAMOND_LEGGINGS, Items.NETHERITE_LEGGINGS);
|
||||
tag(Tags.Items.ARMORS_BOOTS).add(Items.LEATHER_BOOTS, Items.CHAINMAIL_BOOTS, Items.IRON_BOOTS, Items.GOLDEN_BOOTS, Items.DIAMOND_BOOTS, Items.NETHERITE_BOOTS);
|
||||
tag(Tags.Items.ARMORS).addTags(Tags.Items.ARMORS_HELMETS, Tags.Items.ARMORS_CHESTPLATES, Tags.Items.ARMORS_LEGGINGS, Tags.Items.ARMORS_BOOTS);
|
||||
}
|
||||
|
||||
private void addColored(Consumer<TagKey<Item>> consumer, TagKey<Item> group, String pattern)
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.network.Connection;
|
||||
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
@@ -174,4 +175,15 @@ public interface IForgeBlockEntity extends ICapabilitySerializable<CompoundTag>
|
||||
{
|
||||
return ModelData.EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this {@link BlockEntity} has custom outline rendering behavior.
|
||||
*
|
||||
* @param player the local player currently viewing this {@code BlockEntity}
|
||||
* @return {@code true} to enable outline processing
|
||||
*/
|
||||
default boolean hasCustomOutlineRendering(Player player)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.ai.attributes.AttributeInstance;
|
||||
import net.minecraft.world.entity.boss.enderdragon.EnderDragon;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
@@ -410,4 +411,17 @@ public interface IForgeEntity extends ICapabilitySerializable<CompoundTag>
|
||||
{
|
||||
return type.getSound(self(), action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this {@link Entity} has custom outline rendering behavior which does
|
||||
* not use the existing automatic outline rendering based on {@link Entity#isCurrentlyGlowing()}
|
||||
* and the entity's team color.
|
||||
*
|
||||
* @param player the local player currently viewing this {@code Entity}
|
||||
* @return {@code true} to enable outline processing
|
||||
*/
|
||||
default boolean hasCustomOutlineRendering(Player player)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) Forge Development LLC and contributors
|
||||
* SPDX-License-Identifier: LGPL-2.1-only
|
||||
*/
|
||||
|
||||
package net.minecraftforge.common.extensions;
|
||||
|
||||
public interface IForgeHolderSet<T>
|
||||
{
|
||||
/**
|
||||
* <p>Adds a callback to run when this holderset's contents invalidate (i.e. because tags were rebound).</p>
|
||||
*
|
||||
* <p>The intended usage and use case is with composite holdersets that need to cache sets/list based on other
|
||||
* holdersets, which may be mutable (because they are tag-based or themselves composite holdersets).
|
||||
* Composite holdersets should use this to add callbacks to each of their component holdersets when constructed.</p>
|
||||
*
|
||||
* @param runnable Runnable to invoke when this component holderset's contents are no longer valid.
|
||||
* This runnable should only clear caches and allow them to be lazily reevaluated later,
|
||||
* as not all tag holdersets may have been rebound when this is called.
|
||||
* This runnable should also invalidate all of the caller's listeners.
|
||||
*/
|
||||
default public void addInvalidationListener(Runnable runnable)
|
||||
{
|
||||
// noop by default, mutable/composite holdersets must override
|
||||
}
|
||||
}
|
||||
@@ -81,8 +81,6 @@ public class FakePlayer extends ServerPlayer
|
||||
this.connection = new FakePlayerNetHandler(level.getServer(), this);
|
||||
}
|
||||
|
||||
@Override public Vec3 position() { return new Vec3(0, 0, 0); }
|
||||
@Override public BlockPos blockPosition() { return BlockPos.ZERO; }
|
||||
@Override public void displayClientMessage(Component chatComponent, boolean actionBar) { }
|
||||
@Override public void awardStat(Stat stat, int amount) { }
|
||||
@Override public boolean isInvulnerableTo(DamageSource source) { return true; }
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) Forge Development LLC and contributors
|
||||
* SPDX-License-Identifier: LGPL-2.1-only
|
||||
*/
|
||||
|
||||
package net.minecraftforge.common.world;
|
||||
|
||||
import net.minecraft.world.level.levelgen.structure.BoundingBox;
|
||||
|
||||
@@ -14,7 +14,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
*
|
||||
* AnvilUpdateEvent is fired when the inputs (either input stack, or the name) to an anvil are changed. <br>
|
||||
* AnvilUpdateEvent is fired whenever the input stacks (left or right) or the name in an anvil changed. <br>
|
||||
* It is called from {@link AnvilMenu#createResult()}. <br>
|
||||
* If the event is canceled, vanilla behavior will not run, and the output will be set to {@link ItemStack#EMPTY}. <br>
|
||||
* If the event is not canceled, but the output is not empty, it will set the output and not run vanilla behavior. <br>
|
||||
|
||||
@@ -16,11 +16,15 @@ import com.mojang.brigadier.CommandDispatcher;
|
||||
import net.minecraft.commands.CommandBuildContext;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.ReloadableServerResources;
|
||||
import net.minecraft.server.level.ChunkHolder;
|
||||
import net.minecraft.server.players.PlayerList;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.util.random.WeightedRandomList;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.entity.MobCategory;
|
||||
import net.minecraft.world.entity.projectile.Projectile;
|
||||
import net.minecraft.world.entity.projectile.ThrownEnderpearl;
|
||||
import net.minecraft.world.level.biome.MobSpawnSettings;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import net.minecraft.world.level.portal.PortalShape;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
@@ -115,6 +119,7 @@ import net.minecraftforge.event.level.BlockEvent.CreateFluidSourceEvent;
|
||||
import net.minecraftforge.event.level.BlockEvent.EntityMultiPlaceEvent;
|
||||
import net.minecraftforge.event.level.BlockEvent.EntityPlaceEvent;
|
||||
import net.minecraftforge.event.level.BlockEvent.NeighborNotifyEvent;
|
||||
import net.minecraftforge.event.level.ChunkTicketLevelUpdatedEvent;
|
||||
import net.minecraftforge.event.level.ChunkWatchEvent;
|
||||
import net.minecraftforge.event.level.ExplosionEvent;
|
||||
import net.minecraftforge.event.level.PistonEvent;
|
||||
@@ -607,6 +612,12 @@ public class ForgeEventFactory
|
||||
return event.getResult() != Result.DENY;
|
||||
}
|
||||
|
||||
public static void fireChunkTicketLevelUpdated(ServerLevel level, long chunkPos, int oldTicketLevel, int newTicketLevel, @Nullable ChunkHolder chunkHolder)
|
||||
{
|
||||
if (oldTicketLevel != newTicketLevel)
|
||||
MinecraftForge.EVENT_BUS.post(new ChunkTicketLevelUpdatedEvent(level, chunkPos, oldTicketLevel, newTicketLevel, chunkHolder));
|
||||
}
|
||||
|
||||
public static void fireChunkWatch(ServerPlayer entity, LevelChunk chunk, ServerLevel level)
|
||||
{
|
||||
MinecraftForge.EVENT_BUS.post(new ChunkWatchEvent.Watch(entity, chunk, level));
|
||||
@@ -801,4 +812,12 @@ public class ForgeEventFactory
|
||||
{
|
||||
MinecraftForge.EVENT_BUS.post(new TickEvent.ServerTickEvent(TickEvent.Phase.END, haveTime, server));
|
||||
}
|
||||
|
||||
public static WeightedRandomList<MobSpawnSettings.SpawnerData> getPotentialSpawns(LevelAccessor level, MobCategory category, BlockPos pos, WeightedRandomList<MobSpawnSettings.SpawnerData> oldList)
|
||||
{
|
||||
LevelEvent.PotentialSpawns event = new LevelEvent.PotentialSpawns(level, category, pos, oldList);
|
||||
if (MinecraftForge.EVENT_BUS.post(event))
|
||||
return WeightedRandomList.create();
|
||||
return WeightedRandomList.create(event.getSpawnerDataList());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) Forge Development LLC and contributors
|
||||
* SPDX-License-Identifier: LGPL-2.1-only
|
||||
*/
|
||||
|
||||
package net.minecraftforge.event.level;
|
||||
|
||||
import net.minecraft.server.level.ChunkHolder;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.eventbus.api.Cancelable;
|
||||
import net.minecraftforge.eventbus.api.Event;
|
||||
import net.minecraftforge.fml.LogicalSide;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* This event is fired whenever a chunk has its ticket level changed via the server's ChunkMap.
|
||||
* <p>
|
||||
* This event does not fire if the new ticket level is the same as the old level, or if both the
|
||||
* new <strong>AND</strong> old ticket levels represent values past the max chunk distance.
|
||||
* <p>
|
||||
* Due to how vanilla processes ticket level changes this event may be fired "twice" in one tick for the same chunk.
|
||||
* The scenario where this happens is when increasing the level from say 31 (ticking) to 32, the way vanilla does it
|
||||
* is by first changing it from 31 to 46, and then queuing the update from 46 to 32. However, when going from 32 to 31,
|
||||
* vanilla is able to go directly.
|
||||
* <p>
|
||||
* This event is not {@linkplain Cancelable cancellable} and does not {@linkplain HasResult have a result}.
|
||||
* <p>
|
||||
* This event is fired on the {@linkplain MinecraftForge#EVENT_BUS main Forge event bus}
|
||||
* only on the {@linkplain LogicalSide#SERVER logical server}.
|
||||
**/
|
||||
public class ChunkTicketLevelUpdatedEvent extends Event
|
||||
{
|
||||
private final ServerLevel level;
|
||||
private final long chunkPos;
|
||||
private final int oldTicketLevel;
|
||||
private final int newTicketLevel;
|
||||
@Nullable
|
||||
private final ChunkHolder chunkHolder;
|
||||
|
||||
public ChunkTicketLevelUpdatedEvent(ServerLevel level, long chunkPos, int oldTicketLevel, int newTicketLevel, @Nullable ChunkHolder chunkHolder)
|
||||
{
|
||||
this.level = level;
|
||||
this.chunkPos = chunkPos;
|
||||
this.oldTicketLevel = oldTicketLevel;
|
||||
this.newTicketLevel = newTicketLevel;
|
||||
this.chunkHolder = chunkHolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the server level containing the chunk}
|
||||
*/
|
||||
public ServerLevel getLevel()
|
||||
{
|
||||
return this.level;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the long representation of the chunk position the ticket level changed for}
|
||||
*/
|
||||
public long getChunkPos()
|
||||
{
|
||||
return this.chunkPos;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the previous ticket level the chunk had}
|
||||
*/
|
||||
public int getOldTicketLevel()
|
||||
{
|
||||
return this.oldTicketLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the new ticket level for the chunk}
|
||||
*/
|
||||
public int getNewTicketLevel()
|
||||
{
|
||||
return this.newTicketLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return chunk that had its ticket level updated}
|
||||
*/
|
||||
@Nullable
|
||||
public ChunkHolder getChunkHolder()
|
||||
{
|
||||
return this.chunkHolder;
|
||||
}
|
||||
}
|
||||
@@ -5,13 +5,21 @@
|
||||
|
||||
package net.minecraftforge.event.level;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.ProgressListener;
|
||||
import net.minecraft.util.random.WeightedRandomList;
|
||||
import net.minecraft.world.entity.MobCategory;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.biome.MobSpawnSettings;
|
||||
import net.minecraft.world.level.storage.ServerLevelData;
|
||||
import net.minecraftforge.common.ForgeInternalHandler;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
@@ -117,4 +125,83 @@ public class LevelEvent extends Event
|
||||
return settings;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fired when building a list of all possible entities that can spawn at the specified location.
|
||||
*
|
||||
* <p>If an entry is added to the list, it needs to be a globally unique instance.</p>
|
||||
*
|
||||
* The event is called in {@link net.minecraft.world.level.NaturalSpawner#mobsAt(ServerLevel,
|
||||
* StructureManager, ChunkGenerator, MobCategory, RandomSource, BlockPos)}.</p>
|
||||
*
|
||||
* <p>This event is {@linkplain Cancelable cancellable}, and does not {@linkplain HasResult have a result}.
|
||||
* Canceling the event will result in an empty list, meaning no entity will be spawned.</p>
|
||||
*/
|
||||
@Cancelable
|
||||
public static class PotentialSpawns extends LevelEvent
|
||||
{
|
||||
private final MobCategory mobcategory;
|
||||
private final BlockPos pos;
|
||||
private final List<MobSpawnSettings.SpawnerData> list;
|
||||
private final List<MobSpawnSettings.SpawnerData> view;
|
||||
|
||||
public PotentialSpawns(LevelAccessor level, MobCategory category, BlockPos pos, WeightedRandomList<MobSpawnSettings.SpawnerData> oldList)
|
||||
{
|
||||
super(level);
|
||||
this.pos = pos;
|
||||
this.mobcategory = category;
|
||||
if (!oldList.isEmpty())
|
||||
this.list = new ArrayList<>(oldList.unwrap());
|
||||
else
|
||||
this.list = new ArrayList<>();
|
||||
|
||||
this.view = Collections.unmodifiableList(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the category of the mobs in the spawn list.}
|
||||
*/
|
||||
public MobCategory getMobCategory()
|
||||
{
|
||||
return mobcategory;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the block position where the chosen mob will be spawned.}
|
||||
*/
|
||||
public BlockPos getPos()
|
||||
{
|
||||
return pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the list of mobs that can potentially be spawned.}
|
||||
*/
|
||||
public List<MobSpawnSettings.SpawnerData> getSpawnerDataList()
|
||||
{
|
||||
return view;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a SpawnerData entry to the spawn list.
|
||||
*
|
||||
* @param data SpawnerData entry to be appended to the spawn list.
|
||||
*/
|
||||
public void addSpawnerData(MobSpawnSettings.SpawnerData data)
|
||||
{
|
||||
list.add(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a SpawnerData entry from the spawn list.
|
||||
*
|
||||
* @param data SpawnerData entry to be removed from the spawn list.
|
||||
*
|
||||
* {@return {@code true} if the spawn list contained the specified element.}
|
||||
*/
|
||||
public boolean removeSpawnerData(MobSpawnSettings.SpawnerData data)
|
||||
{
|
||||
return list.remove(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,83 +5,24 @@
|
||||
|
||||
package net.minecraftforge.network;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Reference2ReferenceArrayMap;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.protocol.login.ServerboundCustomQueryPacket;
|
||||
import net.minecraft.network.protocol.login.ClientboundCustomQueryPacket;
|
||||
import net.minecraft.network.protocol.game.ServerboundCustomPayloadPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundCustomPayloadPacket;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.fml.unsafe.UnsafeHacks;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public interface ICustomPacket<T extends Packet<?>> {
|
||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||
enum Fields {
|
||||
CPACKETCUSTOMPAYLOAD(ServerboundCustomPayloadPacket.class),
|
||||
SPACKETCUSTOMPAYLOAD(ClientboundCustomPayloadPacket.class),
|
||||
CPACKETCUSTOMLOGIN(ServerboundCustomQueryPacket.class),
|
||||
SPACKETCUSTOMLOGIN(ClientboundCustomQueryPacket.class),
|
||||
;
|
||||
/**
|
||||
* Returns a unsafe reference to this packet's internal data.
|
||||
* Any modifications to this buffer will be reflected in the main buffer.
|
||||
*/
|
||||
@Nullable
|
||||
FriendlyByteBuf getInternalData();
|
||||
|
||||
static final Reference2ReferenceArrayMap<Class<?>, Fields> lookup;
|
||||
static {
|
||||
lookup = Stream.of(values()).
|
||||
collect(Collectors.toMap(Fields::getClazz, Function.identity(), (m1, m2)->m1, Reference2ReferenceArrayMap::new));
|
||||
}
|
||||
ResourceLocation getName();
|
||||
|
||||
private final Class<?> clazz;
|
||||
|
||||
final Optional<Field> data;
|
||||
final Optional<Field> channel;
|
||||
final Optional<Field> index;
|
||||
|
||||
Fields(Class<?> customPacketClass)
|
||||
{
|
||||
this.clazz = customPacketClass;
|
||||
Field[] fields = customPacketClass.getDeclaredFields();
|
||||
data = Arrays.stream(fields).filter(f-> !Modifier.isStatic(f.getModifiers()) && f.getType() == FriendlyByteBuf.class).findFirst();
|
||||
channel = Arrays.stream(fields).filter(f->!Modifier.isStatic(f.getModifiers()) && f.getType() == ResourceLocation.class).findFirst();
|
||||
index = Arrays.stream(fields).filter(f->!Modifier.isStatic(f.getModifiers()) && f.getType() == int.class).findFirst();
|
||||
}
|
||||
|
||||
private Class<?> getClazz()
|
||||
{
|
||||
return clazz;
|
||||
}
|
||||
}
|
||||
|
||||
default FriendlyByteBuf getInternalData() {
|
||||
return Fields.lookup.get(this.getClass()).data.map(f->UnsafeHacks.<FriendlyByteBuf>getField(f, this)).orElse(null);
|
||||
}
|
||||
|
||||
default ResourceLocation getName() {
|
||||
return Fields.lookup.get(this.getClass()).channel.map(f->UnsafeHacks.<ResourceLocation>getField(f, this)).orElse(LoginWrapper.WRAPPER);
|
||||
}
|
||||
|
||||
default int getIndex() {
|
||||
return Fields.lookup.get(this.getClass()).index.map(f->UnsafeHacks.getIntField(f, this)).orElse(Integer.MIN_VALUE);
|
||||
}
|
||||
|
||||
default void setData(FriendlyByteBuf buffer) {
|
||||
Fields.lookup.get(this.getClass()).data.ifPresent(f->UnsafeHacks.setField(f, this, buffer));
|
||||
}
|
||||
|
||||
default void setName(ResourceLocation channelName) {
|
||||
Fields.lookup.get(this.getClass()).channel.ifPresent(f->UnsafeHacks.setField(f, this, channelName));
|
||||
}
|
||||
|
||||
default void setIndex(int index) {
|
||||
Fields.lookup.get(this.getClass()).index.ifPresent(f->UnsafeHacks.setIntField(f, this, index));
|
||||
}
|
||||
int getIndex();
|
||||
|
||||
default NetworkDirection getDirection() {
|
||||
return NetworkDirection.directionFor(this.getClass());
|
||||
|
||||
@@ -13,6 +13,7 @@ import net.minecraftforge.network.event.EventNetworkChannel;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
/**
|
||||
* Wrapper for custom login packets. Transforms unnamed login channel messages into channels dispatched the same
|
||||
@@ -21,7 +22,8 @@ import org.apache.logging.log4j.Logger;
|
||||
public class LoginWrapper
|
||||
{
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
static final ResourceLocation WRAPPER = new ResourceLocation("fml:loginwrapper");
|
||||
@ApiStatus.Internal
|
||||
public static final ResourceLocation WRAPPER = new ResourceLocation("fml:loginwrapper");
|
||||
private EventNetworkChannel wrapperChannel;
|
||||
|
||||
LoginWrapper() {
|
||||
|
||||
@@ -32,12 +32,14 @@ public class MCRegisterPacketHandler
|
||||
|
||||
public static class ChannelList {
|
||||
private Set<ResourceLocation> locations = new HashSet<>();
|
||||
private Set<ResourceLocation> remoteLocations = Set.of();
|
||||
|
||||
public void updateFrom(final Supplier<NetworkEvent.Context> source, FriendlyByteBuf buffer, final NetworkEvent.RegistrationChangeType changeType) {
|
||||
byte[] data = new byte[Math.max(buffer.readableBytes(), 0)];
|
||||
buffer.readBytes(data);
|
||||
Set<ResourceLocation> oldLocations = this.locations;
|
||||
this.locations = bytesToResLocation(data);
|
||||
this.remoteLocations = Set.copyOf(this.locations);
|
||||
// ensure all locations receive updates, old and new.
|
||||
oldLocations.addAll(this.locations);
|
||||
oldLocations.stream()
|
||||
@@ -76,6 +78,14 @@ public class MCRegisterPacketHandler
|
||||
}
|
||||
return rl;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the unmodifiable set of channel locations sent by the remote side}
|
||||
* This is useful for interacting with other modloaders via the network to inspect registered network channel IDs.
|
||||
*/
|
||||
public Set<ResourceLocation> getRemoteLocations() {
|
||||
return this.remoteLocations;
|
||||
}
|
||||
}
|
||||
|
||||
public void addChannels(Set<ResourceLocation> locations, Connection manager) {
|
||||
|
||||
@@ -14,7 +14,6 @@ import net.minecraft.network.protocol.game.ServerboundCustomPayloadPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundCustomPayloadPacket;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.fml.LogicalSide;
|
||||
import net.minecraftforge.fml.unsafe.UnsafeHacks;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
@@ -25,15 +24,16 @@ import java.util.stream.Stream;
|
||||
|
||||
public enum NetworkDirection
|
||||
{
|
||||
PLAY_TO_SERVER(NetworkEvent.ClientCustomPayloadEvent::new, LogicalSide.CLIENT, ServerboundCustomPayloadPacket.class, 1),
|
||||
PLAY_TO_CLIENT(NetworkEvent.ServerCustomPayloadEvent::new, LogicalSide.SERVER, ClientboundCustomPayloadPacket.class, 0),
|
||||
LOGIN_TO_SERVER(NetworkEvent.ClientCustomPayloadLoginEvent::new, LogicalSide.CLIENT, ServerboundCustomQueryPacket.class, 3),
|
||||
LOGIN_TO_CLIENT(NetworkEvent.ServerCustomPayloadLoginEvent::new, LogicalSide.SERVER, ClientboundCustomQueryPacket.class, 2);
|
||||
PLAY_TO_SERVER(NetworkEvent.ClientCustomPayloadEvent::new, LogicalSide.CLIENT, ServerboundCustomPayloadPacket.class, 1, (d, i, n) -> new ServerboundCustomPayloadPacket(n, d)),
|
||||
PLAY_TO_CLIENT(NetworkEvent.ServerCustomPayloadEvent::new, LogicalSide.SERVER, ClientboundCustomPayloadPacket.class, 0, (d, i, n) -> new ClientboundCustomPayloadPacket(n, d)),
|
||||
LOGIN_TO_SERVER(NetworkEvent.ClientCustomPayloadLoginEvent::new, LogicalSide.CLIENT, ServerboundCustomQueryPacket.class, 3, (d, i, n) -> new ServerboundCustomQueryPacket(i, d)),
|
||||
LOGIN_TO_CLIENT(NetworkEvent.ServerCustomPayloadLoginEvent::new, LogicalSide.SERVER, ClientboundCustomQueryPacket.class, 2, (d, i, n) -> new ClientboundCustomQueryPacket(i, n, d));
|
||||
|
||||
private final BiFunction<ICustomPacket<?>, Supplier<NetworkEvent.Context>, NetworkEvent> eventSupplier;
|
||||
private final LogicalSide logicalSide;
|
||||
private final Class<? extends Packet> packetClass;
|
||||
private final int otherWay;
|
||||
private final Factory factory;
|
||||
|
||||
private static final Reference2ReferenceArrayMap<Class<? extends Packet>, NetworkDirection> packetLookup;
|
||||
|
||||
@@ -42,12 +42,13 @@ public enum NetworkDirection
|
||||
collect(Collectors.toMap(NetworkDirection::getPacketClass, Function.identity(), (m1,m2)->m1, Reference2ReferenceArrayMap::new));
|
||||
}
|
||||
|
||||
NetworkDirection(BiFunction<ICustomPacket<?>, Supplier<NetworkEvent.Context>, NetworkEvent> eventSupplier, LogicalSide logicalSide, Class<? extends Packet> clazz, int i)
|
||||
private NetworkDirection(BiFunction<ICustomPacket<?>, Supplier<NetworkEvent.Context>, NetworkEvent> eventSupplier, LogicalSide logicalSide, Class<? extends Packet> clazz, int i, Factory factory)
|
||||
{
|
||||
this.eventSupplier = eventSupplier;
|
||||
this.logicalSide = logicalSide;
|
||||
this.packetClass = clazz;
|
||||
this.otherWay = i;
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
private Class<? extends Packet> getPacketClass() {
|
||||
@@ -75,10 +76,10 @@ public enum NetworkDirection
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Packet<?>> ICustomPacket<T> buildPacket(Pair<FriendlyByteBuf,Integer> packetData, ResourceLocation channelName)
|
||||
{
|
||||
ICustomPacket<T> packet = (ICustomPacket<T>)UnsafeHacks.newInstance(getPacketClass());
|
||||
packet.setName(channelName);
|
||||
packet.setData(packetData.getLeft());
|
||||
packet.setIndex(packetData.getRight());
|
||||
return packet;
|
||||
return this.factory.create(packetData.getLeft(), packetData.getRight(), channelName);
|
||||
}
|
||||
|
||||
private interface Factory<T extends Packet<?>> {
|
||||
ICustomPacket<T> create(FriendlyByteBuf data, Integer index, ResourceLocation channelName);
|
||||
}
|
||||
}
|
||||
@@ -231,4 +231,10 @@ public class NetworkHooks
|
||||
{
|
||||
return mgr.channel().attr(NetworkConstants.FML_MOD_MISMATCH_DATA).get();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static MCRegisterPacketHandler.ChannelList getChannelList(Connection mgr)
|
||||
{
|
||||
return mgr.channel().attr(NetworkConstants.FML_MC_REGISTRY).get();
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,7 @@ public class NetworkInstance
|
||||
this.networkProtocolVersion = networkProtocolVersion.get();
|
||||
this.clientAcceptedVersions = clientAcceptedVersions;
|
||||
this.serverAcceptedVersions = serverAcceptedVersions;
|
||||
this.networkEventBus = BusBuilder.builder().setExceptionHandler(this::handleError).build();
|
||||
this.networkEventBus = BusBuilder.builder().setExceptionHandler(this::handleError).useModLauncher().build();
|
||||
}
|
||||
|
||||
private void handleError(IEventBus iEventBus, Event event, IEventListener[] iEventListeners, int i, Throwable throwable)
|
||||
@@ -95,6 +95,9 @@ public class NetworkInstance
|
||||
|
||||
public boolean isRemotePresent(Connection manager) {
|
||||
ConnectionData connectionData = NetworkHooks.getConnectionData(manager);
|
||||
return connectionData != null && connectionData.getChannels().containsKey(channelName);
|
||||
MCRegisterPacketHandler.ChannelList channelList = NetworkHooks.getChannelList(manager);
|
||||
return (connectionData != null && connectionData.getChannels().containsKey(channelName))
|
||||
// if it's not in the fml connection data, let's check if it's sent by another modloader.
|
||||
|| (channelList != null && channelList.getRemoteLocations().contains(channelName));
|
||||
}
|
||||
}
|
||||
@@ -135,7 +135,7 @@ public class IndexedMessageCodec
|
||||
}
|
||||
|
||||
void consume(FriendlyByteBuf payload, int payloadIndex, Supplier<NetworkEvent.Context> context) {
|
||||
if (payload == null) {
|
||||
if (payload == null || !payload.isReadable()) {
|
||||
LOGGER.error(SIMPLENET, "Received empty payload on channel {}", Optional.ofNullable(networkInstance).map(NetworkInstance::getChannelName).map(Objects::toString).orElse("MISSING CHANNEL"));
|
||||
if (!HandshakeHandler.packetNeedsResponse(context.get().getNetworkManager(), payloadIndex))
|
||||
{
|
||||
|
||||
@@ -26,6 +26,7 @@ public class ForgeDeferredRegistriesSetup
|
||||
ForgeRegistries.DEFERRED_BIOME_MODIFIERS.register(modEventBus);
|
||||
ForgeRegistries.DEFERRED_STRUCTURE_MODIFIER_SERIALIZERS.register(modEventBus);
|
||||
ForgeRegistries.DEFERRED_STRUCTURE_MODIFIERS.register(modEventBus);
|
||||
ForgeRegistries.DEFERRED_HOLDER_SET_TYPES.register(modEventBus);
|
||||
|
||||
setup = true;
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ import net.minecraftforge.common.Tags;
|
||||
import net.minecraftforge.common.loot.IGlobalLootModifier;
|
||||
import net.minecraftforge.common.world.BiomeModifier;
|
||||
import net.minecraftforge.fluids.FluidType;
|
||||
import net.minecraftforge.registries.holdersets.HolderSetType;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
import net.minecraftforge.common.world.StructureModifier;
|
||||
@@ -127,6 +128,12 @@ public class ForgeRegistries
|
||||
* Use {@link Keys#FLUID_TYPES} to create a {@link DeferredRegister}.
|
||||
*/
|
||||
public static final Supplier<IForgeRegistry<FluidType>> FLUID_TYPES = DEFERRED_FLUID_TYPES.makeRegistry(GameData::getFluidTypeRegistryBuilder);
|
||||
static final DeferredRegister<HolderSetType> DEFERRED_HOLDER_SET_TYPES = DeferredRegister.create(Keys.HOLDER_SET_TYPES, "forge");
|
||||
/**
|
||||
* Calling {@link Supplier#get()} before {@link NewRegistryEvent} is fired will result in a null registry returned.
|
||||
* Use {@link Keys#HOLDER_SET_TYPES} to create a {@link DeferredRegister}.
|
||||
*/
|
||||
public static final Supplier<IForgeRegistry<HolderSetType>> HOLDER_SET_TYPES = DEFERRED_HOLDER_SET_TYPES.makeRegistry(GameData::getHolderSetTypeRegistryBuilder);
|
||||
|
||||
// Custom forge datapack registries
|
||||
static final DeferredRegister<BiomeModifier> DEFERRED_BIOME_MODIFIERS = DeferredRegister.create(Keys.BIOME_MODIFIERS, "forge");
|
||||
@@ -175,6 +182,7 @@ public class ForgeRegistries
|
||||
public static final ResourceKey<Registry<Codec<? extends BiomeModifier>>> BIOME_MODIFIER_SERIALIZERS = key("forge:biome_modifier_serializers");
|
||||
public static final ResourceKey<Registry<Codec<? extends StructureModifier>>> STRUCTURE_MODIFIER_SERIALIZERS = key("forge:structure_modifier_serializers");
|
||||
public static final ResourceKey<Registry<FluidType>> FLUID_TYPES = key("forge:fluid_type");
|
||||
public static final ResourceKey<Registry<HolderSetType>> HOLDER_SET_TYPES = key("forge:holder_set_type");
|
||||
|
||||
// Forge Dynamic
|
||||
public static final ResourceKey<Registry<BiomeModifier>> BIOME_MODIFIERS = key("forge:biome_modifier");
|
||||
|
||||
@@ -48,6 +48,8 @@ import net.minecraftforge.fml.ModLoadingContext;
|
||||
import net.minecraftforge.fml.StartupMessageManager;
|
||||
import net.minecraftforge.fml.util.EnhancedRuntimeException;
|
||||
import net.minecraftforge.fml.util.thread.EffectiveSide;
|
||||
import net.minecraftforge.registries.holdersets.HolderSetType;
|
||||
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
@@ -164,6 +166,11 @@ public class GameData
|
||||
{
|
||||
return makeRegistry(FLUID_TYPES).disableSaving();
|
||||
}
|
||||
|
||||
static RegistryBuilder<HolderSetType> getHolderSetTypeRegistryBuilder()
|
||||
{
|
||||
return new RegistryBuilder<HolderSetType>().disableSaving().disableSync();
|
||||
}
|
||||
|
||||
private static <T> RegistryBuilder<T> makeRegistry(ResourceKey<? extends Registry<T>> key)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) Forge Development LLC and contributors
|
||||
* SPDX-License-Identifier: LGPL-2.1-only
|
||||
*/
|
||||
|
||||
package net.minecraftforge.registries.holdersets;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.HolderSet;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.HolderSetCodec;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraftforge.common.ForgeMod;
|
||||
|
||||
/**
|
||||
* <p>Holderset that represents an intersection of other holdersets. Json format:</p>
|
||||
* <pre>
|
||||
* {
|
||||
* "type": "forge:and",
|
||||
* "values":
|
||||
* [
|
||||
* // list of sub-holdersets (strings, lists, or objects)
|
||||
* ]
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
public class AndHolderSet<T> extends CompositeHolderSet<T>
|
||||
{
|
||||
public static <T> Codec<? extends ICustomHolderSet<T>> codec(ResourceKey<? extends Registry<T>> registryKey, Codec<Holder<T>> holderCodec, boolean forceList)
|
||||
{
|
||||
return HolderSetCodec.create(registryKey, holderCodec, forceList)
|
||||
.listOf()
|
||||
.xmap(AndHolderSet::new, AndHolderSet::getComponents)
|
||||
.fieldOf("values")
|
||||
.codec();
|
||||
}
|
||||
|
||||
public AndHolderSet(List<HolderSet<T>> values)
|
||||
{
|
||||
super(values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HolderSetType type()
|
||||
{
|
||||
return ForgeMod.AND_HOLDER_SET.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<Holder<T>> createSet()
|
||||
{
|
||||
List<HolderSet<T>> components = this.getComponents();
|
||||
if (components.size() < 1)
|
||||
{
|
||||
return Set.of();
|
||||
}
|
||||
if (components.size() == 1)
|
||||
{
|
||||
return components.get(0).stream().collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
List<HolderSet<T>> remainingComponents = components.subList(1, components.size());
|
||||
return components.get(0)
|
||||
.stream()
|
||||
.filter(holder -> remainingComponents.stream().allMatch(holderset -> holderset.contains(holder)))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "AndSet[" + this.getComponents() + "]";
|
||||
}
|
||||
}
|
||||
Loaded 100 of 119 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user