mirror of
https://github.com/architectury/architectury-api.git
synced 2026-03-30 13:05:25 -05:00
Big clean up, more details in the PR (#216)
* Big clean up, more details in the PR * Fix build * Deprecate BlockProperties, generate AWs for Item constructors, Block constructors and RenderStateShard fields * Add a few more RenderType AWs * Deprecate BlockPropertiesExtension * Set defaultType on resolving the entity type in SpawnEggItem * Used the wrong object * Add license information for generating AWs * Add link to original PR * Properly add support for forge vanilla registries * Bump to 4.1
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* This file is part of architectury.
|
||||
* Copyright (C) 2020, 2021, 2022 architectury
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
package dev.architectury.core.item;
|
||||
|
||||
import dev.architectury.registry.registries.RegistrySupplier;
|
||||
import net.minecraft.core.BlockSource;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.dispenser.DefaultDispenseItemBehavior;
|
||||
import net.minecraft.core.dispenser.DispenseItemBehavior;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
import net.minecraft.world.entity.MobSpawnType;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.SpawnEggItem;
|
||||
import net.minecraft.world.level.block.DispenserBlock;
|
||||
import net.minecraft.world.level.gameevent.GameEvent;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class ArchitecturySpawnEggItem extends SpawnEggItem {
|
||||
private static final Logger LOGGER = LogManager.getLogger(ArchitecturySpawnEggItem.class);
|
||||
|
||||
private final RegistrySupplier<? extends EntityType<? extends Mob>> entityType;
|
||||
|
||||
protected static DispenseItemBehavior createDispenseItemBehavior() {
|
||||
return new DefaultDispenseItemBehavior() {
|
||||
@Override
|
||||
public ItemStack execute(BlockSource source, ItemStack stack) {
|
||||
Direction direction = source.getBlockState().getValue(DispenserBlock.FACING);
|
||||
EntityType<?> entityType = ((SpawnEggItem) stack.getItem()).getType(stack.getTag());
|
||||
|
||||
try {
|
||||
entityType.spawn(source.getLevel(), stack, null, source.getPos().relative(direction), MobSpawnType.DISPENSER, direction != Direction.UP, false);
|
||||
} catch (Exception var6) {
|
||||
LOGGER.error("Error while dispensing spawn egg from dispenser at {}", source.getPos(), var6);
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
stack.shrink(1);
|
||||
source.getLevel().gameEvent(GameEvent.ENTITY_PLACE, source.getPos());
|
||||
return stack;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public ArchitecturySpawnEggItem(RegistrySupplier<? extends EntityType<? extends Mob>> entityType, int backgroundColor, int highlightColor, Properties properties) {
|
||||
this(entityType, backgroundColor, highlightColor, properties, createDispenseItemBehavior());
|
||||
}
|
||||
|
||||
public ArchitecturySpawnEggItem(RegistrySupplier<? extends EntityType<? extends Mob>> entityType, int backgroundColor, int highlightColor, Properties properties,
|
||||
@Nullable DispenseItemBehavior dispenseItemBehavior) {
|
||||
super(null, backgroundColor, highlightColor, properties);
|
||||
this.entityType = Objects.requireNonNull(entityType, "entityType");
|
||||
SpawnEggItem.BY_ID.remove(null);
|
||||
entityType.listen(type -> {
|
||||
SpawnEggItem.BY_ID.put(type, this);
|
||||
this.defaultType = type;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityType<?> getType(@Nullable CompoundTag compoundTag) {
|
||||
EntityType<?> type = super.getType(compoundTag);
|
||||
return type == null ? entityType.get() : type;
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,6 @@ import dev.architectury.annotations.ForgeEvent;
|
||||
import dev.architectury.annotations.ForgeEventCancellable;
|
||||
import dev.architectury.injectables.annotations.ExpectPlatform;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.reflect.Method;
|
||||
@@ -58,7 +57,7 @@ public final class EventFactory {
|
||||
public static <T> Event<T> createLoop(Class<T> clazz) {
|
||||
return of(listeners -> (T) Proxy.newProxyInstance(EventFactory.class.getClassLoader(), new Class[]{clazz}, new AbstractInvocationHandler() {
|
||||
@Override
|
||||
protected Object handleInvocation(@NotNull Object proxy, @NotNull Method method, Object @NotNull [] args) throws Throwable {
|
||||
protected Object handleInvocation(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
for (var listener : listeners) {
|
||||
invokeMethod(listener, method, args);
|
||||
}
|
||||
@@ -77,7 +76,7 @@ public final class EventFactory {
|
||||
public static <T> Event<T> createEventResult(Class<T> clazz) {
|
||||
return of(listeners -> (T) Proxy.newProxyInstance(EventFactory.class.getClassLoader(), new Class[]{clazz}, new AbstractInvocationHandler() {
|
||||
@Override
|
||||
protected Object handleInvocation(@NotNull Object proxy, @NotNull Method method, Object @NotNull [] args) throws Throwable {
|
||||
protected Object handleInvocation(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
for (var listener : listeners) {
|
||||
var result = (EventResult) Objects.requireNonNull(invokeMethod(listener, method, args));
|
||||
if (result.interruptsFurtherEvaluation()) {
|
||||
@@ -99,7 +98,7 @@ public final class EventFactory {
|
||||
public static <T> Event<T> createCompoundEventResult(Class<T> clazz) {
|
||||
return of(listeners -> (T) Proxy.newProxyInstance(EventFactory.class.getClassLoader(), new Class[]{clazz}, new AbstractInvocationHandler() {
|
||||
@Override
|
||||
protected Object handleInvocation(@NotNull Object proxy, @NotNull Method method, Object @NotNull [] args) throws Throwable {
|
||||
protected Object handleInvocation(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
for (var listener : listeners) {
|
||||
var result = (CompoundEventResult) Objects.requireNonNull(invokeMethod(listener, method, args));
|
||||
if (result.interruptsFurtherEvaluation()) {
|
||||
@@ -121,7 +120,7 @@ public final class EventFactory {
|
||||
public static <T> Event<Consumer<T>> createConsumerLoop(Class<T> clazz) {
|
||||
Event<Consumer<T>> event = of(listeners -> (Consumer<T>) Proxy.newProxyInstance(EventFactory.class.getClassLoader(), new Class[]{Consumer.class}, new AbstractInvocationHandler() {
|
||||
@Override
|
||||
protected Object handleInvocation(@NotNull Object proxy, @NotNull Method method, Object @NotNull [] args) throws Throwable {
|
||||
protected Object handleInvocation(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
for (var listener : listeners) {
|
||||
invokeMethod(listener, method, args);
|
||||
}
|
||||
@@ -148,7 +147,7 @@ public final class EventFactory {
|
||||
public static <T> Event<EventActor<T>> createEventActorLoop(Class<T> clazz) {
|
||||
Event<EventActor<T>> event = of(listeners -> (EventActor<T>) Proxy.newProxyInstance(EventFactory.class.getClassLoader(), new Class[]{EventActor.class}, new AbstractInvocationHandler() {
|
||||
@Override
|
||||
protected Object handleInvocation(@NotNull Object proxy, @NotNull Method method, Object @NotNull [] args) throws Throwable {
|
||||
protected Object handleInvocation(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
for (var listener : listeners) {
|
||||
var result = (EventResult) invokeMethod(listener, method, args);
|
||||
if (result.interruptsFurtherEvaluation()) {
|
||||
|
||||
@@ -24,7 +24,6 @@ import dev.architectury.injectables.targets.ArchitecturyTarget;
|
||||
import dev.architectury.utils.Env;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.minecraft.SharedConstants;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collection;
|
||||
|
||||
@@ -25,9 +25,12 @@ import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.material.Material;
|
||||
import net.minecraft.world.level.material.MaterialColor;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval
|
||||
public abstract class BlockProperties extends BlockBehaviour.Properties implements BlockPropertiesExtension {
|
||||
public BlockProperties(Material material, Function<BlockState, MaterialColor> function) {
|
||||
super(material, function);
|
||||
|
||||
@@ -19,5 +19,9 @@
|
||||
|
||||
package dev.architectury.registry.block;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval
|
||||
public interface BlockPropertiesExtension {
|
||||
}
|
||||
@@ -19,9 +19,9 @@
|
||||
|
||||
package dev.architectury.registry.level;
|
||||
|
||||
import dev.architectury.injectables.annotations.ExpectPlatform;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.world.level.GameRules;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
@@ -37,10 +37,12 @@ public final class GameRuleFactory {
|
||||
*
|
||||
* @param defaultValue the rule's default value
|
||||
* @return the created type
|
||||
* @deprecated Use the method directly.
|
||||
*/
|
||||
@ExpectPlatform
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval
|
||||
public static GameRules.Type<GameRules.BooleanValue> createBooleanRule(boolean defaultValue) {
|
||||
throw new AssertionError();
|
||||
return GameRules.BooleanValue.create(defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,10 +51,12 @@ public final class GameRuleFactory {
|
||||
* @param defaultValue the rule's default value
|
||||
* @param changedCallback a callback that is called when the rule's value is changed
|
||||
* @return the created type
|
||||
* @deprecated Use the method directly.
|
||||
*/
|
||||
@ExpectPlatform
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval
|
||||
public static GameRules.Type<GameRules.BooleanValue> createBooleanRule(boolean defaultValue, BiConsumer<MinecraftServer, GameRules.BooleanValue> changedCallback) {
|
||||
throw new AssertionError();
|
||||
return GameRules.BooleanValue.create(defaultValue, changedCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,10 +64,12 @@ public final class GameRuleFactory {
|
||||
*
|
||||
* @param defaultValue the rule's default value
|
||||
* @return the created type
|
||||
* @deprecated Use the method directly.
|
||||
*/
|
||||
@ExpectPlatform
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval
|
||||
public static GameRules.Type<GameRules.IntegerValue> createIntRule(int defaultValue) {
|
||||
throw new AssertionError();
|
||||
return GameRules.IntegerValue.create(defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -72,9 +78,11 @@ public final class GameRuleFactory {
|
||||
* @param defaultValue the rule's default value
|
||||
* @param changedCallback a callback that is called when the rule's value is changed
|
||||
* @return the created type
|
||||
* @deprecated Use the method directly.
|
||||
*/
|
||||
@ExpectPlatform
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval
|
||||
public static GameRules.Type<GameRules.IntegerValue> createIntRule(int defaultValue, BiConsumer<MinecraftServer, GameRules.IntegerValue> changedCallback) {
|
||||
throw new AssertionError();
|
||||
return GameRules.IntegerValue.create(defaultValue, changedCallback);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
|
||||
package dev.architectury.registry.level;
|
||||
|
||||
import dev.architectury.injectables.annotations.ExpectPlatform;
|
||||
import net.minecraft.world.level.GameRules;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
/**
|
||||
* A registry for registering game rules.
|
||||
@@ -37,9 +37,11 @@ public final class GameRuleRegistry {
|
||||
* @param type the type of the rule
|
||||
* @param <T> the type of the rule value
|
||||
* @return a key for the registered rule
|
||||
* @deprecated Use the method directly.
|
||||
*/
|
||||
@ExpectPlatform
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval
|
||||
public static <T extends GameRules.Value<T>> GameRules.Key<T> register(String name, GameRules.Category category, GameRules.Type<T> type) {
|
||||
throw new AssertionError();
|
||||
return GameRules.register(name, category, type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,9 @@
|
||||
|
||||
package dev.architectury.registry.level.advancement;
|
||||
|
||||
import dev.architectury.injectables.annotations.ExpectPlatform;
|
||||
import net.minecraft.advancements.CriteriaTriggers;
|
||||
import net.minecraft.advancements.CriterionTrigger;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
public final class CriteriaTriggersRegistry {
|
||||
private CriteriaTriggersRegistry() {
|
||||
@@ -32,9 +33,11 @@ public final class CriteriaTriggersRegistry {
|
||||
* @param trigger The trigger to register
|
||||
* @param <T> The type of trigger
|
||||
* @return The trigger registered
|
||||
* @deprecated Use the method directly.
|
||||
*/
|
||||
@ExpectPlatform
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval
|
||||
public static <T extends CriterionTrigger<?>> T register(T trigger) {
|
||||
throw new AssertionError();
|
||||
return CriteriaTriggers.register(trigger);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ public final class EntityAttributeRegistry {
|
||||
* @see net.minecraft.world.entity.ai.attributes.DefaultAttributes
|
||||
*/
|
||||
@ExpectPlatform
|
||||
public static void register(Supplier<EntityType<? extends LivingEntity>> type, Supplier<AttributeSupplier.Builder> attribute) {
|
||||
public static void register(Supplier<? extends EntityType<? extends LivingEntity>> type, Supplier<AttributeSupplier.Builder> attribute) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ import com.google.common.base.Suppliers;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
@@ -61,7 +60,7 @@ public class DeferredRegister<T> implements Iterable<RegistrySupplier<T>> {
|
||||
var entry = new Entry<T>(id, (Supplier<T>) supplier);
|
||||
this.entries.add(entry);
|
||||
if (registered) {
|
||||
var registrar = registriesSupplier.get().get(key);
|
||||
var registrar = getRegistrar();
|
||||
entry.value = registrar.register(entry.id, entry.supplier);
|
||||
}
|
||||
return (RegistrySupplier<R>) entry;
|
||||
@@ -72,18 +71,25 @@ public class DeferredRegister<T> implements Iterable<RegistrySupplier<T>> {
|
||||
throw new IllegalStateException("Cannot register a deferred register twice!");
|
||||
}
|
||||
registered = true;
|
||||
var registrar = registriesSupplier.get().get(key);
|
||||
var registrar = getRegistrar();
|
||||
for (var entry : entries) {
|
||||
entry.value = registrar.register(entry.id, entry.supplier);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Iterator<RegistrySupplier<T>> iterator() {
|
||||
return entryView.iterator();
|
||||
}
|
||||
|
||||
public Registries getRegistries() {
|
||||
return registriesSupplier.get();
|
||||
}
|
||||
|
||||
public Registrar<T> getRegistrar() {
|
||||
return registriesSupplier.get().get(key);
|
||||
}
|
||||
|
||||
private class Entry<R> implements RegistrySupplier<R> {
|
||||
private final ResourceLocation id;
|
||||
private final Supplier<R> supplier;
|
||||
@@ -94,6 +100,16 @@ public class DeferredRegister<T> implements Iterable<RegistrySupplier<T>> {
|
||||
this.supplier = supplier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Registries getRegistries() {
|
||||
return DeferredRegister.this.getRegistries();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Registrar<R> getRegistrar() {
|
||||
return (Registrar<R>) DeferredRegister.this.getRegistrar();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getRegistryId() {
|
||||
return key.location();
|
||||
|
||||
@@ -27,11 +27,22 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public interface Registrar<T> extends Iterable<T> {
|
||||
RegistrySupplier<T> delegate(ResourceLocation id);
|
||||
|
||||
default <R extends T> RegistrySupplier<R> wrap(R obj) {
|
||||
ResourceLocation id = getId(obj);
|
||||
|
||||
if (id == null) {
|
||||
throw new IllegalArgumentException("Cannot wrap an object without an id: " + obj);
|
||||
} else {
|
||||
return (RegistrySupplier<R>) delegate(id);
|
||||
}
|
||||
}
|
||||
|
||||
<E extends T> RegistrySupplier<E> register(ResourceLocation id, Supplier<E> supplier);
|
||||
|
||||
@Nullable
|
||||
@@ -56,4 +67,32 @@ public interface Registrar<T> extends Iterable<T> {
|
||||
Set<Map.Entry<ResourceKey<T>, T>> entrySet();
|
||||
|
||||
ResourceKey<? extends Registry<T>> key();
|
||||
|
||||
/**
|
||||
* Listens to when the registry entry is registered, and calls the given action.
|
||||
* Evaluates immediately if the entry is already registered.
|
||||
* <p>
|
||||
* Whenever the callback is called is dependent on the registry implementation.
|
||||
* On fabric, this will be called when the registry entry is registered.
|
||||
* On forge, this will be called when the registry entry is registered or when Minecraft has started.
|
||||
*
|
||||
* @param supplier the entry to listen to
|
||||
* @param callback the action to call when the registry entry is registered
|
||||
*/
|
||||
default <R extends T> void listen(RegistrySupplier<R> supplier, Consumer<R> callback) {
|
||||
listen(supplier.getId(), obj -> callback.accept((R) obj));
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens to when the registry entry is registered, and calls the given action.
|
||||
* Evaluates immediately if the entry is already registered.
|
||||
* <p>
|
||||
* Whenever the callback is called is dependent on the registry implementation.
|
||||
* On fabric, this will be called when the registry entry is registered.
|
||||
* On forge, this will be called when the registry entry is registered or when Minecraft has started.
|
||||
*
|
||||
* @param id the entry to listen to
|
||||
* @param callback the action to call when the registry entry is registered
|
||||
*/
|
||||
void listen(ResourceLocation id, Consumer<T> callback);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,10 @@
|
||||
|
||||
package dev.architectury.registry.registries;
|
||||
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Optional;
|
||||
@@ -27,12 +30,24 @@ import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@ApiStatus.NonExtendable
|
||||
public interface RegistrySupplier<T> extends Supplier<T> {
|
||||
Registries getRegistries();
|
||||
|
||||
Registrar<T> getRegistrar();
|
||||
|
||||
/**
|
||||
* @return the identifier of the registry
|
||||
*/
|
||||
ResourceLocation getRegistryId();
|
||||
|
||||
/**
|
||||
* @return the identifier of the registry
|
||||
*/
|
||||
default ResourceKey<Registry<T>> getRegistryKey() {
|
||||
return ResourceKey.createRegistryKey(getRegistryId());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the identifier of the entry
|
||||
*/
|
||||
@@ -84,4 +99,14 @@ public interface RegistrySupplier<T> extends Supplier<T> {
|
||||
default T orElseGet(Supplier<? extends T> supplier) {
|
||||
return isPresent() ? get() : supplier.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens to when the registry entry is registered, and calls the given action.
|
||||
* Evaluates immediately if the entry is already registered.
|
||||
*
|
||||
* @param callback the action to call when the registry entry is registered
|
||||
*/
|
||||
default void listen(Consumer<T> callback) {
|
||||
getRegistrar().listen(this, callback);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user