mirror of
https://github.com/FabricMC/fabric.git
synced 2024-11-28 02:26:01 -05:00
24w36a (#4068)
* 24w36a * Some fixes * More work * Fixes * Update yarn * Update fabric loader * Bump versions
This commit is contained in:
parent
2ade441e60
commit
d48ec150ba
127 changed files with 493 additions and 943 deletions
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3",
|
||||
"fabricloader": ">=0.16.4",
|
||||
"fabric-api-base": "*",
|
||||
"fabric-command-api-v2": "*"
|
||||
},
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3",
|
||||
"fabricloader": ">=0.16.4",
|
||||
"fabric-api-base": "*",
|
||||
"fabric-command-api-v2": "*"
|
||||
},
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
]
|
||||
},
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3",
|
||||
"fabricloader": ">=0.16.4",
|
||||
"minecraft": ">=1.18.2"
|
||||
},
|
||||
"description": "Contains common tags used by mods for vanilla things.",
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3",
|
||||
"fabricloader": ">=0.16.4",
|
||||
"fabric-key-binding-api-v1": "*"
|
||||
},
|
||||
"description": "Keybinding registry API.",
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3",
|
||||
"fabricloader": ">=0.16.4",
|
||||
"fabric-api-base": "*",
|
||||
"fabric-resource-loader-v0": "*"
|
||||
},
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3",
|
||||
"fabricloader": ">=0.16.4",
|
||||
"fabric-block-view-api-v2": "*"
|
||||
},
|
||||
"description": "Thread-safe hooks for block entity data use during terrain rendering.",
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
]
|
||||
},
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3",
|
||||
"fabricloader": ">=0.16.4",
|
||||
"minecraft": ">=1.15-alpha.19.39.a",
|
||||
"fabric-api-base": "*",
|
||||
"fabric-rendering-v1": "*"
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3"
|
||||
"fabricloader": ">=0.16.4"
|
||||
},
|
||||
"description": "Contains the essentials for Fabric API modules.",
|
||||
"custom": {
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3",
|
||||
"fabricloader": ">=0.16.4",
|
||||
"fabric-api-base": "*",
|
||||
"fabric-lifecycle-events-v1": "*"
|
||||
},
|
||||
|
|
|
@ -46,19 +46,19 @@ public class FabricApiLookupTest implements ModInitializer {
|
|||
// It's meant to work with unsided containers: chests, dispensers, droppers and hoppers.
|
||||
public static final RegistryKey<Block> CHUTE_BLOCK_KEY = keyOf("chute");
|
||||
public static final ChuteBlock CHUTE_BLOCK = new ChuteBlock(AbstractBlock.Settings.create().registryKey(CHUTE_BLOCK_KEY));
|
||||
public static final BlockItem CHUTE_ITEM = new BlockItem(CHUTE_BLOCK, new Item.Settings());
|
||||
public static final BlockItem CHUTE_ITEM = new BlockItem(CHUTE_BLOCK, new Item.Settings().registryKey(RegistryKey.of(RegistryKeys.ITEM, CHUTE_BLOCK_KEY.getValue())));
|
||||
public static BlockEntityType<ChuteBlockEntity> CHUTE_BLOCK_ENTITY_TYPE;
|
||||
// Cobble gen - Block without model that can generate infinite cobblestone when placed above a chute.
|
||||
// It's meant to test BlockApiLookup#registerSelf.
|
||||
public static final RegistryKey<Block> COBBLE_GEN_BLOCK_KEY = keyOf("cobble_gen");
|
||||
public static final CobbleGenBlock COBBLE_GEN_BLOCK = new CobbleGenBlock(AbstractBlock.Settings.create().registryKey(COBBLE_GEN_BLOCK_KEY));
|
||||
public static final BlockItem COBBLE_GEN_ITEM = new BlockItem(COBBLE_GEN_BLOCK, new Item.Settings());
|
||||
public static final BlockItem COBBLE_GEN_ITEM = new BlockItem(COBBLE_GEN_BLOCK, new Item.Settings().registryKey(RegistryKey.of(RegistryKeys.ITEM, COBBLE_GEN_BLOCK_KEY.getValue())));
|
||||
public static BlockEntityType<CobbleGenBlockEntity> COBBLE_GEN_BLOCK_ENTITY_TYPE;
|
||||
// Testing for item api lookups is done in the `item` package.
|
||||
|
||||
public static final RegistryKey<Block> INSPECTOR_BLOCK_KEY = keyOf("inspector");
|
||||
public static final InspectorBlock INSPECTOR_BLOCK = new InspectorBlock(AbstractBlock.Settings.create().registryKey(INSPECTOR_BLOCK_KEY));
|
||||
public static final BlockItem INSPECTOR_ITEM = new BlockItem(INSPECTOR_BLOCK, new Item.Settings());
|
||||
public static final BlockItem INSPECTOR_ITEM = new BlockItem(INSPECTOR_BLOCK, new Item.Settings().registryKey(RegistryKey.of(RegistryKeys.ITEM, INSPECTOR_BLOCK_KEY.getValue())));
|
||||
|
||||
private static RegistryKey<Block> keyOf(String id) {
|
||||
return RegistryKey.of(RegistryKeys.BLOCK, Identifier.of(MOD_ID, id));
|
||||
|
|
|
@ -19,9 +19,12 @@ package net.fabricmc.fabric.test.lookup.item;
|
|||
import static net.fabricmc.fabric.test.lookup.FabricApiLookupTest.ensureException;
|
||||
|
||||
import net.minecraft.component.DataComponentTypes;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
import net.minecraft.registry.RegistryKeys;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
|
@ -33,10 +36,11 @@ public class FabricItemApiLookupTest {
|
|||
public static final ItemApiLookup<Inspectable, Void> INSPECTABLE =
|
||||
ItemApiLookup.get(Identifier.of("testmod", "inspectable"), Inspectable.class, Void.class);
|
||||
|
||||
public static final InspectableItem HELLO_ITEM = new InspectableItem("Hello Fabric API tester!");
|
||||
public static final RegistryKey<Item> HELLO_ITEM_KEY = RegistryKey.of(RegistryKeys.ITEM, Identifier.of(FabricApiLookupTest.MOD_ID, "hello"));
|
||||
public static final InspectableItem HELLO_ITEM = new InspectableItem("Hello Fabric API tester!", new Item.Settings().registryKey(HELLO_ITEM_KEY));
|
||||
|
||||
public static void onInitialize() {
|
||||
Registry.register(Registries.ITEM, Identifier.of(FabricApiLookupTest.MOD_ID, "hello"), HELLO_ITEM);
|
||||
Registry.register(Registries.ITEM, HELLO_ITEM_KEY, HELLO_ITEM);
|
||||
|
||||
// Diamonds and diamond blocks can be inspected and will also print their name.
|
||||
INSPECTABLE.registerForItems((stack, ignored) -> () -> {
|
||||
|
|
|
@ -24,8 +24,8 @@ import net.fabricmc.fabric.test.lookup.api.Inspectable;
|
|||
public class InspectableItem extends Item implements Inspectable {
|
||||
private final String inspectionResult;
|
||||
|
||||
public InspectableItem(String inspectionResult) {
|
||||
super(new Settings());
|
||||
public InspectableItem(String inspectionResult, Item.Settings settings) {
|
||||
super(settings);
|
||||
this.inspectionResult = inspectionResult;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3",
|
||||
"fabricloader": ">=0.16.4",
|
||||
"minecraft": ">=1.16.2"
|
||||
},
|
||||
"description": "Hooks for adding biomes to the default world generator.",
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3"
|
||||
"fabricloader": ">=0.16.4"
|
||||
},
|
||||
"entrypoints": {
|
||||
},
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3"
|
||||
"fabricloader": ">=0.16.4"
|
||||
},
|
||||
"description": "Hooks for block views",
|
||||
"mixins": [
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3",
|
||||
"fabricloader": ">=0.16.4",
|
||||
"minecraft": ">=1.15-alpha.19.38.b",
|
||||
"fabric-api-base": "*"
|
||||
},
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3"
|
||||
"fabricloader": ">=0.16.4"
|
||||
},
|
||||
"description": "Adds the ability to load tags from the local mods.",
|
||||
"custom": {
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3",
|
||||
"fabricloader": ">=0.16.4",
|
||||
"fabric-api-base": "*",
|
||||
"minecraft": ">1.19-alpha.22.11.a"
|
||||
},
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3",
|
||||
"fabricloader": ">=0.16.4",
|
||||
"fabric-api-base": "*",
|
||||
"fabric-lifecycle-events-v1": "*",
|
||||
"fabric-resource-loader-v0": "*"
|
||||
|
|
|
@ -150,9 +150,9 @@ public final class ContentRegistryTest implements ModInitializer {
|
|||
LOGGER.info("SculkSensorFrequencyRegistry test passed!");
|
||||
}
|
||||
|
||||
var dirtyPotion = new DirtyPotionItem(new Item.Settings().maxCount(1));
|
||||
Registry.register(Registries.ITEM, Identifier.of("fabric-content-registries-v0-testmod", "dirty_potion"),
|
||||
dirtyPotion);
|
||||
RegistryKey<Item> dirtyPotionKey = RegistryKey.of(RegistryKeys.ITEM, Identifier.of("fabric-content-registries-v0-testmod", "dirty_potion"));
|
||||
var dirtyPotion = new DirtyPotionItem(new Item.Settings().maxCount(1).registryKey(dirtyPotionKey));
|
||||
Registry.register(Registries.ITEM, dirtyPotionKey, dirtyPotion);
|
||||
/* Mods should use BrewingRecipeRegistry.registerPotionType(Item), which is access widened by fabric-transitive-access-wideners-v1
|
||||
* This testmod uses an accessor due to Loom limitations that prevent TAWs from applying across Gradle subproject boundaries */
|
||||
FabricBrewingRecipeRegistryBuilder.BUILD.register(builder -> {
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3",
|
||||
"fabricloader": ">=0.16.4",
|
||||
"minecraft": ">=1.18.2"
|
||||
},
|
||||
"description": "Contains common tags used by mods for vanilla things.",
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
]
|
||||
},
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3",
|
||||
"fabricloader": ">=0.16.4",
|
||||
"minecraft": ">=1.20.5-beta.1",
|
||||
"fabric-lifecycle-events-v1": "*"
|
||||
},
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3"
|
||||
"fabricloader": ">=0.16.4"
|
||||
},
|
||||
"description": "Adds Fabric-related debug info to crash reports.",
|
||||
"mixins": [
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3",
|
||||
"fabricloader": ">=0.16.4",
|
||||
"fabric-entity-events-v1": "*",
|
||||
"fabric-object-builder-api-v1": "*"
|
||||
},
|
||||
|
|
|
@ -16,19 +16,22 @@
|
|||
|
||||
package net.fabricmc.fabric.test.attachment.gametest;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.IntSupplier;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.SpawnReason;
|
||||
import net.minecraft.entity.mob.MobEntity;
|
||||
import net.minecraft.entity.mob.DrownedEntity;
|
||||
import net.minecraft.entity.mob.ZombieEntity;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.test.GameTest;
|
||||
import net.minecraft.test.GameTestException;
|
||||
import net.minecraft.test.TestContext;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.TeleportTarget;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
|
@ -36,6 +39,7 @@ import net.fabricmc.fabric.api.attachment.v1.AttachmentRegistry;
|
|||
import net.fabricmc.fabric.api.attachment.v1.AttachmentType;
|
||||
import net.fabricmc.fabric.api.gametest.v1.FabricGameTest;
|
||||
import net.fabricmc.fabric.test.attachment.AttachmentTestMod;
|
||||
import net.fabricmc.fabric.test.attachment.mixin.ZombieEntityAccessor;
|
||||
|
||||
public class AttachmentCopyTests implements FabricGameTest {
|
||||
// using a lambda type because serialization shouldn't play a role in this
|
||||
|
@ -74,10 +78,19 @@ public class AttachmentCopyTests implements FabricGameTest {
|
|||
|
||||
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
|
||||
public void testMobConversion(TestContext context) {
|
||||
MobEntity mob = Objects.requireNonNull(EntityType.ZOMBIE.create(context.getWorld(), SpawnReason.SPAWN_EGG));
|
||||
ZombieEntity mob = context.spawnEntity(EntityType.ZOMBIE, BlockPos.ORIGIN);
|
||||
mob.setAttached(DUMMY, () -> 42);
|
||||
mob.setAttached(COPY_ON_DEATH, () -> 42);
|
||||
MobEntity converted = mob.convertTo(EntityType.DROWNED, false);
|
||||
|
||||
ZombieEntityAccessor zombieEntityAccessor = (ZombieEntityAccessor) mob;
|
||||
zombieEntityAccessor.invokeConvertTo(EntityType.DROWNED);
|
||||
List<DrownedEntity> drowned = context.getEntities(EntityType.DROWNED);
|
||||
|
||||
if (drowned.size() != 1) {
|
||||
throw new GameTestException("Conversion failed");
|
||||
}
|
||||
|
||||
DrownedEntity converted = drowned.getFirst();
|
||||
if (converted == null) throw new GameTestException("Conversion failed");
|
||||
|
||||
if (converted.hasAttached(DUMMY)) {
|
||||
|
|
|
@ -14,15 +14,16 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.test.entity.event;
|
||||
package net.fabricmc.fabric.test.attachment.mixin;
|
||||
|
||||
import net.minecraft.item.ArmorItem;
|
||||
import net.minecraft.item.ArmorMaterials;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
import net.fabricmc.fabric.api.entity.event.v1.FabricElytraItem;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.mob.ZombieEntity;
|
||||
|
||||
public class DiamondElytraItem extends ArmorItem implements FabricElytraItem {
|
||||
public DiamondElytraItem() {
|
||||
super(ArmorMaterials.DIAMOND, Type.CHESTPLATE, new Settings().maxCount(1).maxDamage(100));
|
||||
}
|
||||
@Mixin(ZombieEntity.class)
|
||||
public interface ZombieEntityAccessor {
|
||||
@Invoker("convertTo")
|
||||
void invokeConvertTo(EntityType<? extends ZombieEntity> entityType);
|
||||
}
|
|
@ -3,7 +3,8 @@
|
|||
"package": "net.fabricmc.fabric.test.attachment.mixin",
|
||||
"compatibilityLevel": "JAVA_21",
|
||||
"mixins": [
|
||||
"BlockEntityTypeAccessor"
|
||||
"BlockEntityTypeAccessor",
|
||||
"ZombieEntityAccessor"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
|
|
|
@ -317,8 +317,8 @@ transitive-accessible method net/minecraft/data/client/ItemModelGenerator regist
|
|||
transitive-accessible method net/minecraft/data/client/ItemModelGenerator uploadArmor (Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;)V
|
||||
transitive-accessible method net/minecraft/data/client/ItemModelGenerator uploadArmor (Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;)V
|
||||
transitive-accessible method net/minecraft/data/client/ItemModelGenerator suffixTrim (Lnet/minecraft/util/Identifier;Ljava/lang/String;)Lnet/minecraft/util/Identifier;
|
||||
transitive-accessible method net/minecraft/data/client/ItemModelGenerator createArmorJson (Lnet/minecraft/util/Identifier;Ljava/util/Map;Lnet/minecraft/registry/entry/RegistryEntry;)Lcom/google/gson/JsonObject;
|
||||
transitive-accessible method net/minecraft/data/client/ItemModelGenerator registerArmor (Lnet/minecraft/item/ArmorItem;)V
|
||||
transitive-accessible method net/minecraft/data/client/ItemModelGenerator createArmorJson (Lnet/minecraft/util/Identifier;Ljava/util/Map;Lnet/minecraft/util/Identifier;)Lcom/google/gson/JsonObject;
|
||||
transitive-accessible method net/minecraft/data/client/ItemModelGenerator registerArmor (Lnet/minecraft/item/Item;Lnet/minecraft/util/Identifier;Lnet/minecraft/item/equipment/EquipmentModel;Lnet/minecraft/entity/EquipmentSlot;)V
|
||||
transitive-extendable method net/minecraft/data/MetadataProvider getName ()Ljava/lang/String;
|
||||
transitive-extendable method net/minecraft/data/SnbtProvider getName ()Ljava/lang/String;
|
||||
transitive-extendable method net/minecraft/data/client/ModelProvider getName ()Ljava/lang/String;
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3"
|
||||
"fabricloader": ">=0.16.4"
|
||||
},
|
||||
"description": "Allows for automatic data generation.",
|
||||
"mixins": [
|
||||
|
|
|
@ -88,7 +88,7 @@ public class DataGeneratorTestContent implements ModInitializer {
|
|||
Block block = Registry.register(Registries.BLOCK, identifier, new Block(settings.registryKey(RegistryKey.of(RegistryKeys.BLOCK, identifier))));
|
||||
|
||||
if (hasItem) {
|
||||
Registry.register(Registries.ITEM, identifier, new BlockItem(block, new Item.Settings()));
|
||||
Registry.register(Registries.ITEM, identifier, new BlockItem(block, new Item.Settings().registryKey(RegistryKey.of(RegistryKeys.ITEM, identifier))));
|
||||
}
|
||||
|
||||
return block;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3",
|
||||
"fabricloader": ">=0.16.4",
|
||||
"minecraft": ">=1.16-rc.3",
|
||||
"fabric-api-base": "*"
|
||||
},
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
/*
|
||||
* 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.client.entity.event.elytra;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
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.Slice;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import net.minecraft.client.network.AbstractClientPlayerEntity;
|
||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.network.packet.c2s.play.ClientCommandC2SPacket;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Mixin(ClientPlayerEntity.class)
|
||||
abstract class ClientPlayerEntityMixin extends AbstractClientPlayerEntity {
|
||||
ClientPlayerEntityMixin(ClientWorld world, GameProfile profile) {
|
||||
super(world, profile);
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private ClientPlayNetworkHandler networkHandler;
|
||||
|
||||
/**
|
||||
* Call {@link #checkFallFlying()} even if the player is not wearing {@link Items#ELYTRA} to allow custom elytra flight.
|
||||
*/
|
||||
@Inject(at = @At(value = "FIELD", target = "Lnet/minecraft/entity/EquipmentSlot;CHEST:Lnet/minecraft/entity/EquipmentSlot;"), method = "tickMovement", slice = @Slice(from = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;isClimbing()Z"), to = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;checkFallFlying()Z")), allow = 1)
|
||||
void injectElytraStart(CallbackInfo info) {
|
||||
// Note that if fall flying is not ALLOWed, checkFallFlying will return false and nothing will happen.
|
||||
if (this.checkFallFlying()) {
|
||||
networkHandler.sendPacket(new ClientCommandC2SPacket(this, ClientCommandC2SPacket.Mode.START_FALL_FLYING));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"required": true,
|
||||
"package": "net.fabricmc.fabric.mixin.client.entity.event",
|
||||
"compatibilityLevel": "JAVA_21",
|
||||
"client": [
|
||||
"elytra.ClientPlayerEntityMixin"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1,
|
||||
"maxShiftBy": 3
|
||||
}
|
||||
}
|
|
@ -16,9 +16,8 @@
|
|||
|
||||
package net.fabricmc.fabric.api.entity.event.v1;
|
||||
|
||||
import net.minecraft.entity.EquipmentSlot;
|
||||
import net.minecraft.component.DataComponentTypes;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import net.fabricmc.fabric.api.event.Event;
|
||||
import net.fabricmc.fabric.api.event.EventFactory;
|
||||
|
@ -45,7 +44,7 @@ public final class EntityElytraEvents {
|
|||
* An event to grant elytra flight to living entities when some condition is met.
|
||||
* Will be called when players try to start elytra flight by pressing space in mid-air, and every tick for all flying living entities to check if elytra flight is still allowed.
|
||||
*
|
||||
* <p>Items that wish to enable custom elytra flight when worn in the chest equipment slot can simply implement {@link FabricElytraItem} instead of registering a listener.
|
||||
* <p>Items that wish to enable custom elytra flight when worn in the chest equipment slot can add the {@link DataComponentTypes#GLIDER} component to an item.
|
||||
*/
|
||||
public static final Event<Custom> CUSTOM = EventFactory.createArrayBacked(Custom.class, listeners -> (entity, tickElytra) -> {
|
||||
for (Custom listener : listeners) {
|
||||
|
@ -57,18 +56,6 @@ public final class EntityElytraEvents {
|
|||
return false;
|
||||
});
|
||||
|
||||
static {
|
||||
CUSTOM.register((entity, tickElytra) -> {
|
||||
ItemStack chestStack = entity.getEquippedStack(EquipmentSlot.CHEST);
|
||||
|
||||
if (chestStack.getItem() instanceof FabricElytraItem fabricElytraItem) {
|
||||
return fabricElytraItem.useCustomElytra(entity, chestStack, tickElytra);
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Allow {
|
||||
/**
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
* 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.api.entity.event.v1;
|
||||
|
||||
import net.minecraft.entity.EquipmentSlot;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.item.ElytraItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.event.GameEvent;
|
||||
|
||||
/**
|
||||
* An interface that can be implemented on an item to provide custom elytra flight when it is worn in the {@link EquipmentSlot#CHEST} slot.
|
||||
*
|
||||
* <p>To disable cape rendering when this item is worn (like the vanilla elytra item), have a look at {@code LivingEntityFeatureRenderEvents}.
|
||||
*/
|
||||
public interface FabricElytraItem {
|
||||
/**
|
||||
* Try to use this custom elytra.
|
||||
*
|
||||
* @param entity the entity
|
||||
* @param chestStack the stack currently worn in the chest slot, will always be of this item
|
||||
* @param tickElytra true to tick the elytra, false to only perform the check; vanilla-like elytras can use {@link #doVanillaElytraTick} to handle ticking
|
||||
* @return true to enable elytra flight for the entity
|
||||
*/
|
||||
default boolean useCustomElytra(LivingEntity entity, ItemStack chestStack, boolean tickElytra) {
|
||||
if (ElytraItem.isUsable(chestStack)) {
|
||||
if (tickElytra) {
|
||||
doVanillaElytraTick(entity, chestStack);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper to perform the default vanilla elytra tick logic: damage the elytra every 20 ticks, and send a game event every 10 ticks.
|
||||
*/
|
||||
default void doVanillaElytraTick(LivingEntity entity, ItemStack chestStack) {
|
||||
int nextRoll = entity.getFallFlyingTicks() + 1;
|
||||
|
||||
if (!entity.getWorld().isClient && nextRoll % 10 == 0) {
|
||||
if ((nextRoll / 10) % 2 == 0) {
|
||||
chestStack.damage(1, entity, EquipmentSlot.CHEST);
|
||||
}
|
||||
|
||||
entity.emitGameEvent(GameEvent.ELYTRA_GLIDE);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,6 +17,7 @@
|
|||
package net.fabricmc.fabric.api.entity.event.v1;
|
||||
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.conversion.EntityConversionContext;
|
||||
import net.minecraft.entity.damage.DamageSource;
|
||||
import net.minecraft.entity.mob.MobEntity;
|
||||
|
||||
|
@ -166,9 +167,9 @@ public final class ServerLivingEntityEvents {
|
|||
*
|
||||
* @param previous the previous entity instance
|
||||
* @param converted the new instance for the converted entity
|
||||
* @param keepEquipment whether the converted entity should keep the previous one's equipment, like armor
|
||||
* @param conversionContext the context used for the conversion
|
||||
*/
|
||||
void onConversion(MobEntity previous, MobEntity converted, boolean keepEquipment);
|
||||
void onConversion(MobEntity previous, MobEntity converted, EntityConversionContext conversionContext);
|
||||
}
|
||||
|
||||
private ServerLivingEntityEvents() {
|
||||
|
|
|
@ -22,15 +22,16 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.conversion.EntityConversionContext;
|
||||
import net.minecraft.entity.mob.MobEntity;
|
||||
|
||||
import net.fabricmc.fabric.api.entity.event.v1.ServerLivingEntityEvents;
|
||||
|
||||
@Mixin(MobEntity.class)
|
||||
public class MobEntityMixin {
|
||||
@ModifyArg(method = "convertTo", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;spawnEntity(Lnet/minecraft/entity/Entity;)Z"))
|
||||
private Entity afterEntityConverted(Entity converted, @Local(argsOnly = true) boolean keepEquipment) {
|
||||
ServerLivingEntityEvents.MOB_CONVERSION.invoker().onConversion((MobEntity) (Object) this, (MobEntity) converted, keepEquipment);
|
||||
@ModifyArg(method = "convertTo", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/world/ServerWorld;spawnEntityAndPassengers(Lnet/minecraft/entity/Entity;)V"))
|
||||
private Entity afterEntityConverted(Entity converted, @Local(argsOnly = true) EntityConversionContext conversionContext) {
|
||||
ServerLivingEntityEvents.MOB_CONVERSION.invoker().onConversion((MobEntity) (Object) this, (MobEntity) converted, conversionContext);
|
||||
return converted;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* 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.entity.event;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.mob.MobEntity;
|
||||
import net.minecraft.entity.passive.MooshroomEntity;
|
||||
|
||||
import net.fabricmc.fabric.api.entity.event.v1.ServerLivingEntityEvents;
|
||||
|
||||
@Mixin(MooshroomEntity.class)
|
||||
class MooshroomEntityMixin {
|
||||
@ModifyArg(
|
||||
method = "sheared",
|
||||
at = @At(ordinal = 0, value = "INVOKE", target = "Lnet/minecraft/world/World;spawnEntity(Lnet/minecraft/entity/Entity;)Z")
|
||||
)
|
||||
private Entity afterMooshroomConversion(Entity converted) {
|
||||
ServerLivingEntityEvents.MOB_CONVERSION.invoker().onConversion((MooshroomEntity) (Object) this, (MobEntity) converted, false);
|
||||
return converted;
|
||||
}
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
/*
|
||||
* 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.entity.event;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.mob.MobEntity;
|
||||
import net.minecraft.entity.passive.AnimalEntity;
|
||||
import net.minecraft.entity.passive.PigEntity;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import net.fabricmc.fabric.api.entity.event.v1.ServerLivingEntityEvents;
|
||||
|
||||
@Mixin(PigEntity.class)
|
||||
abstract class PigEntityMixin extends AnimalEntity {
|
||||
protected PigEntityMixin(EntityType<? extends AnimalEntity> entityType, World world) {
|
||||
super(entityType, world);
|
||||
}
|
||||
|
||||
@ModifyArg(
|
||||
method = "onStruckByLightning",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/server/world/ServerWorld;spawnEntity(Lnet/minecraft/entity/Entity;)Z")
|
||||
)
|
||||
private Entity afterPiglinConversion(Entity converted) {
|
||||
ServerLivingEntityEvents.MOB_CONVERSION.invoker().onConversion(this, (MobEntity) converted, false);
|
||||
return converted;
|
||||
}
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
/*
|
||||
* 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.entity.event;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.mob.MobEntity;
|
||||
import net.minecraft.entity.passive.FishEntity;
|
||||
import net.minecraft.entity.passive.TadpoleEntity;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import net.fabricmc.fabric.api.entity.event.v1.ServerLivingEntityEvents;
|
||||
|
||||
@Mixin(TadpoleEntity.class)
|
||||
abstract class TadpoleEntityMixin extends FishEntity {
|
||||
TadpoleEntityMixin(EntityType<? extends FishEntity> entityType, World world) {
|
||||
super(entityType, world);
|
||||
}
|
||||
|
||||
@ModifyArg(
|
||||
method = "growUp",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/server/world/ServerWorld;spawnEntityAndPassengers(Lnet/minecraft/entity/Entity;)V")
|
||||
)
|
||||
private Entity afterGrowingUpToFrog(Entity converted) {
|
||||
ServerLivingEntityEvents.MOB_CONVERSION.invoker().onConversion(this, (MobEntity) converted, false);
|
||||
return converted;
|
||||
}
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
/*
|
||||
* 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.entity.event;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.mob.MobEntity;
|
||||
import net.minecraft.entity.passive.MerchantEntity;
|
||||
import net.minecraft.entity.passive.VillagerEntity;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import net.fabricmc.fabric.api.entity.event.v1.ServerLivingEntityEvents;
|
||||
|
||||
@Mixin(VillagerEntity.class)
|
||||
abstract class VillagerEntityMixin extends MerchantEntity {
|
||||
VillagerEntityMixin(EntityType<? extends MerchantEntity> entityType, World world) {
|
||||
super(entityType, world);
|
||||
}
|
||||
|
||||
@ModifyArg(
|
||||
method = "onStruckByLightning",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/server/world/ServerWorld;spawnEntityAndPassengers(Lnet/minecraft/entity/Entity;)V")
|
||||
)
|
||||
private Entity afterWitchConversion(Entity converted) {
|
||||
ServerLivingEntityEvents.MOB_CONVERSION.invoker().onConversion(this, (MobEntity) converted, false);
|
||||
return converted;
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
* 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.entity.event.elytra;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
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 net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.mob.ElytraFlightController;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import net.fabricmc.fabric.api.entity.event.v1.EntityElytraEvents;
|
||||
|
||||
@Mixin(ElytraFlightController.class)
|
||||
public class ElytraFlightControllerMixin {
|
||||
@Shadow
|
||||
@Final
|
||||
private LivingEntity entity;
|
||||
|
||||
@WrapOperation(method = "update", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z"))
|
||||
private boolean checkAllowEvent(ItemStack instance, Item item, Operation<Boolean> original) {
|
||||
// ALLOW event is checked by LivingEntityMixin.
|
||||
return original.call(instance, item) || EntityElytraEvents.CUSTOM.invoker().useCustomElytra(this.entity, false);
|
||||
}
|
||||
}
|
|
@ -20,10 +20,12 @@ 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.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import net.fabricmc.fabric.api.entity.event.v1.EntityElytraEvents;
|
||||
|
@ -40,14 +42,14 @@ abstract class LivingEntityMixin extends Entity {
|
|||
* Handle ALLOW and CUSTOM {@link EntityElytraEvents} when an entity is fall flying.
|
||||
*/
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;getEquippedStack(Lnet/minecraft/entity/EquipmentSlot;)Lnet/minecraft/item/ItemStack;"), method = "tickFallFlying()V", allow = 1, cancellable = true)
|
||||
@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;getEquippedStack(Lnet/minecraft/entity/EquipmentSlot;)Lnet/minecraft/item/ItemStack;"), method = "tickGliding()V", allow = 1, cancellable = true)
|
||||
void injectElytraTick(CallbackInfo info) {
|
||||
LivingEntity self = (LivingEntity) (Object) this;
|
||||
|
||||
if (!EntityElytraEvents.ALLOW.invoker().allowElytraFlight(self)) {
|
||||
// The entity is already fall flying by now, we just need to stop it.
|
||||
if (!getWorld().isClient) {
|
||||
setFlag(Entity.FALL_FLYING_FLAG_INDEX, false);
|
||||
setFlag(Entity.GLIDING_FLAG_INDEX, false);
|
||||
}
|
||||
|
||||
info.cancel();
|
||||
|
@ -58,4 +60,19 @@ abstract class LivingEntityMixin extends Entity {
|
|||
info.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Inject(at = @At(value = "FIELD", target = "Lnet/minecraft/entity/EquipmentSlot;VALUES:Ljava/util/List;"), method = "canGlide", allow = 1, cancellable = true)
|
||||
void injectElytraCheck(CallbackInfoReturnable<Boolean> cir) {
|
||||
PlayerEntity self = (PlayerEntity) (Object) this;
|
||||
|
||||
if (!EntityElytraEvents.ALLOW.invoker().allowElytraFlight(self)) {
|
||||
cir.setReturnValue(false);
|
||||
return; // Return to prevent the rest of this injector from running.
|
||||
}
|
||||
|
||||
if (EntityElytraEvents.CUSTOM.invoker().useCustomElytra(self, false)) {
|
||||
cir.setReturnValue(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
* 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.entity.event.elytra;
|
||||
|
||||
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.CallbackInfoReturnable;
|
||||
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import net.fabricmc.fabric.api.entity.event.v1.EntityElytraEvents;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Mixin(PlayerEntity.class)
|
||||
abstract class PlayerEntityMixin extends LivingEntity {
|
||||
PlayerEntityMixin(EntityType<? extends LivingEntity> entityType, World world) {
|
||||
super(entityType, world);
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@Shadow
|
||||
public abstract void startFallFlying();
|
||||
|
||||
/**
|
||||
* Allow the server-side and client-side elytra checks to fail when {@link EntityElytraEvents#ALLOW} blocks flight,
|
||||
* and otherwise to succeed for elytra flight through {@link EntityElytraEvents#CUSTOM}.
|
||||
*/
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Inject(at = @At(value = "FIELD", target = "Lnet/minecraft/entity/EquipmentSlot;CHEST:Lnet/minecraft/entity/EquipmentSlot;"), method = "checkFallFlying()Z", allow = 1, cancellable = true)
|
||||
void injectElytraCheck(CallbackInfoReturnable<Boolean> cir) {
|
||||
PlayerEntity self = (PlayerEntity) (Object) this;
|
||||
|
||||
if (!EntityElytraEvents.ALLOW.invoker().allowElytraFlight(self)) {
|
||||
cir.setReturnValue(false);
|
||||
return; // Return to prevent the rest of this injector from running.
|
||||
}
|
||||
|
||||
if (EntityElytraEvents.CUSTOM.invoker().useCustomElytra(self, false)) {
|
||||
startFallFlying();
|
||||
cir.setReturnValue(true);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,16 +6,10 @@
|
|||
"EntityMixin",
|
||||
"LivingEntityMixin",
|
||||
"MobEntityMixin",
|
||||
"MooshroomEntityMixin",
|
||||
"PigEntityMixin",
|
||||
"PlayerEntityMixin",
|
||||
"PlayerManagerMixin",
|
||||
"ServerPlayerEntityMixin",
|
||||
"TadpoleEntityMixin",
|
||||
"VillagerEntityMixin",
|
||||
"elytra.ElytraFlightControllerMixin",
|
||||
"elytra.LivingEntityMixin",
|
||||
"elytra.PlayerEntityMixin"
|
||||
"elytra.LivingEntityMixin"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1,
|
||||
|
|
|
@ -16,15 +16,11 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3"
|
||||
"fabricloader": ">=0.16.4"
|
||||
},
|
||||
"description": "Events to hook into entities.",
|
||||
"mixins": [
|
||||
"fabric-entity-events-v1.mixins.json",
|
||||
{
|
||||
"config": "fabric-entity-events-v1.client.mixins.json",
|
||||
"environment": "client"
|
||||
}
|
||||
"fabric-entity-events-v1.mixins.json"
|
||||
],
|
||||
"custom": {
|
||||
"fabric-api:module-lifecycle": "stable"
|
||||
|
|
|
@ -23,6 +23,7 @@ import net.minecraft.block.AbstractBlock;
|
|||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.component.DataComponentTypes;
|
||||
import net.minecraft.entity.EquipmentSlot;
|
||||
import net.minecraft.entity.damage.DamageTypes;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
|
@ -30,15 +31,18 @@ import net.minecraft.item.BlockItem;
|
|||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.item.equipment.EquipmentModels;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
import net.minecraft.registry.RegistryKeys;
|
||||
import net.minecraft.server.command.CommandManager;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.Unit;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
|
@ -58,13 +62,14 @@ public final class EntityEventTests implements ModInitializer {
|
|||
Identifier.of("fabric-entity-events-v1-testmod", "test_bed")
|
||||
);
|
||||
public static final Block TEST_BED = new TestBedBlock(AbstractBlock.Settings.create().strength(1, 1).registryKey(TEST_BED_KEY));
|
||||
public static final Item DIAMOND_ELYTRA = new DiamondElytraItem();
|
||||
public static final RegistryKey<Item> DIAMOND_ELYTRA_KEY = RegistryKey.of(RegistryKeys.ITEM, Identifier.of("fabric-entity-events-v1-testmod", "diamond_elytra"));
|
||||
public static final Item DIAMOND_ELYTRA = new Item(new Item.Settings().component(DataComponentTypes.GLIDER, Unit.INSTANCE).equippable(EquipmentSlot.CHEST, SoundEvents.ITEM_ARMOR_EQUIP_ELYTRA, EquipmentModels.ELYTRA).registryKey(DIAMOND_ELYTRA_KEY));
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
Registry.register(Registries.BLOCK, TEST_BED_KEY, TEST_BED);
|
||||
Registry.register(Registries.ITEM, TEST_BED_KEY.getValue(), new BlockItem(TEST_BED, new Item.Settings()));
|
||||
Registry.register(Registries.ITEM, Identifier.of("fabric-entity-events-v1-testmod", "diamond_elytra"), DIAMOND_ELYTRA);
|
||||
Registry.register(Registries.ITEM, TEST_BED_KEY.getValue(), new BlockItem(TEST_BED, new Item.Settings().registryKey(RegistryKey.of(RegistryKeys.ITEM, TEST_BED_KEY.getValue()))));
|
||||
Registry.register(Registries.ITEM, DIAMOND_ELYTRA_KEY, DIAMOND_ELYTRA);
|
||||
|
||||
ServerEntityCombatEvents.AFTER_KILLED_OTHER_ENTITY.register((world, entity, killed) -> {
|
||||
LOGGER.info("Entity {} Killed: {}", entity, killed);
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3",
|
||||
"fabricloader": ">=0.16.4",
|
||||
"fabric-api-base": "*",
|
||||
"fabric-networking-api-v1": "*",
|
||||
"minecraft": ">=1.15-alpha.19.37.a"
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3"
|
||||
"fabricloader": ">=0.16.4"
|
||||
},
|
||||
"description": "Allows registration of custom game rules.",
|
||||
"mixins": [
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
]
|
||||
},
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3",
|
||||
"fabricloader": ">=0.16.4",
|
||||
"fabric-resource-loader-v0": "*"
|
||||
},
|
||||
"description": "Allows registration of custom game tests.",
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
}
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3",
|
||||
"fabricloader": ">=0.16.4",
|
||||
"fabric-api-base": "*"
|
||||
},
|
||||
"description": "Hooks for items",
|
||||
|
|
|
@ -16,45 +16,47 @@
|
|||
|
||||
package net.fabricmc.fabric.test.item;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.minecraft.item.ArmorItem;
|
||||
import net.minecraft.item.ArmorMaterial;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.item.equipment.ArmorMaterial;
|
||||
import net.minecraft.item.equipment.EquipmentType;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.registry.entry.RegistryEntry;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
import net.minecraft.registry.RegistryKeys;
|
||||
import net.minecraft.registry.tag.ItemTags;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.Util;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
|
||||
public class ArmorKnockbackResistanceTest implements ModInitializer {
|
||||
private static final RegistryEntry<ArmorMaterial> WOOD_ARMOR = Registry.registerReference(Registries.ARMOR_MATERIAL, Identifier.of("fabric-item-api-v1-testmod", "wood"), createTestArmorMaterial());
|
||||
private static final ArmorMaterial WOOD_ARMOR = createTestArmorMaterial();
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
Registry.register(Registries.ITEM, Identifier.of("fabric-item-api-v1-testmod",
|
||||
"wooden_boots"), new ArmorItem(WOOD_ARMOR, ArmorItem.Type.BOOTS, new Item.Settings()));
|
||||
RegistryKey<Item> registryKey = RegistryKey.of(RegistryKeys.ITEM, Identifier.of("fabric-item-api-v1-testmod", "wooden_boots"));
|
||||
Registry.register(Registries.ITEM, registryKey, new ArmorItem(WOOD_ARMOR, EquipmentType.BOOTS, new Item.Settings().registryKey(registryKey)));
|
||||
}
|
||||
|
||||
private static ArmorMaterial createTestArmorMaterial() {
|
||||
return new ArmorMaterial(
|
||||
Util.make(new EnumMap<>(ArmorItem.Type.class), (map) -> {
|
||||
map.put(ArmorItem.Type.BOOTS, 1);
|
||||
map.put(ArmorItem.Type.LEGGINGS, 2);
|
||||
map.put(ArmorItem.Type.CHESTPLATE, 3);
|
||||
map.put(ArmorItem.Type.HELMET, 1);
|
||||
map.put(ArmorItem.Type.BODY, 3);
|
||||
}),
|
||||
SoundEvents.ITEM_ARMOR_EQUIP_LEATHER,
|
||||
(stack) -> stack.getItem() == Items.LEATHER,
|
||||
List.of(new ArmorMaterial.Layer(Identifier.of("fabric-item-api-v1-testmod", "wood"))),
|
||||
0,
|
||||
0.5F
|
||||
Map.of(
|
||||
EquipmentType.BOOTS, 1,
|
||||
EquipmentType.LEGGINGS, 2,
|
||||
EquipmentType.CHESTPLATE, 3,
|
||||
EquipmentType.HELMET, 1,
|
||||
EquipmentType.BODY, 3
|
||||
),
|
||||
1,
|
||||
SoundEvents.ITEM_ARMOR_EQUIP_LEATHER,
|
||||
0,
|
||||
0.5F,
|
||||
ItemTags.REPAIRS_LEATHER_ARMOR,
|
||||
Identifier.of("fabric-item-api-v1-testmod", "wood")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@ import net.minecraft.network.codec.PacketCodecs;
|
|||
import net.minecraft.potion.Potions;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
import net.minecraft.registry.RegistryKeys;
|
||||
import net.minecraft.registry.entry.RegistryEntry;
|
||||
import net.minecraft.registry.tag.EnchantmentTags;
|
||||
import net.minecraft.text.Text;
|
||||
|
@ -55,11 +57,12 @@ public class CustomDamageTest implements ModInitializer {
|
|||
}
|
||||
};
|
||||
// Do this static init *after* the damage handler otherwise it's still null while inside the constructor
|
||||
public static final Item WEIRD_PICK = new WeirdPick();
|
||||
public static final RegistryKey<Item> WEIRD_PICK_KEY = RegistryKey.of(RegistryKeys.ITEM, Identifier.of("fabric-item-api-v1-testmod", "weird_pickaxe"));
|
||||
public static final Item WEIRD_PICK = new WeirdPick(WEIRD_PICK_KEY);
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
Registry.register(Registries.ITEM, Identifier.of("fabric-item-api-v1-testmod", "weird_pickaxe"), WEIRD_PICK);
|
||||
Registry.register(Registries.ITEM, WEIRD_PICK_KEY, WEIRD_PICK);
|
||||
FabricBrewingRecipeRegistryBuilder.BUILD.register(builder -> builder.registerPotionRecipe(Potions.WATER, WEIRD_PICK, Potions.AWKWARD));
|
||||
EnchantmentEvents.ALLOW_ENCHANTING.register(((enchantment, target, enchantingContext) -> {
|
||||
if (target.isOf(Items.DIAMOND_PICKAXE) && enchantment.matchesKey(Enchantments.SHARPNESS) && EnchantmentHelper.hasAnyEnchantmentsIn(target, EnchantmentTags.MINING_EXCLUSIVE_SET)) {
|
||||
|
@ -71,8 +74,8 @@ public class CustomDamageTest implements ModInitializer {
|
|||
}
|
||||
|
||||
public static class WeirdPick extends PickaxeItem {
|
||||
protected WeirdPick() {
|
||||
super(ToolMaterial.GOLD, 3f, 5f, new Item.Settings().customDamage(WEIRD_DAMAGE_HANDLER));
|
||||
protected WeirdPick(RegistryKey<Item> registryKey) {
|
||||
super(ToolMaterial.GOLD, 3f, 5f, new Item.Settings().customDamage(WEIRD_DAMAGE_HANDLER).registryKey(registryKey));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -17,9 +17,12 @@
|
|||
package net.fabricmc.fabric.test.item;
|
||||
|
||||
import net.minecraft.component.ComponentType;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.network.codec.PacketCodecs;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
import net.minecraft.registry.RegistryKeys;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.dynamic.Codecs;
|
||||
|
||||
|
@ -31,7 +34,10 @@ public class ItemUpdateAnimationTest implements ModInitializer {
|
|||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
Registry.register(Registries.ITEM, Identifier.of("fabric-item-api-v1-testmod", "updating_allowed"), new UpdatingItem(true));
|
||||
Registry.register(Registries.ITEM, Identifier.of("fabric-item-api-v1-testmod", "updating_disallowed"), new UpdatingItem(false));
|
||||
RegistryKey<Item> updatingAllowedKey = RegistryKey.of(RegistryKeys.ITEM, Identifier.of("fabric-item-api-v1-testmod", "updating_allowed"));
|
||||
RegistryKey<Item> updatingDisallowedKey = RegistryKey.of(RegistryKeys.ITEM, Identifier.of("fabric-item-api-v1-testmod", "updating_disallowed"));
|
||||
|
||||
Registry.register(Registries.ITEM, updatingAllowedKey, new UpdatingItem(true, new Item.Settings().registryKey(updatingAllowedKey)));
|
||||
Registry.register(Registries.ITEM, updatingDisallowedKey, new UpdatingItem(false, new Item.Settings().registryKey(updatingDisallowedKey)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,8 +37,8 @@ public class UpdatingItem extends Item {
|
|||
|
||||
private final boolean allowUpdateAnimation;
|
||||
|
||||
public UpdatingItem(boolean allowUpdateAnimation) {
|
||||
super(new Settings()
|
||||
public UpdatingItem(boolean allowUpdateAnimation, Item.Settings settings) {
|
||||
super(settings
|
||||
.component(DataComponentTypes.ATTRIBUTE_MODIFIERS, AttributeModifiersComponent.builder()
|
||||
.add(EntityAttributes.ATTACK_DAMAGE, PLUS_FIVE, AttributeModifierSlot.MAINHAND)
|
||||
.build()
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3",
|
||||
"fabricloader": ">=0.16.4",
|
||||
"fabric-api-base": "*",
|
||||
"fabric-resource-loader-v0": "*"
|
||||
},
|
||||
|
|
|
@ -37,13 +37,14 @@ import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents;
|
|||
|
||||
public class ItemGroupTest implements ModInitializer {
|
||||
private static final String MOD_ID = "fabric-item-group-api-v1-testmod";
|
||||
private static Item TEST_ITEM;
|
||||
private static final RegistryKey<Item> ITEM_KEY = RegistryKey.of(RegistryKeys.ITEM, Identifier.of(MOD_ID, "item_test_group"));
|
||||
private static final Item TEST_ITEM = new Item(new Item.Settings().registryKey(ITEM_KEY));
|
||||
|
||||
private static final RegistryKey<ItemGroup> ITEM_GROUP = RegistryKey.of(RegistryKeys.ITEM_GROUP, Identifier.of(MOD_ID, "test_group"));
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
TEST_ITEM = Registry.register(Registries.ITEM, Identifier.of("fabric-item-groups-v0-testmod", "item_test_group"), new Item(new Item.Settings()));
|
||||
Registry.register(Registries.ITEM, Identifier.of("fabric-item-groups-v0-testmod", "item_test_group"), TEST_ITEM);
|
||||
|
||||
Registry.register(Registries.ITEM_GROUP, ITEM_GROUP, FabricItemGroup.builder()
|
||||
.displayName(Text.literal("Test Item Group"))
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3"
|
||||
"fabricloader": ">=0.16.4"
|
||||
},
|
||||
"description": "Key Binding registry API.",
|
||||
"mixins": [
|
||||
|
|
|
@ -55,7 +55,7 @@ public abstract class ClientChunkManagerMixin {
|
|||
}
|
||||
}
|
||||
|
||||
@Inject(method = "unload", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientChunkManager$ClientChunkMap;method_62893(ILnet/minecraft/world/chunk/WorldChunk;)V"), locals = LocalCapture.CAPTURE_FAILHARD)
|
||||
@Inject(method = "unload", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientChunkManager$ClientChunkMap;unloadChunk(ILnet/minecraft/world/chunk/WorldChunk;)V"), locals = LocalCapture.CAPTURE_FAILHARD)
|
||||
private void onChunkUnload(ChunkPos pos, CallbackInfo ci, int i, WorldChunk chunk) {
|
||||
ClientChunkEvents.CHUNK_UNLOAD.invoker().onChunkUnload(this.world, chunk);
|
||||
}
|
||||
|
|
|
@ -18,12 +18,12 @@ package net.fabricmc.fabric.mixin.event.lifecycle;
|
|||
|
||||
import java.util.Map;
|
||||
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
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 org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
import net.minecraft.entity.EquipmentSlot;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
|
@ -33,8 +33,8 @@ import net.fabricmc.fabric.api.event.lifecycle.v1.ServerEntityEvents;
|
|||
|
||||
@Mixin(LivingEntity.class)
|
||||
public abstract class LivingEntityMixin {
|
||||
@Inject(method = "getEquipmentChanges", at = @At(value = "INVOKE", target = "Ljava/util/Map;put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"), locals = LocalCapture.CAPTURE_FAILHARD)
|
||||
private void getEquipmentChanges(CallbackInfoReturnable<@Nullable Map<EquipmentSlot, ItemStack>> cir, Map<EquipmentSlot, ItemStack> changes, EquipmentSlot[] slots, int slotsSize, int slotIndex, EquipmentSlot equipmentSlot, ItemStack previousStack, ItemStack currentStack) {
|
||||
@Inject(method = "getEquipmentChanges", at = @At(value = "INVOKE", target = "Ljava/util/Map;put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"))
|
||||
private void getEquipmentChanges(CallbackInfoReturnable<@Nullable Map<EquipmentSlot, ItemStack>> cir, @Local EquipmentSlot equipmentSlot, @Local(ordinal = 0) ItemStack previousStack, @Local(ordinal = 1) ItemStack currentStack) {
|
||||
ServerEntityEvents.EQUIPMENT_CHANGE.invoker().onChange((LivingEntity) (Object) this, equipmentSlot, previousStack, currentStack);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package net.fabricmc.fabric.mixin.event.lifecycle;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
@ -27,6 +29,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||
import net.minecraft.server.world.ChunkHolder;
|
||||
import net.minecraft.server.world.ServerChunkLoadingManager;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraft.world.chunk.WorldChunk;
|
||||
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerChunkEvents;
|
||||
|
@ -35,17 +38,16 @@ import net.fabricmc.fabric.api.event.lifecycle.v1.ServerChunkEvents;
|
|||
public abstract class ServerChunkLoadingManagerMixin {
|
||||
@Shadow
|
||||
@Final
|
||||
private ServerWorld world;
|
||||
|
||||
// Chunk (Un)Load events, An explanation:
|
||||
// Must of this code is wrapped inside of futures and consumers, so it's generally a mess.
|
||||
ServerWorld world;
|
||||
|
||||
/**
|
||||
* Injection is inside of tryUnloadChunk.
|
||||
* We inject just after "setLoadedToWorld" is made false, since here the WorldChunk is guaranteed to be unloaded.
|
||||
*/
|
||||
@Inject(method = "method_60440", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/chunk/WorldChunk;setLoadedToWorld(Z)V", shift = At.Shift.AFTER))
|
||||
private void onChunkUnload(ChunkHolder chunkHolder, long l, CallbackInfo ci, @Local WorldChunk chunk) {
|
||||
ServerChunkEvents.CHUNK_UNLOAD.invoker().onChunkUnload(this.world, chunk);
|
||||
@Inject(method = "method_60440", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/world/ServerChunkLoadingManager;save(Lnet/minecraft/world/chunk/Chunk;)Z"))
|
||||
private void onChunkUnload(ChunkHolder chunkHolder, CompletableFuture<?> completableFuture, long l, CallbackInfo ci, @Local Chunk chunk) {
|
||||
if (chunk instanceof WorldChunk worldChunk) {
|
||||
ServerChunkEvents.CHUNK_UNLOAD.invoker().onChunkUnload(this.world, worldChunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
}
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3",
|
||||
"fabricloader": ">=0.16.4",
|
||||
"fabric-api-base": "*"
|
||||
},
|
||||
"description": "Events for the game's lifecycle.",
|
||||
|
|
|
@ -18,9 +18,10 @@ package net.fabricmc.fabric.mixin.loot;
|
|||
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.DynamicOps;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
|
@ -37,7 +38,7 @@ import net.fabricmc.fabric.impl.loot.LootUtil;
|
|||
@Mixin(JsonDataLoader.class)
|
||||
public class JsonDataLoaderMixin {
|
||||
@Inject(method = "load", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/resource/ResourceFinder;toResourceId(Lnet/minecraft/util/Identifier;)Lnet/minecraft/util/Identifier;", shift = At.Shift.AFTER))
|
||||
private static void fillSourceMap(ResourceManager manager, String dataType, Gson gson, Map<Identifier, JsonElement> results, CallbackInfo ci, @Local Map.Entry<Identifier, Resource> entry, @Local(ordinal = 1) Identifier id) {
|
||||
private static <T> void fillSourceMap(ResourceManager manager, String dataType, DynamicOps<JsonElement> dynamicOps, Codec<T> codec, Map<Identifier, T> results, CallbackInfo ci, @Local Map.Entry<Identifier, Resource> entry, @Local(ordinal = 1) Identifier id) {
|
||||
if (!LootDataType.LOOT_TABLES.registryKey().getValue().getPath().equals(dataType)) return;
|
||||
|
||||
LootUtil.SOURCES.get().put(id, LootUtil.determineSource(entry.getValue()));
|
||||
|
|
|
@ -17,11 +17,10 @@
|
|||
package net.fabricmc.fabric.mixin.loot;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
|
@ -80,9 +79,9 @@ abstract class ReloadableRegistriesMixin {
|
|||
}), fn, executor);
|
||||
}
|
||||
|
||||
@WrapOperation(method = "method_61239", at = @At(value = "INVOKE", target = "Ljava/util/Optional;ifPresent(Ljava/util/function/Consumer;)V"))
|
||||
private static <T> void modifyLootTable(Optional<T> optionalTable, Consumer<? super T> action, Operation<Void> original, @Local(argsOnly = true) Identifier id, @Local(argsOnly = true) RegistryOps<JsonElement> ops) {
|
||||
original.call(optionalTable.map(table -> modifyLootTable(table, id, ops)), action);
|
||||
@Inject(method = "method_61240", at = @At(value = "INVOKE", target = "Ljava/util/Map;forEach(Ljava/util/function/BiConsumer;)V"))
|
||||
private static <T> void modifyLootTable(LootDataType<T> lootDataType, ResourceManager resourceManager, RegistryOps<JsonElement> registryOps, CallbackInfoReturnable<MutableRegistry<?>> cir, @Local Map<Identifier, T> map) {
|
||||
map.replaceAll((identifier, t) -> modifyLootTable(t, identifier, registryOps));
|
||||
}
|
||||
|
||||
@Unique
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3",
|
||||
"fabricloader": ">=0.16.4",
|
||||
"fabric-api-base": "*",
|
||||
"fabric-resource-loader-v0": "*"
|
||||
},
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3",
|
||||
"fabricloader": ">=0.16.4",
|
||||
"fabric-api-base": "*"
|
||||
},
|
||||
"description": "Adds message-related hooks.",
|
||||
|
|
|
@ -46,7 +46,7 @@ public final class DelegatingUnbakedModel implements UnbakedModel {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void resolve(Resolver resolver, ModelType modelType) {
|
||||
public void resolve(Resolver resolver) {
|
||||
resolver.resolve(delegate);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3",
|
||||
"fabricloader": ">=0.16.4",
|
||||
"fabric-api-base": "*"
|
||||
},
|
||||
"description": "Provides hooks for model loading.",
|
||||
|
|
|
@ -98,7 +98,7 @@ public class ModelTestModClient implements ClientModInitializer {
|
|||
Identifier id = context.resourceId();
|
||||
|
||||
if (id != null && id.equals(BROWN_GLAZED_TERRACOTTA_MODEL_ID)) {
|
||||
return context.baker().getModel(MissingModel.ID);
|
||||
return MissingModel.create();
|
||||
}
|
||||
|
||||
return model;
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
},
|
||||
"accessWidener": "fabric-networking-api-v1.accesswidener",
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3",
|
||||
"fabricloader": ">=0.16.4",
|
||||
"fabric-api-base": "*"
|
||||
},
|
||||
"description": "Low-level, vanilla protocol oriented networking hooks.",
|
||||
|
|
|
@ -32,8 +32,6 @@ import net.minecraft.util.math.BlockPos;
|
|||
/**
|
||||
* Fabric's version of BlockEntityType.Builder with additional convenience methods.
|
||||
*
|
||||
* <p>Alternatively, use the access widener for {@link BlockEntityType.BlockEntityFactory}
|
||||
* in Fabric Transitive Access Wideners (v1).
|
||||
*/
|
||||
public final class FabricBlockEntityTypeBuilder<T extends BlockEntity> {
|
||||
private final Factory<? extends T> factory;
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3",
|
||||
"fabricloader": ">=0.16.4",
|
||||
"fabric-api-base": "*"
|
||||
},
|
||||
"description": "Builders for objects vanilla has locked down.",
|
||||
|
|
|
@ -30,6 +30,7 @@ import net.minecraft.item.Item;
|
|||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
import net.minecraft.registry.RegistryKeys;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
@ -73,7 +74,7 @@ public class BlockEntityTypeBuilderTest implements ModInitializer {
|
|||
private static void register(RegistryKey<Block> id, Block block) {
|
||||
Registry.register(Registries.BLOCK, id, block);
|
||||
|
||||
Item item = new BlockItem(block, new Item.Settings());
|
||||
Item item = new BlockItem(block, new Item.Settings().registryKey(RegistryKey.of(RegistryKeys.ITEM, id.getValue())));
|
||||
Registry.register(Registries.ITEM, id.getValue(), item);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ import net.minecraft.item.SignItem;
|
|||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
import net.minecraft.registry.RegistryKeys;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
|
@ -50,8 +51,8 @@ public class TealSignTest implements ModInitializer {
|
|||
public static final HangingSignBlock TEAL_HANGING_SIGN = new HangingSignBlock(TEAL_WOOD_TYPE, AbstractBlock.Settings.copy(Blocks.OAK_HANGING_SIGN).registryKey(TEAL_HANGING_SIGN_KEY));
|
||||
public static final RegistryKey<Block> TEAL_WALL_HANGING_SIGN_KEY = ObjectBuilderTestConstants.block("teal_wall_hanging_sign");
|
||||
public static final WallHangingSignBlock TEAL_WALL_HANGING_SIGN = new WallHangingSignBlock(TEAL_WOOD_TYPE, AbstractBlock.Settings.copy(Blocks.OAK_HANGING_SIGN).registryKey(TEAL_WALL_HANGING_SIGN_KEY));
|
||||
public static final SignItem TEAL_SIGN_ITEM = new SignItem(new Item.Settings(), TEAL_SIGN, TEAL_WALL_SIGN);
|
||||
public static final HangingSignItem TEAL_HANGING_SIGN_ITEM = new HangingSignItem(TEAL_HANGING_SIGN, TEAL_WALL_HANGING_SIGN, new Item.Settings());
|
||||
public static final SignItem TEAL_SIGN_ITEM = new SignItem(TEAL_SIGN, TEAL_WALL_SIGN, new Item.Settings().registryKey(RegistryKey.of(RegistryKeys.ITEM, TEAL_SIGN_KEY.getValue())));
|
||||
public static final HangingSignItem TEAL_HANGING_SIGN_ITEM = new HangingSignItem(TEAL_HANGING_SIGN, TEAL_WALL_HANGING_SIGN, new Item.Settings().registryKey(RegistryKey.of(RegistryKeys.ITEM, TEAL_HANGING_SIGN_KEY.getValue())));
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3"
|
||||
"fabricloader": ">=0.16.4"
|
||||
},
|
||||
"description": "Hooks for registering custom particles.",
|
||||
"mixins": [
|
||||
|
|
|
@ -68,6 +68,6 @@ public final class ParticleTestSetup implements ModInitializer {
|
|||
|
||||
private static void registerBlock(RegistryKey<Block> key, Block block) {
|
||||
Registry.register(Registries.BLOCK, key, block);
|
||||
Registry.register(Registries.ITEM, key.getValue(), new BlockItem(block, new Item.Settings()));
|
||||
Registry.register(Registries.ITEM, key.getValue(), new BlockItem(block, new Item.Settings().registryKey(RegistryKey.of(RegistryKeys.ITEM, key.getValue()))));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
],
|
||||
"accessWidener": "fabric-recipe-api-v1.accesswidener",
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3",
|
||||
"fabricloader": ">=0.16.4",
|
||||
"fabric-networking-api-v1": "*"
|
||||
},
|
||||
"entrypoints": {
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
* 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.registry.sync.client;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
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 net.minecraft.client.render.item.ItemModels;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
import net.minecraft.client.render.model.BakedModelManager;
|
||||
import net.minecraft.client.util.ModelIdentifier;
|
||||
import net.minecraft.registry.Registries;
|
||||
|
||||
import net.fabricmc.fabric.impl.registry.sync.trackers.Int2ObjectMapTracker;
|
||||
|
||||
@Mixin(ItemModels.class)
|
||||
public class ItemModelsMixin {
|
||||
@Final
|
||||
@Shadow
|
||||
public Int2ObjectMap<ModelIdentifier> modelIds;
|
||||
@Final
|
||||
@Shadow
|
||||
private Int2ObjectMap<BakedModel> models;
|
||||
|
||||
@Inject(method = "<init>", at = @At("RETURN"))
|
||||
public void onInit(BakedModelManager bakedModelManager, CallbackInfo info) {
|
||||
Int2ObjectMapTracker.register(Registries.ITEM, "ItemModels.modelIds", modelIds);
|
||||
Int2ObjectMapTracker.register(Registries.ITEM, "ItemModels.models", models);
|
||||
}
|
||||
}
|
|
@ -7,7 +7,6 @@
|
|||
"ClientRegistriesMixin",
|
||||
"ClientRegistriesDynamicRegistriesAccessor",
|
||||
"ItemColorsMixin",
|
||||
"ItemModelsMixin",
|
||||
"MinecraftClientMixin",
|
||||
"ParticleManagerMixin"
|
||||
],
|
||||
|
|
|
@ -204,10 +204,6 @@ public class FabricRegistryInit implements ModInitializer {
|
|||
RegistryAttributeHolder.get(Registries.MAP_DECORATION_TYPE)
|
||||
.addAttribute(RegistryAttribute.SYNCED);
|
||||
|
||||
// Synced via PacketCodecs.registry
|
||||
RegistryAttributeHolder.get(Registries.ARMOR_MATERIAL)
|
||||
.addAttribute(RegistryAttribute.SYNCED);
|
||||
|
||||
// Synced via PacketCodecs.registry
|
||||
RegistryAttributeHolder.get(Registries.CONSUME_EFFECT_TYPE)
|
||||
.addAttribute(RegistryAttribute.SYNCED);
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3",
|
||||
"fabricloader": ">=0.16.4",
|
||||
"fabric-api-base": "*",
|
||||
"fabric-networking-api-v1": "*"
|
||||
},
|
||||
|
|
|
@ -159,7 +159,7 @@ public class RegistrySyncTest implements ModInitializer {
|
|||
Registry.register(Registries.BLOCK, id, block);
|
||||
|
||||
if (REGISTER_ITEMS) {
|
||||
BlockItem blockItem = new BlockItem(block, new Item.Settings());
|
||||
BlockItem blockItem = new BlockItem(block, new Item.Settings().registryKey(RegistryKey.of(RegistryKeys.ITEM, id)));
|
||||
Registry.register(Registries.ITEM, id, blockItem);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,10 +19,8 @@ package net.fabricmc.fabric.mixin.renderer.client;
|
|||
import java.util.BitSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
@ -32,7 +30,6 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
|||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
import net.minecraft.client.render.model.MultipartBakedModel;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
@ -46,7 +43,7 @@ import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
|
|||
public class MultipartBakedModelMixin implements FabricBakedModel {
|
||||
@Shadow
|
||||
@Final
|
||||
private List<Pair<Predicate<BlockState>, BakedModel>> components;
|
||||
private List<MultipartBakedModel.class_10204> components;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
|
@ -61,9 +58,9 @@ public class MultipartBakedModelMixin implements FabricBakedModel {
|
|||
}
|
||||
|
||||
@Inject(at = @At("RETURN"), method = "<init>")
|
||||
private void onInit(List<Pair<Predicate<BlockState>, BakedModel>> components, CallbackInfo cb) {
|
||||
for (Pair<Predicate<BlockState>, BakedModel> component : components) {
|
||||
if (!component.getRight().isVanillaAdapter()) {
|
||||
private void onInit(List<MultipartBakedModel.class_10204> components, CallbackInfo cb) {
|
||||
for (MultipartBakedModel.class_10204 component : components) {
|
||||
if (!component.model().isVanillaAdapter()) {
|
||||
isVanilla = false;
|
||||
break;
|
||||
}
|
||||
|
@ -78,9 +75,9 @@ public class MultipartBakedModelMixin implements FabricBakedModel {
|
|||
bitSet = new BitSet();
|
||||
|
||||
for (int i = 0; i < this.components.size(); i++) {
|
||||
Pair<Predicate<BlockState>, BakedModel> pair = components.get(i);
|
||||
MultipartBakedModel.class_10204 component = components.get(i);
|
||||
|
||||
if (pair.getLeft().test(state)) {
|
||||
if (component.condition().test(state)) {
|
||||
bitSet.set(i);
|
||||
}
|
||||
}
|
||||
|
@ -98,7 +95,7 @@ public class MultipartBakedModelMixin implements FabricBakedModel {
|
|||
|
||||
for (int i = 0; i < this.components.size(); i++) {
|
||||
if (bitSet.get(i)) {
|
||||
components.get(i).getRight().emitBlockQuads(blockView, state, pos, subModelRandomSupplier, context);
|
||||
components.get(i).model().emitBlockQuads(blockView, state, pos, subModelRandomSupplier, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
package net.fabricmc.fabric.mixin.renderer.client;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
|
@ -31,8 +30,8 @@ import net.minecraft.block.BlockState;
|
|||
import net.minecraft.client.render.model.BakedModel;
|
||||
import net.minecraft.client.render.model.WeightedBakedModel;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.collection.DataPool;
|
||||
import net.minecraft.util.collection.Weighted;
|
||||
import net.minecraft.util.collection.Weighting;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.random.Random;
|
||||
import net.minecraft.world.BlockRenderView;
|
||||
|
@ -44,17 +43,14 @@ import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
|
|||
public class WeightedBakedModelMixin implements FabricBakedModel {
|
||||
@Shadow
|
||||
@Final
|
||||
private int totalWeight;
|
||||
@Shadow
|
||||
@Final
|
||||
private List<Weighted.Present<BakedModel>> models;
|
||||
private DataPool<BakedModel> models;
|
||||
@Unique
|
||||
boolean isVanilla = true;
|
||||
|
||||
@Inject(at = @At("RETURN"), method = "<init>")
|
||||
private void onInit(List<Weighted.Present<BakedModel>> models, CallbackInfo cb) {
|
||||
for (int i = 0; i < models.size(); i++) {
|
||||
if (!models.get(i).data().isVanillaAdapter()) {
|
||||
private void onInit(DataPool<BakedModel> dataPool, CallbackInfo cb) {
|
||||
for (Weighted.Present<BakedModel> model : models.getEntries()) {
|
||||
if (!model.data().isVanillaAdapter()) {
|
||||
isVanilla = false;
|
||||
break;
|
||||
}
|
||||
|
@ -68,12 +64,12 @@ public class WeightedBakedModelMixin implements FabricBakedModel {
|
|||
|
||||
@Override
|
||||
public void emitBlockQuads(BlockRenderView blockView, BlockState state, BlockPos pos, Supplier<Random> randomSupplier, RenderContext context) {
|
||||
Weighted.Present<BakedModel> selected = Weighting.getAt(this.models, Math.abs((int) randomSupplier.get().nextLong()) % this.totalWeight).orElse(null);
|
||||
BakedModel selected = this.models.getDataOrEmpty(randomSupplier.get()).orElse(null);
|
||||
|
||||
if (selected != null) {
|
||||
selected.data().emitBlockQuads(blockView, state, pos, () -> {
|
||||
selected.emitBlockQuads(blockView, state, pos, () -> {
|
||||
Random random = randomSupplier.get();
|
||||
random.nextLong(); // Imitate vanilla modifying the random before passing it to the submodel
|
||||
random.nextInt(); // Imitate vanilla modifying the random before passing it to the submodel
|
||||
return random;
|
||||
}, context);
|
||||
}
|
||||
|
@ -81,12 +77,12 @@ public class WeightedBakedModelMixin implements FabricBakedModel {
|
|||
|
||||
@Override
|
||||
public void emitItemQuads(ItemStack stack, Supplier<Random> randomSupplier, RenderContext context) {
|
||||
Weighted.Present<BakedModel> selected = Weighting.getAt(this.models, Math.abs((int) randomSupplier.get().nextLong()) % this.totalWeight).orElse(null);
|
||||
BakedModel selected = this.models.getDataOrEmpty(randomSupplier.get()).orElse(null);
|
||||
|
||||
if (selected != null) {
|
||||
selected.data().emitItemQuads(stack, () -> {
|
||||
selected.emitItemQuads(stack, () -> {
|
||||
Random random = randomSupplier.get();
|
||||
random.nextLong(); // Imitate vanilla modifying the random before passing it to the submodel
|
||||
random.nextInt(); // Imitate vanilla modifying the random before passing it to the submodel
|
||||
return random;
|
||||
}, context);
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3",
|
||||
"fabricloader": ">=0.16.4",
|
||||
"minecraft": ">=1.15-alpha.19.39.a",
|
||||
"fabric-api-base": "*"
|
||||
},
|
||||
|
|
|
@ -46,12 +46,12 @@ public final class Registration {
|
|||
FRAME_VARIANT_BLOCK,
|
||||
};
|
||||
|
||||
public static final Item FRAME_ITEM = register("frame", new BlockItem(FRAME_BLOCK, new Item.Settings()));
|
||||
public static final Item FRAME_MULTIPART_ITEM = register("frame_multipart", new BlockItem(FRAME_MULTIPART_BLOCK, new Item.Settings()));
|
||||
public static final Item FRAME_VARIANT_ITEM = register("frame_variant", new BlockItem(FRAME_VARIANT_BLOCK, new Item.Settings()));
|
||||
public static final Item PILLAR_ITEM = register("pillar", new BlockItem(PILLAR_BLOCK, new Item.Settings()));
|
||||
public static final Item OCTAGONAL_COLUMN_ITEM = register("octagonal_column", new BlockItem(OCTAGONAL_COLUMN_BLOCK, new Item.Settings()));
|
||||
public static final Item RIVERSTONE_ITEM = register("riverstone", new BlockItem(RIVERSTONE_BLOCK, new Item.Settings()));
|
||||
public static final Item FRAME_ITEM = registerItem("frame", (settings) -> new BlockItem(FRAME_BLOCK, settings));
|
||||
public static final Item FRAME_MULTIPART_ITEM = registerItem("frame_multipart", (settings) -> new BlockItem(FRAME_MULTIPART_BLOCK, settings));
|
||||
public static final Item FRAME_VARIANT_ITEM = registerItem("frame_variant", (settings) -> new BlockItem(FRAME_VARIANT_BLOCK, settings));
|
||||
public static final Item PILLAR_ITEM = registerItem("pillar", (settings) -> new BlockItem(PILLAR_BLOCK, settings));
|
||||
public static final Item OCTAGONAL_COLUMN_ITEM = registerItem("octagonal_column", (settings) -> new BlockItem(OCTAGONAL_COLUMN_BLOCK, settings));
|
||||
public static final Item RIVERSTONE_ITEM = registerItem("riverstone", (settings) -> new BlockItem(RIVERSTONE_BLOCK, settings));
|
||||
|
||||
public static final BlockEntityType<FrameBlockEntity> FRAME_BLOCK_ENTITY_TYPE = register("frame", FabricBlockEntityTypeBuilder.create(FrameBlockEntity::new, FRAME_BLOCKS).build());
|
||||
|
||||
|
@ -61,8 +61,9 @@ public final class Registration {
|
|||
return Registry.register(Registries.BLOCK, id, constructor.apply(settings.registryKey(RegistryKey.of(RegistryKeys.BLOCK, id))));
|
||||
}
|
||||
|
||||
private static <T extends Item> T register(String path, T item) {
|
||||
return Registry.register(Registries.ITEM, RendererTest.id(path), item);
|
||||
private static <T extends Item> T registerItem(String path, Function<Item.Settings, T> itemFunction) {
|
||||
RegistryKey<Item> registryKey = RegistryKey.of(RegistryKeys.ITEM, RendererTest.id(path));
|
||||
return Registry.register(Registries.ITEM, registryKey, itemFunction.apply(new Item.Settings().registryKey(registryKey)));
|
||||
}
|
||||
|
||||
private static <T extends BlockEntityType<?>> T register(String path, T blockEntityType) {
|
||||
|
|
|
@ -40,7 +40,7 @@ public class FrameUnbakedModel implements UnbakedModel {
|
|||
private static final SpriteIdentifier OBSIDIAN_SPRITE_ID = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, Identifier.ofVanilla("block/obsidian"));
|
||||
|
||||
@Override
|
||||
public void resolve(Resolver resolver, ModelType currentlyResolvingType) {
|
||||
public void resolve(Resolver resolver) {
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -55,7 +55,7 @@ public class OctagonalColumnUnbakedModel implements UnbakedModel {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void resolve(Resolver resolver, ModelType currentlyResolvingType) {
|
||||
public void resolve(Resolver resolver) {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -38,7 +38,7 @@ public class PillarUnbakedModel implements UnbakedModel {
|
|||
.toList();
|
||||
|
||||
@Override
|
||||
public void resolve(Resolver resolver, ModelType currentlyResolvingType) {
|
||||
public void resolve(Resolver resolver) {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
|
|
@ -19,7 +19,6 @@ package net.fabricmc.fabric.test.renderer.client;
|
|||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
|
@ -31,7 +30,7 @@ import net.minecraft.client.render.model.WeightedBakedModel;
|
|||
import net.minecraft.client.render.model.json.ModelOverrideList;
|
||||
import net.minecraft.client.render.model.json.ModelTransformation;
|
||||
import net.minecraft.client.texture.Sprite;
|
||||
import net.minecraft.util.collection.Weighted;
|
||||
import net.minecraft.util.collection.DataPool;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.random.Random;
|
||||
|
@ -51,16 +50,7 @@ public class RandomSupplierTest implements ClientModInitializer {
|
|||
|
||||
@Override
|
||||
public void onInitializeClient() {
|
||||
var checkingModel = new RandomCheckingBakedModel();
|
||||
var weighted = new WeightedBakedModel(List.of(
|
||||
Weighted.of(checkingModel, 1),
|
||||
Weighted.of(checkingModel, 2)));
|
||||
var multipart = new MultipartBakedModel(List.of(
|
||||
Pair.of(state -> true, weighted),
|
||||
Pair.of(state -> true, weighted)));
|
||||
var weightedAgain = new WeightedBakedModel(List.of(
|
||||
Weighted.of(multipart, 1),
|
||||
Weighted.of(multipart, 2)));
|
||||
WeightedBakedModel weightedAgain = createWeightedBakedModel();
|
||||
|
||||
long startingSeed = 42;
|
||||
Random random = Random.create();
|
||||
|
@ -78,6 +68,25 @@ public class RandomSupplierTest implements ClientModInitializer {
|
|||
weightedAgain.emitBlockQuads(null, Blocks.STONE.getDefaultState(), BlockPos.ORIGIN, randomSupplier, null);
|
||||
}
|
||||
|
||||
private static WeightedBakedModel createWeightedBakedModel() {
|
||||
var checkingModel = new RandomCheckingBakedModel();
|
||||
|
||||
DataPool.Builder<BakedModel> weightedBuilder = DataPool.builder();
|
||||
weightedBuilder.add(checkingModel, 1);
|
||||
weightedBuilder.add(checkingModel, 2);
|
||||
|
||||
var weighted = new WeightedBakedModel(weightedBuilder.build());
|
||||
var multipart = new MultipartBakedModel(List.of(
|
||||
new MultipartBakedModel.class_10204(state -> true, weighted),
|
||||
new MultipartBakedModel.class_10204(state -> true, weighted)));
|
||||
|
||||
DataPool.Builder<BakedModel> weightedAgainBuilder = DataPool.builder();
|
||||
weightedAgainBuilder.add(multipart, 1);
|
||||
weightedAgainBuilder.add(multipart, 2);
|
||||
|
||||
return new WeightedBakedModel(weightedAgainBuilder.build());
|
||||
}
|
||||
|
||||
private static class RandomCheckingBakedModel implements BakedModel {
|
||||
@Override
|
||||
public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction face, Random random) {
|
||||
|
|
|
@ -33,7 +33,7 @@ public class RiverstoneUnbakedModel implements UnbakedModel {
|
|||
private static final Identifier GOLD_BLOCK_MODEL_ID = Identifier.ofVanilla("block/gold_block");
|
||||
|
||||
@Override
|
||||
public void resolve(Resolver resolver, ModelType currentlyResolvingType) {
|
||||
public void resolve(Resolver resolver) {
|
||||
resolver.resolve(STONE_MODEL_ID);
|
||||
resolver.resolve(GOLD_BLOCK_MODEL_ID);
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ public abstract class ItemRendererMixin {
|
|||
@Unique
|
||||
private final ThreadLocal<ItemRenderContext> fabric_contexts = ThreadLocal.withInitial(() -> new ItemRenderContext(colors));
|
||||
|
||||
@Inject(method = "method_62476", at = @At(value = "HEAD"), cancellable = true)
|
||||
@Inject(method = "renderItem(Lnet/minecraft/item/ItemStack;Lnet/minecraft/client/render/model/json/ModelTransformationMode;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;IILnet/minecraft/client/render/model/BakedModel;Z)V", at = @At(value = "HEAD"), cancellable = true)
|
||||
public void hook_renderItem(ItemStack stack, ModelTransformationMode transformMode, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int light, int overlay, BakedModel model, boolean notInHand, CallbackInfo ci) {
|
||||
if (!model.isVanillaAdapter()) {
|
||||
fabric_contexts.get().renderModel(stack, transformMode, matrixStack, vertexConsumerProvider, light, overlay, model);
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3",
|
||||
"fabricloader": ">=0.16.4",
|
||||
"minecraft": ">=1.15-alpha.19.39.a",
|
||||
"fabric-api-base": "*",
|
||||
"fabric-renderer-api-v1": "*"
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3",
|
||||
"fabricloader": ">=0.16.4",
|
||||
"fabric-api-base": "*"
|
||||
},
|
||||
"description": "Hooks for registering fluid renders.",
|
||||
|
|
|
@ -16,24 +16,26 @@
|
|||
|
||||
package net.fabricmc.fabric.mixin.client.rendering;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
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.CallbackInfo;
|
||||
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.render.entity.feature.CapeFeatureRenderer;
|
||||
import net.minecraft.client.render.entity.state.PlayerEntityRenderState;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import net.fabricmc.fabric.api.client.rendering.v1.LivingEntityFeatureRenderEvents;
|
||||
|
||||
@Mixin(CapeFeatureRenderer.class)
|
||||
public class CapeFeatureRendererMixin {
|
||||
@Inject(at = @At(value = "FIELD", target = "Lnet/minecraft/item/Items;ELYTRA:Lnet/minecraft/item/Item;"), method = "render", require = 1, allow = 1, cancellable = true)
|
||||
public void injectCapeRenderCheck(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, PlayerEntityRenderState state, float limbAngle, float limbDistance, CallbackInfo ci) {
|
||||
@WrapOperation(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/entity/feature/CapeFeatureRenderer;method_64075(Lnet/minecraft/item/ItemStack;)Z"), method = "render(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;ILnet/minecraft/client/render/entity/state/PlayerEntityRenderState;FF)V")
|
||||
public boolean injectCapeRenderCheck(CapeFeatureRenderer instance, ItemStack itemStack, Operation<Boolean> original, @Local(argsOnly = true) PlayerEntityRenderState state) {
|
||||
if (!LivingEntityFeatureRenderEvents.ALLOW_CAPE_RENDER.invoker().allowCapeRender(state)) {
|
||||
ci.cancel();
|
||||
return false;
|
||||
}
|
||||
|
||||
return original.call(instance, itemStack);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.3",
|
||||
"fabricloader": ">=0.16.4",
|
||||
"fabric-api-base": "*"
|
||||
},
|
||||
"description": "Hooks and registries for rendering-related things.",
|
||||
|
|
|
@ -19,15 +19,18 @@ package net.fabricmc.fabric.test.rendering;
|
|||
import net.minecraft.item.Item;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
import net.minecraft.registry.RegistryKeys;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
|
||||
public class CustomAtlasSourcesTestInit implements ModInitializer {
|
||||
public static final Item DOUBLE_IRON_INGOT = new Item(new Item.Settings());
|
||||
public static final RegistryKey<Item> DOUBLE_IRON_INGOT_KEY = RegistryKey.of(RegistryKeys.ITEM, Identifier.of("fabric-rendering-v1-testmod", "double_iron_ingot"));
|
||||
public static final Item DOUBLE_IRON_INGOT = new Item(new Item.Settings().registryKey(DOUBLE_IRON_INGOT_KEY));
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
Registry.register(Registries.ITEM, Identifier.of("fabric-rendering-v1-testmod", "double_iron_ingot"), DOUBLE_IRON_INGOT);
|
||||
Registry.register(Registries.ITEM, DOUBLE_IRON_INGOT_KEY, DOUBLE_IRON_INGOT);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ import net.fabricmc.api.ModInitializer;
|
|||
public class CustomColorResolverTestInit implements ModInitializer {
|
||||
public static final RegistryKey<Block> KEY = RegistryKey.of(RegistryKeys.BLOCK, Identifier.of("fabric-rendering-v1-testmod", "custom_color_block"));
|
||||
public static final Block CUSTOM_COLOR_BLOCK = new Block(AbstractBlock.Settings.create().registryKey(KEY));
|
||||
public static final Item CUSTOM_COLOR_BLOCK_ITEM = new BlockItem(CUSTOM_COLOR_BLOCK, new Item.Settings());
|
||||
public static final Item CUSTOM_COLOR_BLOCK_ITEM = new BlockItem(CUSTOM_COLOR_BLOCK, new Item.Settings().registryKey(RegistryKey.of(RegistryKeys.ITEM, KEY.getValue())));
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
|
|
|
@ -16,44 +16,47 @@
|
|||
|
||||
package net.fabricmc.fabric.test.rendering;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import net.minecraft.item.ArmorItem;
|
||||
import net.minecraft.item.ArmorMaterial;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.item.equipment.ArmorMaterial;
|
||||
import net.minecraft.item.equipment.EquipmentType;
|
||||
import net.minecraft.item.tooltip.TooltipData;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.registry.entry.RegistryEntry;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
import net.minecraft.registry.RegistryKeys;
|
||||
import net.minecraft.registry.tag.ItemTags;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.Util;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
|
||||
public class TooltipComponentTestInit implements ModInitializer {
|
||||
public static Item CUSTOM_TOOLTIP_ITEM = new CustomTooltipItem();
|
||||
public static RegistryEntry<ArmorMaterial> TEST_ARMOR_MATERIAL = Registry.registerReference(Registries.ARMOR_MATERIAL, Identifier.of("fabric-rendering-v1-testmod", "test_material"), createTestArmorMaterial());
|
||||
public static Item CUSTOM_ARMOR_ITEM = new ArmorItem(TEST_ARMOR_MATERIAL, ArmorItem.Type.CHESTPLATE, new Item.Settings());
|
||||
public static final RegistryKey<Item> CUSTOM_TOOLTIP_ITEM_KEY = RegistryKey.of(RegistryKeys.ITEM, Identifier.of("fabric-rendering-v1-testmod", "custom_tooltip"));
|
||||
public static final Item CUSTOM_TOOLTIP_ITEM = new CustomTooltipItem(new Item.Settings().registryKey(CUSTOM_TOOLTIP_ITEM_KEY));
|
||||
|
||||
public static final ArmorMaterial TEST_ARMOR_MATERIAL = createTestArmorMaterial();
|
||||
public static final RegistryKey<Item> CUSTOM_ARMOR_ITEM_KEY = RegistryKey.of(RegistryKeys.ITEM, Identifier.of("fabric-rendering-v1-testmod", "test_chest"));
|
||||
public static final Item CUSTOM_ARMOR_ITEM = new ArmorItem(TEST_ARMOR_MATERIAL, EquipmentType.CHESTPLATE, new Item.Settings().registryKey(CUSTOM_ARMOR_ITEM_KEY));
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
Registry.register(Registries.ITEM, Identifier.of("fabric-rendering-v1-testmod", "custom_tooltip"), CUSTOM_TOOLTIP_ITEM);
|
||||
Registry.register(Registries.ITEM, Identifier.of("fabric-rendering-v1-testmod", "test_chest"), CUSTOM_ARMOR_ITEM);
|
||||
Registry.register(Registries.ITEM, CUSTOM_TOOLTIP_ITEM_KEY, CUSTOM_TOOLTIP_ITEM);
|
||||
Registry.register(Registries.ITEM, CUSTOM_ARMOR_ITEM_KEY, CUSTOM_ARMOR_ITEM);
|
||||
}
|
||||
|
||||
private static class CustomTooltipItem extends Item {
|
||||
CustomTooltipItem() {
|
||||
super(new Settings());
|
||||
CustomTooltipItem(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<TooltipData> getTooltipData(ItemStack stack) {
|
||||
return Optional.of(new Data(stack.getTranslationKey()));
|
||||
return Optional.of(new Data(stack.getItem().getTranslationKey()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,18 +65,20 @@ public class TooltipComponentTestInit implements ModInitializer {
|
|||
|
||||
private static ArmorMaterial createTestArmorMaterial() {
|
||||
return new ArmorMaterial(
|
||||
Util.make(new EnumMap<>(ArmorItem.Type.class), (map) -> {
|
||||
map.put(ArmorItem.Type.BOOTS, 1);
|
||||
map.put(ArmorItem.Type.LEGGINGS, 2);
|
||||
map.put(ArmorItem.Type.CHESTPLATE, 3);
|
||||
map.put(ArmorItem.Type.HELMET, 1);
|
||||
map.put(ArmorItem.Type.BODY, 3);
|
||||
}),
|
||||
SoundEvents.ITEM_ARMOR_EQUIP_LEATHER,
|
||||
(stack) -> stack.getItem() == Items.LEATHER,
|
||||
List.of(new ArmorMaterial.Layer(Identifier.of("fabric-rendering-v1-testmod", "test_material"))),
|
||||
0,
|
||||
0
|
||||
0,
|
||||
Map.of(
|
||||
EquipmentType.BOOTS, 1,
|
||||
EquipmentType.LEGGINGS, 2,
|
||||
EquipmentType.CHESTPLATE, 3,
|
||||
EquipmentType.HELMET, 1,
|
||||
EquipmentType.BODY, 3
|
||||
),
|
||||
1,
|
||||
SoundEvents.ITEM_ARMOR_EQUIP_LEATHER,
|
||||
0,
|
||||
0.5F,
|
||||
ItemTags.REPAIRS_LEATHER_ARMOR,
|
||||
Identifier.of("fabric-rendering-v1-testmod", "test_material")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
@ -114,7 +115,7 @@ public final class ResourceConditionsImpl implements ModInitializer {
|
|||
* - any call to {@link #tagsPopulated} will check the tags from the failed reload instead of failing directly.
|
||||
* This is probably acceptable.
|
||||
*/
|
||||
public static final ThreadLocal<Map<RegistryKey<?>, Set<Identifier>>> LOADED_TAGS = new ThreadLocal<>();
|
||||
public static final AtomicReference<Map<RegistryKey<?>, Set<Identifier>>> LOADED_TAGS = new AtomicReference<>();
|
||||
|
||||
public static void setTags(List<Registry.PendingTagLoad<?>> tags) {
|
||||
Map<RegistryKey<?>, Set<Identifier>> tagMap = new IdentityHashMap<>();
|
||||
|
@ -123,7 +124,9 @@ public final class ResourceConditionsImpl implements ModInitializer {
|
|||
tagMap.put(registryTags.getKey(), registryTags.getLookup().streamTagKeys().map(TagKey::id).collect(Collectors.toSet()));
|
||||
}
|
||||
|
||||
LOADED_TAGS.set(tagMap);
|
||||
if (LOADED_TAGS.getAndSet(tagMap) != null) {
|
||||
throw new IllegalStateException("Tags already captured, this should not happen");
|
||||
}
|
||||
}
|
||||
|
||||
// Cannot use registry because tags are not loaded to the registry at this stage yet.
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue