mirror of
https://github.com/FabricMC/fabric.git
synced 2025-03-21 20:50:28 -04:00
22w11a
This commit is contained in:
parent
08b1b79b17
commit
7463d67c85
32 changed files with 220 additions and 177 deletions
fabric-api-lookup-api-v1/src/main/java/net/fabricmc/fabric/impl/lookup/entity
fabric-biome-api-v1/src
main
java/net/fabricmc/fabric
resources
testmod/java/net/fabricmc/fabric/test/biome
fabric-command-api-v1/src/main/java/net/fabricmc/fabric/mixin/command
fabric-data-generation-api-v1/src
main
java/net/fabricmc/fabric/api/datagen/v1/provider
resources
testmod/java/net/fabricmc/fabric/test/datagen
fabric-dimensions-v1/src/testmod/java/net/fabricmc/fabric/test/dimension
fabric-events-interaction-v0/src/main/java/net/fabricmc/fabric/mixin/event/interaction
fabric-gametest-api-v1/src/main/java/net/fabricmc/fabric/mixin/gametest
fabric-mining-level-api-v1/src/main/java/net/fabricmc/fabric/impl/mininglevel
fabric-resource-loader-v0/src/main/java/net/fabricmc/fabric
impl/resource/loader
mixin/resource/loader
fabric-screen-api-v1/src/main/java/net/fabricmc/fabric/mixin/screen
gradle.propertiessrc/main/resources
|
@ -42,7 +42,7 @@ import net.fabricmc.fabric.api.lookup.v1.entity.EntityApiLookup;
|
|||
|
||||
public class EntityApiLookupImpl<A, C> implements EntityApiLookup<A, C> {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger("fabric-api-lookup-api-v1/entity");
|
||||
private static final ApiLookupMap<EntityApiLookup<?, ?>> LOOKUPS = ApiLookupMap.create(EntityApiLookupImpl::new);
|
||||
private static final ApiLookupMap<EntityApiLookup<?, ?>> LOOKUPS = ApiLookupMap.<EntityApiLookup<?, ?>>create(EntityApiLookupImpl::new);
|
||||
private static final Map<Class<?>, Set<EntityType<?>>> REGISTERED_SELVES = new HashMap<>();
|
||||
private static boolean checkEntityLookup = true;
|
||||
|
||||
|
|
|
@ -45,12 +45,6 @@ import net.fabricmc.fabric.impl.biome.modification.BuiltInRegistryKeys;
|
|||
* <p><b>Experimental feature</b>, may be removed or changed without further notice.
|
||||
*/
|
||||
public interface BiomeModificationContext {
|
||||
/**
|
||||
* @see Biome#getCategory()
|
||||
* @see Biome.Builder#category(Biome.Category)
|
||||
*/
|
||||
void setCategory(Biome.Category category);
|
||||
|
||||
/**
|
||||
* Returns the modification context for the biomes weather properties.
|
||||
*/
|
||||
|
|
|
@ -26,8 +26,8 @@ import net.minecraft.util.registry.RegistryKey;
|
|||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.dimension.DimensionOptions;
|
||||
import net.minecraft.world.gen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.gen.feature.ConfiguredStructureFeature;
|
||||
import net.minecraft.world.gen.feature.PlacedFeature;
|
||||
import net.minecraft.world.gen.feature.StructureFeature;
|
||||
|
||||
import net.fabricmc.fabric.impl.biome.modification.BuiltInRegistryKeys;
|
||||
|
||||
|
@ -121,8 +121,8 @@ public interface BiomeSelectionContext {
|
|||
*
|
||||
* <p>This method is intended for use with the Vanilla configured structures found in {@link net.minecraft.world.gen.feature.ConfiguredStructureFeatures}.
|
||||
*/
|
||||
default boolean validForBuiltInStructure(ConfiguredStructureFeature<?, ?> configuredStructure) {
|
||||
RegistryKey<ConfiguredStructureFeature<?, ?>> key = BuiltInRegistryKeys.get(configuredStructure);
|
||||
default boolean validForBuiltInStructure(StructureFeature structureFeature) {
|
||||
RegistryKey<StructureFeature> key = BuiltInRegistryKeys.get(structureFeature);
|
||||
return validForStructure(key);
|
||||
}
|
||||
|
||||
|
@ -130,14 +130,14 @@ public interface BiomeSelectionContext {
|
|||
* Returns true if the configured structure with the given key can start in this biome in any chunk generator
|
||||
* used by the current world-save.
|
||||
*/
|
||||
boolean validForStructure(RegistryKey<ConfiguredStructureFeature<?, ?>> key);
|
||||
boolean validForStructure(RegistryKey<StructureFeature> key);
|
||||
|
||||
/**
|
||||
* Tries to retrieve the registry key for the given configured feature, which should be from this biomes
|
||||
* current structure list. May be empty if the configured feature is not registered, or does not come
|
||||
* from this biomes feature list.
|
||||
*/
|
||||
Optional<RegistryKey<ConfiguredStructureFeature<?, ?>>> getStructureKey(ConfiguredStructureFeature<?, ?> configuredStructure);
|
||||
Optional<RegistryKey<StructureFeature>> getStructureKey(StructureFeature structureFeature);
|
||||
|
||||
/**
|
||||
* Tries to determine whether this biome generates in a specific dimension, based on the {@link net.minecraft.world.gen.GeneratorOptions}
|
||||
|
|
|
@ -17,16 +17,14 @@
|
|||
package net.fabricmc.fabric.api.biome.v1;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import net.minecraft.tag.TagKey;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.SpawnGroup;
|
||||
import net.minecraft.tag.TagKey;
|
||||
import net.minecraft.util.registry.BuiltinRegistries;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
|
@ -167,16 +165,4 @@ public final class BiomeSelectors {
|
|||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches Biomes that have one of the given categories.
|
||||
*
|
||||
* @see Biome#getCategory()
|
||||
*/
|
||||
public static Predicate<BiomeSelectionContext> categories(Biome.Category... categories) {
|
||||
Set<Biome.Category> categorySet = EnumSet.noneOf(Biome.Category.class);
|
||||
Collections.addAll(categorySet, categories);
|
||||
|
||||
return context -> categorySet.contains(context.getBiome().category);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,9 @@ package net.fabricmc.fabric.impl.biome;
|
|||
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
@ -29,6 +32,7 @@ import net.minecraft.util.registry.RegistryKey;
|
|||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.biome.BiomeKeys;
|
||||
import net.minecraft.world.biome.source.TheEndBiomeSource;
|
||||
import net.minecraft.world.biome.source.util.MultiNoiseUtil;
|
||||
import net.minecraft.world.gen.random.AtomicSimpleRandom;
|
||||
import net.minecraft.world.gen.random.ChunkRandom;
|
||||
|
||||
|
@ -79,28 +83,30 @@ public final class TheEndBiomeData {
|
|||
END_BARRENS_MAP.computeIfAbsent(highlands, key -> new WeightedPicker<>()).add(barrens, weight);
|
||||
}
|
||||
|
||||
public static Overrides createOverrides(Registry<Biome> biomeRegistry, long seed) {
|
||||
return new Overrides(biomeRegistry, seed);
|
||||
public static Overrides createOverrides(Registry<Biome> biomeRegistry) {
|
||||
return new Overrides(biomeRegistry);
|
||||
}
|
||||
|
||||
/**
|
||||
* An instance of this class is attached to each {@link TheEndBiomeSource}.
|
||||
*/
|
||||
public static class Overrides {
|
||||
private final PerlinNoiseSampler sampler;
|
||||
|
||||
// Vanilla entries to compare against
|
||||
private final RegistryEntry<Biome> endMidlands;
|
||||
private final RegistryEntry<Biome> endBarrens;
|
||||
private final RegistryEntry<Biome> endHighlands;
|
||||
|
||||
// Maps where the keys have been resolved to actual entries
|
||||
private final Map<RegistryEntry<Biome>, WeightedPicker<RegistryEntry<Biome>>> endBiomesMap;
|
||||
private final Map<RegistryEntry<Biome>, WeightedPicker<RegistryEntry<Biome>>> endMidlandsMap;
|
||||
private final Map<RegistryEntry<Biome>, WeightedPicker<RegistryEntry<Biome>>> endBarrensMap;
|
||||
private final @Nullable Map<RegistryEntry<Biome>, WeightedPicker<RegistryEntry<Biome>>> endBiomesMap;
|
||||
private final @Nullable Map<RegistryEntry<Biome>, WeightedPicker<RegistryEntry<Biome>>> endMidlandsMap;
|
||||
private final @Nullable Map<RegistryEntry<Biome>, WeightedPicker<RegistryEntry<Biome>>> endBarrensMap;
|
||||
|
||||
public Overrides(Registry<Biome> biomeRegistry, long seed) {
|
||||
this.sampler = new PerlinNoiseSampler(new ChunkRandom(new AtomicSimpleRandom(seed)));
|
||||
// cache for our own sampler (used for random biome replacement selection)
|
||||
private final Map<MultiNoiseUtil.MultiNoiseSampler, PerlinNoiseSampler> samplers = new WeakHashMap<>();
|
||||
// current seed, set from ChunkGenerator hook since it is not normally available
|
||||
private static ThreadLocal<Long> seed = new ThreadLocal<>();
|
||||
|
||||
public Overrides(Registry<Biome> biomeRegistry) {
|
||||
this.endMidlands = biomeRegistry.entryOf(BiomeKeys.END_MIDLANDS);
|
||||
this.endBarrens = biomeRegistry.entryOf(BiomeKeys.END_BARRENS);
|
||||
this.endHighlands = biomeRegistry.entryOf(BiomeKeys.END_HIGHLANDS);
|
||||
|
@ -111,40 +117,60 @@ public final class TheEndBiomeData {
|
|||
}
|
||||
|
||||
// Resolves all RegistryKey instances to RegistryEntries
|
||||
private Map<RegistryEntry<Biome>, WeightedPicker<RegistryEntry<Biome>>> resolveOverrides(Registry<Biome> biomeRegistry, Map<RegistryKey<Biome>, WeightedPicker<RegistryKey<Biome>>> overrides) {
|
||||
var result = new IdentityHashMap<RegistryEntry<Biome>, WeightedPicker<RegistryEntry<Biome>>>(overrides.size());
|
||||
private @Nullable Map<RegistryEntry<Biome>, WeightedPicker<RegistryEntry<Biome>>> resolveOverrides(Registry<Biome> biomeRegistry, Map<RegistryKey<Biome>, WeightedPicker<RegistryKey<Biome>>> overrides) {
|
||||
Map<RegistryEntry<Biome>, WeightedPicker<RegistryEntry<Biome>>> result = new IdentityHashMap<>(overrides.size());
|
||||
|
||||
for (Map.Entry<RegistryKey<Biome>, WeightedPicker<RegistryKey<Biome>>> entry : overrides.entrySet()) {
|
||||
result.put(biomeRegistry.entryOf(entry.getKey()), entry.getValue().map(biomeRegistry::entryOf));
|
||||
WeightedPicker<RegistryKey<Biome>> picker = entry.getValue();
|
||||
if (picker.getEntryCount() <= 1) continue; // don't use no-op entries
|
||||
|
||||
result.put(biomeRegistry.entryOf(entry.getKey()), picker.map(biomeRegistry::entryOf));
|
||||
}
|
||||
|
||||
return result;
|
||||
return result.isEmpty() ? null : result;
|
||||
}
|
||||
|
||||
public RegistryEntry<Biome> pick(int x, int y, int z, RegistryEntry<Biome> vanillaBiome) {
|
||||
RegistryEntry<Biome> replacementKey;
|
||||
|
||||
// The x and z of the entry are divided by 64 to ensure custom biomes are large enough; going larger than this]
|
||||
// seems to make custom biomes too hard to find.
|
||||
public RegistryEntry<Biome> pick(int x, int y, int z, MultiNoiseUtil.MultiNoiseSampler noise, RegistryEntry<Biome> vanillaBiome) {
|
||||
if (vanillaBiome == endMidlands || vanillaBiome == endBarrens) {
|
||||
// Since the highlands picker is statically populated by InternalBiomeData, picker will never be null.
|
||||
WeightedPicker<RegistryEntry<Biome>> highlandsPicker = endBiomesMap.get(endHighlands);
|
||||
RegistryEntry<Biome> highlandsKey = highlandsPicker.pickFromNoise(sampler, x / 64.0, 0, z / 64.0);
|
||||
// select a random highlands biome replacement, then try to replace it with a midlands or barrens biome replacement
|
||||
RegistryEntry<Biome> highlandsReplacement = pick(endHighlands, endHighlands, endBiomesMap, x, z, noise);
|
||||
Map<RegistryEntry<Biome>, WeightedPicker<RegistryEntry<Biome>>> map = vanillaBiome == endMidlands ? endMidlandsMap : endBarrensMap;
|
||||
|
||||
if (vanillaBiome == endMidlands) {
|
||||
WeightedPicker<RegistryEntry<Biome>> midlandsPicker = endMidlandsMap.get(highlandsKey);
|
||||
replacementKey = (midlandsPicker == null) ? vanillaBiome : midlandsPicker.pickFromNoise(sampler, x / 64.0, 0, z / 64.0);
|
||||
} else {
|
||||
WeightedPicker<RegistryEntry<Biome>> barrensPicker = endBarrensMap.get(highlandsKey);
|
||||
replacementKey = (barrensPicker == null) ? vanillaBiome : barrensPicker.pickFromNoise(sampler, x / 64.0, 0, z / 64.0);
|
||||
}
|
||||
return pick(highlandsReplacement, vanillaBiome, map, x, z, noise);
|
||||
} else {
|
||||
// Since the main island and small islands pickers are statically populated by InternalBiomeData, picker will never be null.
|
||||
WeightedPicker<RegistryEntry<Biome>> picker = endBiomesMap.get(vanillaBiome);
|
||||
replacementKey = picker.pickFromNoise(sampler, x / 64.0, 0, z / 64.0);
|
||||
assert END_BIOMES_MAP.containsKey(vanillaBiome.getKey().orElseThrow());
|
||||
|
||||
return pick(vanillaBiome, vanillaBiome, endBiomesMap, x, z, noise);
|
||||
}
|
||||
}
|
||||
|
||||
private <T> T pick(T key, T defaultValue, Map<T, WeightedPicker<T>> pickers, int x, int z, MultiNoiseUtil.MultiNoiseSampler noise) {
|
||||
if (pickers == null) return defaultValue;
|
||||
|
||||
WeightedPicker<T> picker = pickers.get(key);
|
||||
if (picker == null || picker.getEntryCount() <= 1) return defaultValue;
|
||||
|
||||
// The x and z of the entry are divided by 64 to ensure custom biomes are large enough; going larger than this
|
||||
// seems to make custom biomes too hard to find.
|
||||
return picker.pickFromNoise(getSampler(noise), x / 64.0, 0, z / 64.0);
|
||||
}
|
||||
|
||||
private synchronized PerlinNoiseSampler getSampler(MultiNoiseUtil.MultiNoiseSampler noise) {
|
||||
PerlinNoiseSampler ret = samplers.get(noise);
|
||||
|
||||
if (ret == null) {
|
||||
Long seed = Overrides.seed.get();
|
||||
if (seed == null) throw new IllegalStateException("seed isn't set, ChunkGenerator hook not working?");
|
||||
|
||||
ret = new PerlinNoiseSampler(new ChunkRandom(new AtomicSimpleRandom(seed)));
|
||||
samplers.put(noise, ret);
|
||||
}
|
||||
|
||||
return replacementKey;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static void setSeed(long seed) {
|
||||
Overrides.seed.set(seed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,6 +50,10 @@ public final class WeightedPicker<T> {
|
|||
return currentTotal;
|
||||
}
|
||||
|
||||
int getEntryCount() {
|
||||
return entries.size();
|
||||
}
|
||||
|
||||
public T pickFromNoise(PerlinNoiseSampler sampler, double x, double y, double z) {
|
||||
double target = Math.abs(sampler.sample(x, y, z)) * getCurrentWeightTotal();
|
||||
|
||||
|
|
|
@ -33,8 +33,6 @@ import com.google.common.collect.ImmutableMap;
|
|||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import net.minecraft.util.registry.RegistryEntry;
|
||||
import net.minecraft.util.registry.RegistryEntryList;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.SpawnGroup;
|
||||
import net.minecraft.sound.BiomeAdditionsSound;
|
||||
|
@ -44,6 +42,8 @@ import net.minecraft.sound.SoundEvent;
|
|||
import net.minecraft.util.collection.Pool;
|
||||
import net.minecraft.util.registry.DynamicRegistryManager;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.util.registry.RegistryEntry;
|
||||
import net.minecraft.util.registry.RegistryEntryList;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.biome.BiomeEffects;
|
||||
|
@ -52,9 +52,9 @@ import net.minecraft.world.biome.GenerationSettings;
|
|||
import net.minecraft.world.biome.SpawnSettings;
|
||||
import net.minecraft.world.gen.GenerationStep;
|
||||
import net.minecraft.world.gen.carver.ConfiguredCarver;
|
||||
import net.minecraft.world.gen.feature.ConfiguredStructureFeature;
|
||||
import net.minecraft.world.gen.feature.Feature;
|
||||
import net.minecraft.world.gen.feature.PlacedFeature;
|
||||
import net.minecraft.world.gen.feature.StructureFeature;
|
||||
|
||||
import net.fabricmc.fabric.api.biome.v1.BiomeModificationContext;
|
||||
|
||||
|
@ -78,11 +78,6 @@ public class BiomeModificationContextImpl implements BiomeModificationContext {
|
|||
this.spawnSettings = new SpawnSettingsContextImpl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCategory(Biome.Category category) {
|
||||
biome.category = category;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WeatherContext getWeather() {
|
||||
return weather;
|
||||
|
@ -202,7 +197,7 @@ public class BiomeModificationContextImpl implements BiomeModificationContext {
|
|||
private class GenerationSettingsContextImpl implements GenerationSettingsContext {
|
||||
private final Registry<ConfiguredCarver<?>> carvers = registries.get(Registry.CONFIGURED_CARVER_KEY);
|
||||
private final Registry<PlacedFeature> features = registries.get(Registry.PLACED_FEATURE_KEY);
|
||||
private final Registry<ConfiguredStructureFeature<?, ?>> structures = registries.get(Registry.CONFIGURED_STRUCTURE_FEATURE_KEY);
|
||||
private final Registry<StructureFeature> structures = registries.get(Registry.CONFIGURED_STRUCTURE_FEATURE_KEY);
|
||||
private final GenerationSettings generationSettings = biome.getGenerationSettings();
|
||||
|
||||
private boolean rebuildFlowerFeatures;
|
||||
|
|
|
@ -28,8 +28,8 @@ import net.minecraft.util.registry.RegistryKey;
|
|||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.dimension.DimensionOptions;
|
||||
import net.minecraft.world.gen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.gen.feature.ConfiguredStructureFeature;
|
||||
import net.minecraft.world.gen.feature.PlacedFeature;
|
||||
import net.minecraft.world.gen.feature.StructureFeature;
|
||||
import net.minecraft.world.level.LevelProperties;
|
||||
|
||||
import net.fabricmc.fabric.api.biome.v1.BiomeSelectionContext;
|
||||
|
@ -78,20 +78,20 @@ public class BiomeSelectionContextImpl implements BiomeSelectionContext {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean validForStructure(RegistryKey<ConfiguredStructureFeature<?, ?>> key) {
|
||||
ConfiguredStructureFeature<?, ?> instance = dynamicRegistries.get(Registry.CONFIGURED_STRUCTURE_FEATURE_KEY).get(key);
|
||||
public boolean validForStructure(RegistryKey<StructureFeature> key) {
|
||||
StructureFeature instance = dynamicRegistries.get(Registry.CONFIGURED_STRUCTURE_FEATURE_KEY).get(key);
|
||||
|
||||
if (instance == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return instance.getBiomes().contains(getBiomeRegistryEntry());
|
||||
return instance.method_41607().contains(getBiomeRegistryEntry());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<RegistryKey<ConfiguredStructureFeature<?, ?>>> getStructureKey(ConfiguredStructureFeature<?, ?> configuredStructure) {
|
||||
Registry<ConfiguredStructureFeature<?, ?>> registry = dynamicRegistries.get(Registry.CONFIGURED_STRUCTURE_FEATURE_KEY);
|
||||
return registry.getKey(configuredStructure);
|
||||
public Optional<RegistryKey<StructureFeature>> getStructureKey(StructureFeature structureFeature) {
|
||||
Registry<StructureFeature> registry = dynamicRegistries.get(Registry.CONFIGURED_STRUCTURE_FEATURE_KEY);
|
||||
return registry.getKey(structureFeature);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -22,8 +22,8 @@ import net.minecraft.util.registry.BuiltinRegistries;
|
|||
import net.minecraft.util.registry.RegistryKey;
|
||||
import net.minecraft.world.gen.carver.ConfiguredCarver;
|
||||
import net.minecraft.world.gen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.gen.feature.ConfiguredStructureFeature;
|
||||
import net.minecraft.world.gen.feature.PlacedFeature;
|
||||
import net.minecraft.world.gen.feature.StructureFeature;
|
||||
|
||||
/**
|
||||
* Utility class for getting the registry keys of built-in worldgen objects and throwing proper exceptions if they
|
||||
|
@ -34,9 +34,9 @@ public final class BuiltInRegistryKeys {
|
|||
private BuiltInRegistryKeys() {
|
||||
}
|
||||
|
||||
public static RegistryKey<ConfiguredStructureFeature<?, ?>> get(ConfiguredStructureFeature<?, ?> configuredStructure) {
|
||||
return BuiltinRegistries.CONFIGURED_STRUCTURE_FEATURE.getKey(configuredStructure)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Given configured structure is not built-in: " + configuredStructure));
|
||||
public static RegistryKey<StructureFeature> get(StructureFeature structureFeature) {
|
||||
return BuiltinRegistries.CONFIGURED_STRUCTURE_FEATURE.getKey(structureFeature)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Given structure is not built-in: " + structureFeature));
|
||||
}
|
||||
|
||||
public static RegistryKey<ConfiguredFeature<?, ?>> get(ConfiguredFeature<?, ?> configuredFeature) {
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.mixin.biome;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import net.minecraft.class_7138;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraft.world.gen.chunk.ChunkGenerator;
|
||||
|
||||
import net.fabricmc.fabric.impl.biome.TheEndBiomeData;
|
||||
|
||||
@Mixin(ChunkGenerator.class)
|
||||
public class MixinChunkGenerator {
|
||||
@Inject(method = "method_38267", at = @At("HEAD"))
|
||||
private void populateBiomes_lambda_head(Chunk chunk, class_7138 rng, CallbackInfoReturnable<Chunk> ci) {
|
||||
// capture seed so TheEndBiomeData.Overrides has it if it needs it
|
||||
TheEndBiomeData.Overrides.setSeed(rng.legacyLevelSeed());
|
||||
}
|
||||
}
|
|
@ -37,12 +37,12 @@ public class MixinTheEndBiomeSource {
|
|||
private TheEndBiomeData.Overrides overrides;
|
||||
|
||||
@Inject(method = "<init>", at = @At("RETURN"))
|
||||
private void init(Registry<Biome> biomeRegistry, long seed, CallbackInfo ci) {
|
||||
overrides = TheEndBiomeData.createOverrides(biomeRegistry, seed);
|
||||
private void init(Registry<Biome> biomeRegistry, CallbackInfo ci) {
|
||||
overrides = TheEndBiomeData.createOverrides(biomeRegistry);
|
||||
}
|
||||
|
||||
@Inject(method = "getBiome", at = @At("RETURN"), cancellable = true)
|
||||
private void getWeightedEndBiome(int biomeX, int biomeY, int biomeZ, MultiNoiseUtil.MultiNoiseSampler multiNoiseSampler, CallbackInfoReturnable<RegistryEntry<Biome>> cir) {
|
||||
cir.setReturnValue(overrides.pick(biomeX, biomeY, biomeZ, cir.getReturnValue()));
|
||||
private void getWeightedEndBiome(int biomeX, int biomeY, int biomeZ, MultiNoiseUtil.MultiNoiseSampler noise, CallbackInfoReturnable<RegistryEntry<Biome>> cir) {
|
||||
cir.setReturnValue(overrides.pick(biomeX, biomeY, biomeZ, noise, cir.getReturnValue()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,8 +11,6 @@ mutable field net/minecraft/world/biome/source/BiomeSource indexedFeaturesSuppli
|
|||
accessible field net/minecraft/world/biome/Biome weather Lnet/minecraft/world/biome/Biome$Weather;
|
||||
accessible field net/minecraft/world/biome/Biome generationSettings Lnet/minecraft/world/biome/GenerationSettings;
|
||||
accessible field net/minecraft/world/biome/Biome spawnSettings Lnet/minecraft/world/biome/SpawnSettings;
|
||||
accessible field net/minecraft/world/biome/Biome category Lnet/minecraft/world/biome/Biome$Category;
|
||||
mutable field net/minecraft/world/biome/Biome category Lnet/minecraft/world/biome/Biome$Category;
|
||||
|
||||
# Biome Weather
|
||||
accessible field net/minecraft/world/biome/Biome$Weather precipitation Lnet/minecraft/world/biome/Biome$Precipitation;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
"mixins": [
|
||||
"modification.DynamicRegistryManagerImplMixin",
|
||||
"modification.MinecraftServerMixin",
|
||||
"MixinChunkGenerator",
|
||||
"MixinMultiNoiseBiomeSource",
|
||||
"MixinTheEndBiomeSource"
|
||||
],
|
||||
|
|
|
@ -102,7 +102,7 @@ public class FabricBiomeTest implements ModInitializer {
|
|||
BiomeSelectors.foundInOverworld(),
|
||||
modification -> modification.getWeather().setDownfall(100))
|
||||
.add(ModificationPhase.ADDITIONS,
|
||||
BiomeSelectors.categories(Biome.Category.DESERT),
|
||||
BiomeSelectors.includeByKey(BiomeKeys.DESERT), // TODO: switch to fabric desert biome tag once it is there?
|
||||
context -> {
|
||||
context.getGenerationSettings().addFeature(GenerationStep.Feature.TOP_LAYER_MODIFICATION,
|
||||
BuiltinRegistries.PLACED_FEATURE.getKey(PLACED_COMMON_DESERT_WELL).orElseThrow()
|
||||
|
@ -134,6 +134,6 @@ public class FabricBiomeTest implements ModInitializer {
|
|||
private static Biome composeEndSpawnSettings(GenerationSettings.Builder builder) {
|
||||
SpawnSettings.Builder builder2 = new SpawnSettings.Builder();
|
||||
DefaultBiomeFeatures.addEndMobs(builder2);
|
||||
return (new Biome.Builder()).precipitation(Biome.Precipitation.NONE).category(Biome.Category.THEEND).temperature(0.5F).downfall(0.5F).effects((new BiomeEffects.Builder()).waterColor(4159204).waterFogColor(329011).fogColor(10518688).skyColor(0).moodSound(BiomeMoodSound.CAVE).build()).spawnSettings(builder2.build()).generationSettings(builder.build()).build();
|
||||
return (new Biome.Builder()).precipitation(Biome.Precipitation.NONE).temperature(0.5F).downfall(0.5F).effects((new BiomeEffects.Builder()).waterColor(4159204).waterFogColor(329011).fogColor(10518688).skyColor(0).moodSound(BiomeMoodSound.CAVE).build()).spawnSettings(builder2.build()).generationSettings(builder.build()).build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import net.minecraft.class_7157;
|
||||
import net.minecraft.server.command.CommandManager;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
|
||||
|
@ -42,8 +43,8 @@ public abstract class CommandManagerMixin {
|
|||
*
|
||||
* @reason Add commands before ambiguities are calculated.
|
||||
*/
|
||||
@Inject(at = @At(value = "INVOKE", target = "Lcom/mojang/brigadier/CommandDispatcher;findAmbiguities(Lcom/mojang/brigadier/AmbiguityConsumer;)V"), method = "<init>")
|
||||
private void fabric_addCommands(CommandManager.RegistrationEnvironment environment, CallbackInfo ci) {
|
||||
@Inject(at = @At(value = "INVOKE", target = "Lcom/mojang/brigadier/CommandDispatcher;setConsumer(Lcom/mojang/brigadier/ResultConsumer;)V"), method = "<init>")
|
||||
private void fabric_addCommands(CommandManager.RegistrationEnvironment environment, class_7157 arg, CallbackInfo ci) {
|
||||
CommandRegistrationCallback.EVENT.invoker().register(this.dispatcher, environment == CommandManager.RegistrationEnvironment.DEDICATED);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,7 +65,6 @@ import net.fabricmc.fabric.mixin.datagen.DynamicRegistryManagerAccessor;
|
|||
public abstract class FabricTagProvider<T> extends AbstractTagProvider<T> {
|
||||
private final FabricDataGenerator fabricDataGenerator;
|
||||
private final String path;
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* Construct a new {@link FabricTagProvider} with the default computed path.
|
||||
|
@ -76,8 +75,8 @@ public abstract class FabricTagProvider<T> extends AbstractTagProvider<T> {
|
|||
* @param registry The backing registry for the Tag type.
|
||||
* @param name The name used for {@link DataProvider#getName()}
|
||||
*/
|
||||
protected FabricTagProvider(FabricDataGenerator dataGenerator, Registry<T> registry, String name) {
|
||||
this(dataGenerator, registry, TagManagerLoader.getPath(registry.getKey()), name);
|
||||
protected FabricTagProvider(FabricDataGenerator dataGenerator, Registry<T> registry) {
|
||||
this(dataGenerator, registry, TagManagerLoader.getPath(registry.getKey()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -88,14 +87,12 @@ public abstract class FabricTagProvider<T> extends AbstractTagProvider<T> {
|
|||
* @param dataGenerator The data generator instance
|
||||
* @param registry The backing registry for the Tag type.
|
||||
* @param path The directory name to write the tag file names. Example: "blocks" or "items"
|
||||
* @param name The name used for {@link DataProvider#getName()}
|
||||
*/
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
protected FabricTagProvider(FabricDataGenerator dataGenerator, Registry<T> registry, String path, String name) {
|
||||
protected FabricTagProvider(FabricDataGenerator dataGenerator, Registry<T> registry, String path) {
|
||||
super(dataGenerator, registry);
|
||||
this.fabricDataGenerator = dataGenerator;
|
||||
this.path = path.startsWith("tags/") ? path : "tags/" + path;
|
||||
this.name = name;
|
||||
|
||||
if (!(this instanceof DynamicRegistryTagProvider) && BuiltinRegistries.REGISTRIES.contains((RegistryKey) registry.getKey())) {
|
||||
throw new IllegalArgumentException("Using FabricTagProvider to generate dynamic registry tags is not supported, Use DynamicRegistryTagProvider instead.");
|
||||
|
@ -128,11 +125,6 @@ public abstract class FabricTagProvider<T> extends AbstractTagProvider<T> {
|
|||
generateTags();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend this class to create {@link Block} tags in the "/blocks" tag directory.
|
||||
*/
|
||||
|
@ -226,8 +218,8 @@ public abstract class FabricTagProvider<T> extends AbstractTagProvider<T> {
|
|||
* @param name The name used for {@link DataProvider#getName()}
|
||||
* @throws IllegalArgumentException if the registry is static registry
|
||||
*/
|
||||
protected DynamicRegistryTagProvider(FabricDataGenerator dataGenerator, RegistryKey<? extends Registry<T>> registryKey, String path, String name) {
|
||||
super(dataGenerator, FabricDataGenHelper.getFakeDynamicRegistry(), path, name);
|
||||
protected DynamicRegistryTagProvider(FabricDataGenerator dataGenerator, RegistryKey<? extends Registry<T>> registryKey, String path) {
|
||||
super(dataGenerator, FabricDataGenHelper.getFakeDynamicRegistry(), path);
|
||||
Preconditions.checkArgument(DynamicRegistryManagerAccessor.getInfos().containsKey(registryKey), "Only dynamic registries are supported in this tag provider.");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,6 +88,7 @@ transitive-accessible method net/minecraft/data/server/RecipeProvider convertBet
|
|||
transitive-accessible method net/minecraft/data/server/RecipeProvider getSmeltingItemPath (Lnet/minecraft/item/ItemConvertible;)Ljava/lang/String;
|
||||
transitive-accessible method net/minecraft/data/server/RecipeProvider getBlastingItemPath (Lnet/minecraft/item/ItemConvertible;)Ljava/lang/String;
|
||||
transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator createStoneState (Lnet/minecraft/block/Block;Lnet/minecraft/util/Identifier;Lnet/minecraft/data/client/TextureMap;Ljava/util/function/BiConsumer;)Lnet/minecraft/data/client/BlockStateSupplier;
|
||||
transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator method_42039 (Lnet/minecraft/block/Block;Lnet/minecraft/util/Identifier;Lnet/minecraft/data/client/TextureMap;Ljava/util/function/BiConsumer;)Lnet/minecraft/data/client/BlockStateSupplier;
|
||||
transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator createDeepslateState (Lnet/minecraft/block/Block;Lnet/minecraft/util/Identifier;Lnet/minecraft/data/client/TextureMap;Ljava/util/function/BiConsumer;)Lnet/minecraft/data/client/BlockStateSupplier;
|
||||
transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator excludeFromSimpleItemModelGeneration (Lnet/minecraft/block/Block;)V
|
||||
transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator registerParentedItemModel (Lnet/minecraft/block/Block;Lnet/minecraft/util/Identifier;)V
|
||||
|
@ -106,8 +107,8 @@ transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator
|
|||
transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator registerMirrorable (Lnet/minecraft/block/Block;)V
|
||||
transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator registerRotatable (Lnet/minecraft/block/Block;)V
|
||||
transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator createButtonBlockState (Lnet/minecraft/block/Block;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;)Lnet/minecraft/data/client/BlockStateSupplier;
|
||||
transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator fillDoorVariantMap (Lnet/minecraft/data/client/BlockStateVariantMap$QuadrupleProperty;Lnet/minecraft/block/enums/DoubleBlockHalf;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;)Lnet/minecraft/data/client/BlockStateVariantMap$QuadrupleProperty;
|
||||
transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator createDoorBlockState (Lnet/minecraft/block/Block;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;)Lnet/minecraft/data/client/BlockStateSupplier;
|
||||
transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator fillDoorVariantMap (Lnet/minecraft/data/client/BlockStateVariantMap$QuadrupleProperty;Lnet/minecraft/block/enums/DoubleBlockHalf;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;)Lnet/minecraft/data/client/BlockStateVariantMap$QuadrupleProperty;
|
||||
transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator createDoorBlockState (Lnet/minecraft/block/Block;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;)Lnet/minecraft/data/client/BlockStateSupplier;
|
||||
transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator createFenceBlockState (Lnet/minecraft/block/Block;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;)Lnet/minecraft/data/client/BlockStateSupplier;
|
||||
transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator createWallBlockState (Lnet/minecraft/block/Block;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;)Lnet/minecraft/data/client/BlockStateSupplier;
|
||||
transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator createFenceGateBlockState (Lnet/minecraft/block/Block;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;)Lnet/minecraft/data/client/BlockStateSupplier;
|
||||
|
|
|
@ -87,7 +87,7 @@ public class DataGeneratorTestEntrypoint implements DataGeneratorEntrypoint {
|
|||
}
|
||||
|
||||
try {
|
||||
new FabricTagProvider.DynamicRegistryTagProvider<>(dataGenerator, Registry.ITEM_KEY, "items", "Item Tags") {
|
||||
new FabricTagProvider.DynamicRegistryTagProvider<>(dataGenerator, Registry.ITEM_KEY, "items") {
|
||||
@Override
|
||||
protected void generateTags() {
|
||||
}
|
||||
|
@ -164,7 +164,7 @@ public class DataGeneratorTestEntrypoint implements DataGeneratorEntrypoint {
|
|||
|
||||
private static class TestBiomeTagProvider extends FabricTagProvider.DynamicRegistryTagProvider<Biome> {
|
||||
private TestBiomeTagProvider(FabricDataGenerator dataGenerator) {
|
||||
super(dataGenerator, Registry.BIOME_KEY, "biomes", "Biome Tags");
|
||||
super(dataGenerator, Registry.BIOME_KEY, "biomes");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.util.concurrent.Executor;
|
|||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
|
||||
import net.minecraft.class_7138;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.structure.StructureSet;
|
||||
import net.minecraft.util.dynamic.RegistryOps;
|
||||
|
@ -36,7 +37,6 @@ import net.minecraft.world.biome.Biome;
|
|||
import net.minecraft.world.biome.BiomeKeys;
|
||||
import net.minecraft.world.biome.source.BiomeAccess;
|
||||
import net.minecraft.world.biome.source.FixedBiomeSource;
|
||||
import net.minecraft.world.biome.source.util.MultiNoiseUtil;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraft.world.gen.GenerationStep;
|
||||
import net.minecraft.world.gen.StructureAccessor;
|
||||
|
@ -46,11 +46,8 @@ import net.minecraft.world.gen.chunk.VerticalBlockSample;
|
|||
|
||||
public class VoidChunkGenerator extends ChunkGenerator {
|
||||
public static final Codec<VoidChunkGenerator> CODEC = RecordCodecBuilder.create((instance) ->
|
||||
method_41042(instance).and(
|
||||
RegistryOps.createRegistryCodec(Registry.BIOME_KEY).forGetter((generator) -> generator.biomeRegistry)
|
||||
)
|
||||
.apply(instance, instance.stable(VoidChunkGenerator::new))
|
||||
);
|
||||
method_41042(instance).and(RegistryOps.createRegistryCodec(Registry.BIOME_KEY).forGetter((generator) -> generator.biomeRegistry))
|
||||
.apply(instance, instance.stable(VoidChunkGenerator::new)));
|
||||
|
||||
private final Registry<Biome> biomeRegistry;
|
||||
|
||||
|
@ -65,22 +62,11 @@ public class VoidChunkGenerator extends ChunkGenerator {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ChunkGenerator withSeed(long seed) {
|
||||
return this;
|
||||
public void carve(ChunkRegion chunkRegion, long l, class_7138 rng, BiomeAccess biomeAccess, StructureAccessor structureAccessor, Chunk chunk, GenerationStep.Carver carver) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiNoiseUtil.MultiNoiseSampler getMultiNoiseSampler() {
|
||||
// Mirror what Vanilla does in the debug chunk generator
|
||||
return MultiNoiseUtil.method_40443();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void carve(ChunkRegion chunkRegion, long l, BiomeAccess biomeAccess, StructureAccessor structureAccessor, Chunk chunk, GenerationStep.Carver carver) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildSurface(ChunkRegion region, StructureAccessor structureAccessor, Chunk chunk) {
|
||||
public void buildSurface(ChunkRegion region, StructureAccessor structureAccessor, class_7138 rng, Chunk chunk) {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -93,7 +79,7 @@ public class VoidChunkGenerator extends ChunkGenerator {
|
|||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Chunk> populateNoise(Executor executor, Blender blender, StructureAccessor structureAccessor, Chunk chunk) {
|
||||
public CompletableFuture<Chunk> populateNoise(Executor executor, Blender blender, class_7138 rng, StructureAccessor structureAccessor, Chunk chunk) {
|
||||
return CompletableFuture.completedFuture(chunk);
|
||||
}
|
||||
|
||||
|
@ -108,16 +94,16 @@ public class VoidChunkGenerator extends ChunkGenerator {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int getHeight(int x, int z, Heightmap.Type heightmapType, HeightLimitView heightLimitView) {
|
||||
public int getHeight(int x, int z, Heightmap.Type heightmapType, HeightLimitView heightLimitView, class_7138 rng) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VerticalBlockSample getColumnSample(int x, int z, HeightLimitView heightLimitView) {
|
||||
public VerticalBlockSample getColumnSample(int x, int z, HeightLimitView heightLimitView, class_7138 rng) {
|
||||
return new VerticalBlockSample(0, new BlockState[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getDebugHudText(List<String> list, BlockPos blockPos) {
|
||||
public void getDebugHudText(List<String> list, class_7138 rng, BlockPos blockPos) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
|||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import net.minecraft.class_7204;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
||||
|
@ -35,6 +36,7 @@ import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket;
|
|||
import net.minecraft.network.packet.c2s.play.PlayerInteractBlockC2SPacket;
|
||||
import net.minecraft.network.packet.c2s.play.PlayerInteractEntityC2SPacket;
|
||||
import net.minecraft.network.packet.c2s.play.PlayerInteractItemC2SPacket;
|
||||
import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.TypedActionResult;
|
||||
|
@ -44,7 +46,6 @@ import net.minecraft.util.math.BlockPos;
|
|||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.GameMode;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import net.fabricmc.fabric.api.event.player.AttackBlockCallback;
|
||||
import net.fabricmc.fabric.api.event.player.AttackEntityCallback;
|
||||
|
@ -61,9 +62,6 @@ public abstract class MixinClientPlayerInteractionManager {
|
|||
@Shadow
|
||||
private GameMode gameMode;
|
||||
|
||||
@Shadow
|
||||
protected abstract void sendPlayerAction(PlayerActionC2SPacket.Action action, BlockPos pos, Direction direction);
|
||||
|
||||
@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/world/GameMode;isCreative()Z", ordinal = 0), method = "attackBlock", cancellable = true)
|
||||
public void attackBlock(BlockPos pos, Direction direction, CallbackInfoReturnable<Boolean> info) {
|
||||
ActionResult result = AttackBlockCallback.EVENT.invoker().interact(client.player, client.world, Hand.MAIN_HAND, pos, direction);
|
||||
|
@ -74,7 +72,7 @@ public abstract class MixinClientPlayerInteractionManager {
|
|||
|
||||
// We also need to let the server process the action if it's accepted.
|
||||
if (result.isAccepted()) {
|
||||
this.sendPlayerAction(PlayerActionC2SPacket.Action.START_DESTROY_BLOCK, pos, direction);
|
||||
method_41931(client.world, id -> new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.START_DESTROY_BLOCK, pos, direction, id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -93,13 +91,19 @@ public abstract class MixinClientPlayerInteractionManager {
|
|||
}
|
||||
}
|
||||
|
||||
@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;getStackInHand(Lnet/minecraft/util/Hand;)Lnet/minecraft/item/ItemStack;", ordinal = 0), method = "interactBlock", cancellable = true)
|
||||
public void interactBlock(ClientPlayerEntity player, ClientWorld world, Hand hand, BlockHitResult blockHitResult, CallbackInfoReturnable<ActionResult> info) {
|
||||
ActionResult result = UseBlockCallback.EVENT.invoker().interact(player, world, hand, blockHitResult);
|
||||
@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerInteractionManager;method_41931(Lnet/minecraft/client/world/ClientWorld;Lnet/minecraft/class_7204;)V"), method = "interactBlock", cancellable = true)
|
||||
public void interactBlock(ClientPlayerEntity player, Hand hand, BlockHitResult blockHitResult, CallbackInfoReturnable<ActionResult> info) {
|
||||
// hook interactBlock between the world border check and the actual block interaction to invoke the use block event first
|
||||
// this needs to be in interactBlock to avoid sending a packet in line with the event javadoc
|
||||
|
||||
if (player.isSpectator()) return; // vanilla spectator check happens later, repeat it before the event to avoid false invocations
|
||||
|
||||
ActionResult result = UseBlockCallback.EVENT.invoker().interact(player, player.world, hand, blockHitResult);
|
||||
|
||||
if (result != ActionResult.PASS) {
|
||||
if (result == ActionResult.SUCCESS) {
|
||||
this.networkHandler.sendPacket(new PlayerInteractBlockC2SPacket(hand, blockHitResult));
|
||||
// send interaction packet to the server with a new sequentially assigned id
|
||||
method_41931(player.clientWorld, id -> new PlayerInteractBlockC2SPacket(hand, blockHitResult, id));
|
||||
}
|
||||
|
||||
info.setReturnValue(result);
|
||||
|
@ -107,12 +111,17 @@ public abstract class MixinClientPlayerInteractionManager {
|
|||
}
|
||||
|
||||
@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayNetworkHandler;sendPacket(Lnet/minecraft/network/Packet;)V", ordinal = 0), method = "interactItem", cancellable = true)
|
||||
public void interactItem(PlayerEntity player, World world, Hand hand, CallbackInfoReturnable<ActionResult> info) {
|
||||
TypedActionResult<ItemStack> result = UseItemCallback.EVENT.invoker().interact(player, world, hand);
|
||||
public void interactItem(PlayerEntity player, Hand hand, CallbackInfoReturnable<ActionResult> info) {
|
||||
// hook interactBlock between the spectator check and sending the first packet to invoke the use item event first
|
||||
// this needs to be in interactBlock to avoid sending a packet in line with the event javadoc
|
||||
TypedActionResult<ItemStack> result = UseItemCallback.EVENT.invoker().interact(player, player.world, hand);
|
||||
|
||||
if (result.getResult() != ActionResult.PASS) {
|
||||
if (result.getResult() == ActionResult.SUCCESS) {
|
||||
this.networkHandler.sendPacket(new PlayerInteractItemC2SPacket(hand));
|
||||
// send the move packet like vanilla to ensure the position+view vectors are accurate
|
||||
networkHandler.sendPacket(new PlayerMoveC2SPacket.Full(player.getX(), player.getY(), player.getZ(), player.getYaw(), player.getPitch(), player.isOnGround()));
|
||||
// send interaction packet to the server with a new sequentially assigned id
|
||||
method_41931((ClientWorld) player.world, id -> new PlayerInteractItemC2SPacket(hand, id));
|
||||
}
|
||||
|
||||
info.setReturnValue(result.getResult());
|
||||
|
@ -145,4 +154,7 @@ public abstract class MixinClientPlayerInteractionManager {
|
|||
info.setReturnValue(result);
|
||||
}
|
||||
}
|
||||
|
||||
@Shadow
|
||||
public abstract void method_41931(ClientWorld clientWorld, class_7204 supplier);
|
||||
}
|
||||
|
|
|
@ -27,13 +27,13 @@ import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
|||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.network.Packet;
|
||||
import net.minecraft.network.listener.ClientPlayPacketListener;
|
||||
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket;
|
||||
import net.minecraft.network.packet.s2c.play.BlockUpdateS2CPacket;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.server.network.ServerPlayerInteractionManager;
|
||||
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Hand;
|
||||
|
@ -44,9 +44,9 @@ import net.minecraft.util.math.Direction;
|
|||
import net.minecraft.world.World;
|
||||
|
||||
import net.fabricmc.fabric.api.event.player.AttackBlockCallback;
|
||||
import net.fabricmc.fabric.api.event.player.PlayerBlockBreakEvents;
|
||||
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
|
||||
import net.fabricmc.fabric.api.event.player.UseItemCallback;
|
||||
import net.fabricmc.fabric.api.event.player.PlayerBlockBreakEvents;
|
||||
|
||||
@Mixin(ServerPlayerInteractionManager.class)
|
||||
public class MixinServerPlayerInteractionManager {
|
||||
|
@ -56,7 +56,7 @@ public class MixinServerPlayerInteractionManager {
|
|||
public ServerPlayerEntity player;
|
||||
|
||||
@Inject(at = @At("HEAD"), method = "processBlockBreakingAction", cancellable = true)
|
||||
public void startBlockBreak(BlockPos pos, PlayerActionC2SPacket.Action playerAction, Direction direction, int i, CallbackInfo info) {
|
||||
public void startBlockBreak(BlockPos pos, PlayerActionC2SPacket.Action playerAction, Direction direction, int worldHeight, int i, CallbackInfo info) {
|
||||
if (playerAction != PlayerActionC2SPacket.Action.START_DESTROY_BLOCK) return;
|
||||
ActionResult result = AttackBlockCallback.EVENT.invoker().interact(player, world, Hand.MAIN_HAND, pos, direction);
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ import org.spongepowered.asm.mixin.Mixin;
|
|||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.command.argument.ArgumentTypes;
|
||||
|
@ -29,20 +29,21 @@ import net.minecraft.command.argument.TestClassArgumentType;
|
|||
import net.minecraft.command.argument.TestFunctionArgumentType;
|
||||
import net.minecraft.command.argument.serialize.ArgumentSerializer;
|
||||
import net.minecraft.command.argument.serialize.ConstantArgumentSerializer;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
@Mixin(ArgumentTypes.class)
|
||||
public abstract class ArgumentTypesMixin {
|
||||
@Shadow
|
||||
public static <T extends ArgumentType<?>> void register(String id, Class<T> argClass, ArgumentSerializer<T> serializer) {
|
||||
private static <A extends ArgumentType<?>, T extends ArgumentSerializer.class_7217<A>> ArgumentSerializer<A, T> register(Registry<ArgumentSerializer<?, ?>> registry, String string, Class<? extends A> clazz, ArgumentSerializer<A, T> argumentSerializer) {
|
||||
throw new AssertionError("Nope.");
|
||||
}
|
||||
|
||||
@Inject(method = "register()V", at = @At("RETURN"))
|
||||
private static void register(CallbackInfo ci) {
|
||||
@Inject(method = "register(Lnet/minecraft/util/registry/Registry;)Lnet/minecraft/command/argument/serialize/ArgumentSerializer;", at = @At("RETURN"))
|
||||
private static void register(Registry<ArgumentSerializer<?, ?>> registry, CallbackInfoReturnable<ArgumentSerializer<?, ?>> ci) {
|
||||
// Registered by vanilla when isDevelopment is enabled.
|
||||
if (!SharedConstants.isDevelopment) {
|
||||
register("test_argument", TestFunctionArgumentType.class, new ConstantArgumentSerializer<>(TestFunctionArgumentType::testFunction));
|
||||
register("test_class", TestClassArgumentType.class, new ConstantArgumentSerializer<>(TestClassArgumentType::testClass));
|
||||
register(registry, "test_argument", TestFunctionArgumentType.class, ConstantArgumentSerializer.method_41999(TestFunctionArgumentType::testFunction));
|
||||
register(registry, "test_class", TestClassArgumentType.class, ConstantArgumentSerializer.method_41999(TestClassArgumentType::testClass));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,15 +16,16 @@
|
|||
|
||||
package net.fabricmc.fabric.mixin.gametest;
|
||||
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.class_7157;
|
||||
import net.minecraft.server.command.CommandManager;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
import net.minecraft.server.command.TestCommand;
|
||||
|
@ -36,7 +37,7 @@ public abstract class CommandManagerMixin {
|
|||
private CommandDispatcher<ServerCommandSource> dispatcher;
|
||||
|
||||
@Inject(method = "<init>", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/command/WorldBorderCommand;register(Lcom/mojang/brigadier/CommandDispatcher;)V", shift = At.Shift.AFTER))
|
||||
private void construct(CommandManager.RegistrationEnvironment environment, CallbackInfo info) {
|
||||
private void construct(CommandManager.RegistrationEnvironment environment, class_7157 arg, CallbackInfo info) {
|
||||
// Registered by vanilla when isDevelopment is enabled.
|
||||
if (!SharedConstants.isDevelopment) {
|
||||
TestCommand.register(this.dispatcher);
|
||||
|
|
|
@ -26,8 +26,8 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.tag.TagKey;
|
||||
import net.minecraft.tag.BlockTags;
|
||||
import net.minecraft.tag.TagKey;
|
||||
|
||||
import net.fabricmc.yarn.constants.MiningLevels;
|
||||
|
||||
|
@ -42,7 +42,7 @@ public final class MiningLevelManagerImpl {
|
|||
private static final ThreadLocal<Reference2IntMap<BlockState>> CACHE = ThreadLocal.withInitial(Reference2IntOpenHashMap::new);
|
||||
|
||||
public static int getRequiredMiningLevel(BlockState state) {
|
||||
return CACHE.get().computeIntIfAbsent(state, s -> {
|
||||
return CACHE.get().computeIfAbsent(state, s -> {
|
||||
int miningLevel = MiningLevels.HAND;
|
||||
|
||||
// Handle #fabric:needs_tool_level_N
|
||||
|
|
|
@ -75,7 +75,7 @@ public abstract class GroupResourcePack implements ResourcePack {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Collection<Identifier> findResources(ResourceType type, String namespace, String prefix, int maxDepth, Predicate<String> pathFilter) {
|
||||
public Collection<Identifier> findResources(ResourceType type, String namespace, String prefix, Predicate<Identifier> predicate) {
|
||||
List<ModResourcePack> packs = this.namespacedPacks.get(namespace);
|
||||
|
||||
if (packs == null) {
|
||||
|
@ -86,7 +86,7 @@ public abstract class GroupResourcePack implements ResourcePack {
|
|||
|
||||
for (int i = packs.size() - 1; i >= 0; i--) {
|
||||
ResourcePack pack = packs.get(i);
|
||||
Collection<Identifier> modResources = pack.findResources(type, namespace, prefix, maxDepth, pathFilter);
|
||||
Collection<Identifier> modResources = pack.findResources(type, namespace, prefix, predicate);
|
||||
|
||||
resources.addAll(modResources);
|
||||
}
|
||||
|
|
|
@ -36,8 +36,8 @@ import java.util.Set;
|
|||
import java.util.function.Predicate;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import net.minecraft.resource.AbstractFileResourcePack;
|
||||
import net.minecraft.resource.ResourceType;
|
||||
|
@ -209,7 +209,7 @@ public class ModNioResourcePack extends AbstractFileResourcePack implements ModR
|
|||
}
|
||||
|
||||
@Override
|
||||
public Collection<Identifier> findResources(ResourceType type, String namespace, String path, int depth, Predicate<String> predicate) {
|
||||
public Collection<Identifier> findResources(ResourceType type, String namespace, String path, Predicate<Identifier> predicate) {
|
||||
if (!namespaces.getOrDefault(type, Collections.emptySet()).contains(namespace)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
@ -227,14 +227,13 @@ public class ModNioResourcePack extends AbstractFileResourcePack implements ModR
|
|||
@Override
|
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
||||
String fileName = file.getFileName().toString();
|
||||
if (fileName.endsWith(".mcmeta")) return FileVisitResult.CONTINUE;
|
||||
|
||||
if (!fileName.endsWith(".mcmeta")
|
||||
&& predicate.test(fileName)) {
|
||||
try {
|
||||
ids.add(new Identifier(namespace, nsPath.relativize(file).toString().replace(separator, "/")));
|
||||
} catch (InvalidIdentifierException e) {
|
||||
LOGGER.error(e.getMessage());
|
||||
}
|
||||
try {
|
||||
Identifier id = new Identifier(namespace, nsPath.relativize(file).toString().replace(separator, "/"));
|
||||
if (predicate.test(id)) ids.add(id);
|
||||
} catch (InvalidIdentifierException e) {
|
||||
LOGGER.error(e.getMessage());
|
||||
}
|
||||
|
||||
return FileVisitResult.CONTINUE;
|
||||
|
|
|
@ -71,10 +71,10 @@ public class ProgrammerArtResourcePack extends GroupResourcePack {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Collection<Identifier> findResources(ResourceType type, String namespace, String prefix, int maxDepth, Predicate<String> pathFilter) {
|
||||
Set<Identifier> resources = new HashSet<>(this.originalResourcePack.findResources(type, namespace, prefix, maxDepth, pathFilter));
|
||||
public Collection<Identifier> findResources(ResourceType type, String namespace, String prefix, Predicate<Identifier> predicate) {
|
||||
Set<Identifier> resources = new HashSet<>(this.originalResourcePack.findResources(type, namespace, prefix, predicate));
|
||||
|
||||
resources.addAll(super.findResources(type, namespace, prefix, maxDepth, pathFilter));
|
||||
resources.addAll(super.findResources(type, namespace, prefix, predicate));
|
||||
|
||||
return resources;
|
||||
}
|
||||
|
|
|
@ -83,8 +83,8 @@ public abstract class DefaultResourcePackMixin {
|
|||
* @reason Gets rid of classpath scanning.
|
||||
*/
|
||||
@Overwrite
|
||||
public Collection<Identifier> findResources(ResourceType type, String namespace, String prefix, int maxDepth, Predicate<String> pathFilter) {
|
||||
return fabric_mcJarPack.findResources(type, namespace, prefix, maxDepth, pathFilter);
|
||||
public Collection<Identifier> findResources(ResourceType type, String namespace, String prefix, Predicate<Identifier> predicate) {
|
||||
return fabric_mcJarPack.findResources(type, namespace, prefix, predicate);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.spongepowered.asm.mixin.Shadow;
|
|||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import net.minecraft.client.gui.screen.world.CreateWorldScreen;
|
||||
|
@ -44,6 +45,14 @@ public class CreateWorldScreenMixin {
|
|||
@Shadow
|
||||
private ResourcePackManager packManager;
|
||||
|
||||
@ModifyVariable(method = "create(Lnet/minecraft/client/MinecraftClient;Lnet/minecraft/client/gui/screen/Screen;)V",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/world/CreateWorldScreen;method_41849(Lnet/minecraft/resource/ResourcePackManager;Lnet/minecraft/resource/DataPackSettings;)Lnet/minecraft/class_7237$FunctionLoaderConfig;"))
|
||||
private static ResourcePackManager onCreateResManagerInit(ResourcePackManager manager) {
|
||||
// Add mod data packs to the initial res pack manager so they are active even if the user doesn't use custom data packs
|
||||
((ResourcePackManagerAccessor) manager).getProviders().add(new ModResourcePackCreator(ResourceType.SERVER_DATA));
|
||||
return manager;
|
||||
}
|
||||
|
||||
@Inject(method = "getScannedPack", at = @At(value = "INVOKE", target = "Lnet/minecraft/resource/ResourcePackManager;scanPacks()V", shift = At.Shift.BEFORE))
|
||||
private void onScanPacks(CallbackInfoReturnable<Pair<File, ResourcePackManager>> cir) {
|
||||
// Allow to display built-in data packs in the data pack selection screen at world creation.
|
||||
|
|
|
@ -127,7 +127,7 @@ abstract class MouseMixin {
|
|||
}
|
||||
|
||||
// Apply same calculations to horizontal scroll as vertical scroll amount has
|
||||
this.horizontalScrollAmount = this.client.options.discreteMouseScroll ? Math.signum(horizontal) : horizontal * this.client.options.mouseWheelSensitivity;
|
||||
this.horizontalScrollAmount = this.client.options.discreteMouseScroll ? Math.signum(horizontal) : horizontal * this.client.options.method_41806().method_41753();
|
||||
|
||||
if (!ScreenMouseEvents.allowMouseScroll(this.currentScreen).invoker().allowMouseScroll(this.currentScreen, mouseX, mouseY, this.horizontalScrollAmount, verticalAmount)) {
|
||||
this.currentScreen = null;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
org.gradle.jvmargs=-Xmx2560M
|
||||
|
||||
version=0.48.0
|
||||
minecraft_version=1.18.2
|
||||
yarn_version=+build.1
|
||||
loader_version=0.13.2
|
||||
version=0.49.0
|
||||
minecraft_version=22w11a
|
||||
yarn_version=+build.2
|
||||
loader_version=0.13.3
|
||||
|
||||
prerelease=false
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
"depends": {
|
||||
"fabricloader": ">=0.13.2",
|
||||
"java": ">=17",
|
||||
"minecraft": "~1.18.2-alpha.22.5.a"
|
||||
"minecraft": "~1.19-alpha.22.11.a"
|
||||
},
|
||||
"description": "Core API module providing key hooks and intercompatibility features."
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue