-
-
Notifications
You must be signed in to change notification settings - Fork 189
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow mods to add custom FeatureFlags
- Loading branch information
Showing
30 changed files
with
1,343 additions
and
1 deletion.
There are no files selected for viewing
14 changes: 14 additions & 0 deletions
14
patches/net/minecraft/client/gui/screens/worldselection/ExperimentsScreen.java.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
--- a/net/minecraft/client/gui/screens/worldselection/ExperimentsScreen.java | ||
+++ b/net/minecraft/client/gui/screens/worldselection/ExperimentsScreen.java | ||
@@ -50,6 +_,11 @@ | ||
|
||
@Override | ||
protected void init() { | ||
+ if (net.minecraft.world.flag.FeatureFlags.REGISTRY.hasAnyModdedFlags()) { | ||
+ this.minecraft.setScreen(new net.neoforged.neoforge.client.gui.ScrollableExperimentsScreen(this.parent, this.packRepository, this.output)); | ||
+ return; | ||
+ } | ||
+ | ||
this.layout.addTitleHeader(TITLE, this.font); | ||
LinearLayout linearlayout = this.layout.addToContents(LinearLayout.vertical()); | ||
linearlayout.addChild(new MultiLineTextWidget(INFO, this.font).setMaxWidth(310), p_293611_ -> p_293611_.paddingBottom(15)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
--- a/net/minecraft/world/flag/FeatureFlag.java | ||
+++ b/net/minecraft/world/flag/FeatureFlag.java | ||
@@ -3,9 +_,25 @@ | ||
public class FeatureFlag { | ||
final FeatureFlagUniverse universe; | ||
final long mask; | ||
+ final int extMaskIndex; | ||
+ final boolean modded; | ||
|
||
+ /** | ||
+ * @deprecated Neo: use {@link #FeatureFlag(FeatureFlagUniverse, int, int, boolean)} instead | ||
+ */ | ||
+ @Deprecated | ||
FeatureFlag(FeatureFlagUniverse p_249115_, int p_251067_) { | ||
+ this(p_249115_, p_251067_, 0, false); | ||
+ } | ||
+ | ||
+ FeatureFlag(FeatureFlagUniverse p_249115_, int p_251067_, int offset, boolean modded) { | ||
this.universe = p_249115_; | ||
this.mask = 1L << p_251067_; | ||
+ this.extMaskIndex = offset - 1; | ||
+ this.modded = modded; | ||
+ } | ||
+ | ||
+ public boolean isModded() { | ||
+ return modded; | ||
} | ||
} |
44 changes: 44 additions & 0 deletions
44
patches/net/minecraft/world/flag/FeatureFlagRegistry.java.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
--- a/net/minecraft/world/flag/FeatureFlagRegistry.java | ||
+++ b/net/minecraft/world/flag/FeatureFlagRegistry.java | ||
@@ -75,6 +_,18 @@ | ||
}, p_249796_ -> List.copyOf(this.toNames(p_249796_))); | ||
} | ||
|
||
+ public FeatureFlag getFlag(ResourceLocation name) { | ||
+ return com.google.common.base.Preconditions.checkNotNull(this.names.get(name), "Flag %s was not registered", name); | ||
+ } | ||
+ | ||
+ public Map<ResourceLocation, FeatureFlag> getAllFlags() { | ||
+ return this.names; | ||
+ } | ||
+ | ||
+ public boolean hasAnyModdedFlags() { | ||
+ return this.names.values().stream().anyMatch(FeatureFlag::isModded); | ||
+ } | ||
+ | ||
public static class Builder { | ||
private final FeatureFlagUniverse universe; | ||
private int id; | ||
@@ -88,11 +_,20 @@ | ||
return this.create(ResourceLocation.withDefaultNamespace(p_251782_)); | ||
} | ||
|
||
+ /** | ||
+ * @deprecated Neo: use {@link #create(ResourceLocation, boolean)} instead | ||
+ */ | ||
+ @Deprecated | ||
public FeatureFlag create(ResourceLocation p_250098_) { | ||
- if (this.id >= 64) { | ||
+ return create(p_250098_, false); | ||
+ } | ||
+ | ||
+ public FeatureFlag create(ResourceLocation p_250098_, boolean modded) { | ||
+ if (this.id >= 64 && false) { | ||
throw new IllegalStateException("Too many feature flags"); | ||
} else { | ||
- FeatureFlag featureflag = new FeatureFlag(this.universe, this.id++); | ||
+ FeatureFlag featureflag = new FeatureFlag(this.universe, this.id % FeatureFlagSet.MAX_CONTAINER_SIZE, this.id / FeatureFlagSet.MAX_CONTAINER_SIZE, modded); | ||
+ this.id++; | ||
FeatureFlag featureflag1 = this.flags.put(p_250098_, featureflag); | ||
if (featureflag1 != null) { | ||
throw new IllegalStateException("Duplicate feature flag " + p_250098_); |
188 changes: 188 additions & 0 deletions
188
patches/net/minecraft/world/flag/FeatureFlagSet.java.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,188 @@ | ||
--- a/net/minecraft/world/flag/FeatureFlagSet.java | ||
+++ b/net/minecraft/world/flag/FeatureFlagSet.java | ||
@@ -7,14 +_,21 @@ | ||
|
||
public final class FeatureFlagSet { | ||
private static final FeatureFlagSet EMPTY = new FeatureFlagSet(null, 0L); | ||
+ private static final long[] EMPTY_EXT_MASK = new long[0]; | ||
public static final int MAX_CONTAINER_SIZE = 64; | ||
@Nullable | ||
private final FeatureFlagUniverse universe; | ||
private final long mask; | ||
+ private final long[] extendedMask; | ||
|
||
private FeatureFlagSet(@Nullable FeatureFlagUniverse p_250433_, long p_251523_) { | ||
+ this(p_250433_, p_251523_, EMPTY_EXT_MASK); | ||
+ } | ||
+ | ||
+ private FeatureFlagSet(@Nullable FeatureFlagUniverse p_250433_, long p_251523_, long[] extendedMask) { | ||
this.universe = p_250433_; | ||
this.mask = p_251523_; | ||
+ this.extendedMask = extendedMask; | ||
} | ||
|
||
static FeatureFlagSet create(FeatureFlagUniverse p_251573_, Collection<FeatureFlag> p_251037_) { | ||
@@ -22,7 +_,8 @@ | ||
return EMPTY; | ||
} else { | ||
long i = computeMask(p_251573_, 0L, p_251037_); | ||
- return new FeatureFlagSet(p_251573_, i); | ||
+ long[] extMask = computeExtendedMask(p_251573_, 0, 0L, p_251037_); | ||
+ return new FeatureFlagSet(p_251573_, i, extMask); | ||
} | ||
} | ||
|
||
@@ -31,16 +_,19 @@ | ||
} | ||
|
||
public static FeatureFlagSet of(FeatureFlag p_252331_) { | ||
- return new FeatureFlagSet(p_252331_.universe, p_252331_.mask); | ||
+ long[] extMask = computeExtendedMask(p_252331_.universe, p_252331_.extMaskIndex, p_252331_.mask, java.util.List.of()); | ||
+ return new FeatureFlagSet(p_252331_.universe, p_252331_.extMaskIndex >= 0 ? 0L : p_252331_.mask, extMask); | ||
} | ||
|
||
public static FeatureFlagSet of(FeatureFlag p_251008_, FeatureFlag... p_249805_) { | ||
- long i = p_249805_.length == 0 ? p_251008_.mask : computeMask(p_251008_.universe, p_251008_.mask, Arrays.asList(p_249805_)); | ||
- return new FeatureFlagSet(p_251008_.universe, i); | ||
+ long i = p_249805_.length == 0 ? (p_251008_.extMaskIndex >= 0 ? 0L : p_251008_.mask) : computeMask(p_251008_.universe, p_251008_.extMaskIndex >= 0 ? 0L : p_251008_.mask, Arrays.asList(p_249805_)); | ||
+ long[] extMask = computeExtendedMask(p_251008_.universe, p_251008_.extMaskIndex, p_251008_.mask, p_249805_.length == 0 ? java.util.List.of() : Arrays.asList(p_249805_)); | ||
+ return new FeatureFlagSet(p_251008_.universe, i, extMask); | ||
} | ||
|
||
private static long computeMask(FeatureFlagUniverse p_249684_, long p_250982_, Iterable<FeatureFlag> p_251734_) { | ||
for (FeatureFlag featureflag : p_251734_) { | ||
+ if (featureflag.extMaskIndex >= 0) continue; | ||
if (p_249684_ != featureflag.universe) { | ||
throw new IllegalStateException("Mismatched feature universe, expected '" + p_249684_ + "', but got '" + featureflag.universe + "'"); | ||
} | ||
@@ -51,8 +_,36 @@ | ||
return p_250982_; | ||
} | ||
|
||
+ private static long[] computeExtendedMask(FeatureFlagUniverse universe, int firstExtIndex, long firstMask, Iterable<FeatureFlag> otherFlags) { | ||
+ long[] extMask = EMPTY_EXT_MASK; | ||
+ if (firstExtIndex >= 0) { | ||
+ extMask = new long[firstExtIndex + 1]; | ||
+ extMask[firstExtIndex] |= firstMask; | ||
+ } | ||
+ for (FeatureFlag flag : otherFlags) { | ||
+ if (flag.extMaskIndex < 0) continue; | ||
+ if (universe != flag.universe) { | ||
+ throw new IllegalStateException("Mismatched feature universe, expected '" + universe + "', but got '" + flag.universe + "'"); | ||
+ } | ||
+ if (flag.extMaskIndex >= extMask.length) { | ||
+ extMask = Arrays.copyOfRange(extMask, 0, flag.extMaskIndex + 1); | ||
+ } | ||
+ extMask[flag.extMaskIndex] |= flag.mask; | ||
+ } | ||
+ return extMask; | ||
+ } | ||
+ | ||
public boolean contains(FeatureFlag p_249521_) { | ||
- return this.universe != p_249521_.universe ? false : (this.mask & p_249521_.mask) != 0L; | ||
+ if (this.universe != p_249521_.universe) { | ||
+ return false; | ||
+ } | ||
+ if (p_249521_.extMaskIndex < 0) { | ||
+ return (this.mask & p_249521_.mask) != 0L; | ||
+ } | ||
+ if (this.extendedMask.length > p_249521_.extMaskIndex) { | ||
+ return (this.extendedMask[p_249521_.extMaskIndex] & p_249521_.mask) != 0L; | ||
+ } | ||
+ return false; | ||
} | ||
|
||
public boolean isEmpty() { | ||
@@ -62,13 +_,33 @@ | ||
public boolean isSubsetOf(FeatureFlagSet p_249164_) { | ||
if (this.universe == null) { | ||
return true; | ||
- } else { | ||
- return this.universe != p_249164_.universe ? false : (this.mask & ~p_249164_.mask) == 0L; | ||
+ } else if (this.universe == p_249164_.universe) { | ||
+ int len = Math.max(this.extendedMask.length, p_249164_.extendedMask.length); | ||
+ for (int i = 0; i < len; i++) { | ||
+ long thisMask = i < this.extendedMask.length ? this.extendedMask[i] : 0L; | ||
+ long otherMask = i < p_249164_.extendedMask.length ? p_249164_.extendedMask[i] : 0L; | ||
+ if ((thisMask & ~otherMask) != 0L) { | ||
+ return false; | ||
+ } | ||
+ } | ||
+ return (this.mask & ~p_249164_.mask) == 0L; | ||
} | ||
+ return false; | ||
} | ||
|
||
public boolean intersects(FeatureFlagSet p_341635_) { | ||
- return this.universe != null && p_341635_.universe != null && this.universe == p_341635_.universe ? (this.mask & p_341635_.mask) != 0L : false; | ||
+ if (this.universe == null || p_341635_.universe == null || this.universe != p_341635_.universe) { | ||
+ return false; | ||
+ } | ||
+ int len = Math.min(this.extendedMask.length, p_341635_.extendedMask.length); | ||
+ for (int i = 0; i < len; i++) { | ||
+ long thisMask = this.extendedMask[i]; | ||
+ long otherMask = p_341635_.extendedMask[i]; | ||
+ if ((thisMask & otherMask) != 0L) { | ||
+ return true; | ||
+ } | ||
+ } | ||
+ return (this.mask & p_341635_.mask) != 0L; | ||
} | ||
|
||
public FeatureFlagSet join(FeatureFlagSet p_251527_) { | ||
@@ -79,7 +_,16 @@ | ||
} else if (this.universe != p_251527_.universe) { | ||
throw new IllegalArgumentException("Mismatched set elements: '" + this.universe + "' != '" + p_251527_.universe + "'"); | ||
} else { | ||
- return new FeatureFlagSet(this.universe, this.mask | p_251527_.mask); | ||
+ long[] extMask = EMPTY_EXT_MASK; | ||
+ if (this.extendedMask.length > 0 || p_251527_.extendedMask.length > 0) { | ||
+ extMask = new long[Math.max(this.extendedMask.length, p_251527_.extendedMask.length)]; | ||
+ for (int i = 0; i < extMask.length; i++) { | ||
+ long thisMask = i < this.extendedMask.length ? this.extendedMask[i] : 0L; | ||
+ long otherMask = i < p_251527_.extendedMask.length ? p_251527_.extendedMask[i] : 0L; | ||
+ extMask[i] = thisMask | otherMask; | ||
+ } | ||
+ } | ||
+ return new FeatureFlagSet(this.universe, this.mask | p_251527_.mask, extMask); | ||
} | ||
} | ||
|
||
@@ -90,7 +_,15 @@ | ||
throw new IllegalArgumentException("Mismatched set elements: '" + this.universe + "' != '" + p_341688_.universe + "'"); | ||
} else { | ||
long i = this.mask & ~p_341688_.mask; | ||
- return i == 0L ? EMPTY : new FeatureFlagSet(this.universe, i); | ||
+ long[] extMask = EMPTY_EXT_MASK; | ||
+ if (this.extendedMask.length > 0 || p_341688_.extendedMask.length > 0) { | ||
+ extMask = new long[this.extendedMask.length]; | ||
+ for (int idx = 0; idx < extMask.length; idx++) { | ||
+ long otherMask = idx < p_341688_.extendedMask.length ? p_341688_.extendedMask[idx] : 0L; | ||
+ extMask[idx] = this.extendedMask[idx] & ~otherMask; | ||
+ } | ||
+ } | ||
+ return i == 0L && extMask.length == 0 ? EMPTY : new FeatureFlagSet(this.universe, i, extMask); | ||
} | ||
} | ||
|
||
@@ -99,7 +_,7 @@ | ||
if (this == p_248691_) { | ||
return true; | ||
} else { | ||
- if (p_248691_ instanceof FeatureFlagSet featureflagset && this.universe == featureflagset.universe && this.mask == featureflagset.mask) { | ||
+ if (p_248691_ instanceof FeatureFlagSet featureflagset && this.universe == featureflagset.universe && this.mask == featureflagset.mask && Arrays.equals(this.extendedMask, featureflagset.extendedMask)) { | ||
return true; | ||
} | ||
|
||
@@ -109,6 +_,10 @@ | ||
|
||
@Override | ||
public int hashCode() { | ||
- return (int)HashCommon.mix(this.mask); | ||
+ int hash = (int)HashCommon.mix(this.mask); | ||
+ for (long extMask : this.extendedMask) { | ||
+ hash = 13 * hash + (int) HashCommon.mix(extMask); | ||
+ } | ||
+ return hash; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
--- a/net/minecraft/world/flag/FeatureFlags.java | ||
+++ b/net/minecraft/world/flag/FeatureFlags.java | ||
@@ -37,6 +_,7 @@ | ||
TRADE_REBALANCE = featureflagregistry$builder.createVanilla("trade_rebalance"); | ||
REDSTONE_EXPERIMENTS = featureflagregistry$builder.createVanilla("redstone_experiments"); | ||
MINECART_IMPROVEMENTS = featureflagregistry$builder.createVanilla("minecart_improvements"); | ||
+ net.neoforged.neoforge.common.util.flag.FeatureFlagLoader.loadModdedFlags(featureflagregistry$builder); | ||
REGISTRY = featureflagregistry$builder.build(); | ||
CODEC = REGISTRY.codec(); | ||
VANILLA_SET = FeatureFlagSet.of(VANILLA); |
Oops, something went wrong.