started lotus, seashell, giant lilypad, improved krakens grasp

This commit is contained in:
craisinlord committed 2026-07-16 00:04:00 -05:00
1 parent 361bf005f3
commit c91590b553
11 files changed
-923

No files matched your search

@@ -1,146 +0,0 @@
package software.bernie.geckolib.animatable;
import net.minecraft.class_1937;
import net.minecraft.class_2586;
import net.minecraft.class_3218;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import software.bernie.geckolib.GeckoLibConstants;
import software.bernie.geckolib.GeckoLibServices;
import software.bernie.geckolib.animation.AnimatableManager;
import software.bernie.geckolib.animation.AnimationController;
import software.bernie.geckolib.constant.dataticket.SerializableDataTicket;
import software.bernie.geckolib.util.RenderUtil;
/**
* The {@link GeoAnimatable} interface specific to {@link class_2586 BlockEntities}
*
* @see <a href="https://github.com/bernie-g/geckolib/wiki/Block-Animations">GeckoLib Wiki - Block Animations</a>
*/
public interface GeoBlockEntity extends GeoAnimatable {
/**
* Get server-synced animation data via its relevant {@link SerializableDataTicket}.
* <p>
* Should only be used on the <u>client-side</u>
* <p>
* <b><u>DO NOT OVERRIDE</u></b>
*
* @param dataTicket The data ticket for the data to retrieve
* @return The synced data, or null if no data of that type has been synced
*/
@ApiStatus.NonExtendable
@Nullable
default <D> D getAnimData(SerializableDataTicket<D> dataTicket) {
return getAnimatableInstanceCache().getManagerForId(0).getData(dataTicket);
}
/**
* Saves an arbitrary piece of data to this animatable's {@link AnimatableManager}
* <p>
* <b><u>DO NOT OVERRIDE</u></b>
*
* @param dataTicket The DataTicket to sync the data for
* @param data The data to sync
*/
@ApiStatus.NonExtendable
default <D> void setAnimData(SerializableDataTicket<D> dataTicket, D data) {
class_2586 blockEntity = (class_2586)this;
class_1937 level = blockEntity.method_10997();
if (level == null) {
GeckoLibConstants.LOGGER.error("Attempting to set animation data for BlockEntity too early! Must wait until after the BlockEntity has been set in the world. (" + blockEntity.getClass().toString() + ")");
return;
}
if (level.method_8608()) {
getAnimatableInstanceCache().getManagerForId(0).setData(dataTicket, data);
}
else {
GeckoLibServices.NETWORK.syncBlockEntityAnimData(blockEntity.method_11016(), dataTicket, data, (class_3218)level);
}
}
/**
* Trigger an animation for this BlockEntity, based on the controller name and animation name
* <p>
* This can be fired from either the client or the server, but optimally you would call it from the server
* <p>
* <b><u>DO NOT OVERRIDE</u></b>
*
* @param controllerName The name of the controller name the animation belongs to, or null to do an inefficient lazy search
* @param animName The name of animation to trigger. This needs to have been registered with the controller via {@link AnimationController#triggerableAnim AnimationController.triggerableAnim}
*/
@ApiStatus.NonExtendable
default void triggerAnim(@Nullable String controllerName, String animName) {
class_2586 blockEntity = (class_2586)this;
class_1937 level = blockEntity.method_10997();
if (level == null) {
GeckoLibConstants.LOGGER.error("Attempting to trigger an animation for a BlockEntity too early! Must wait until after the BlockEntity has been set in the world. (" + blockEntity.getClass().toString() + ")");
return;
}
if (level.method_8608()) {
if (controllerName != null) {
getAnimatableInstanceCache().getManagerForId(0).tryTriggerAnimation(controllerName, animName);
}
else {
getAnimatableInstanceCache().getManagerForId(0).tryTriggerAnimation(animName);
}
}
else {
GeckoLibServices.NETWORK.triggerBlockEntityAnim(blockEntity.method_11016(), controllerName, animName, (class_3218)level);
}
}
/**
* Stop a previously triggered animation for this BlockEntity for the given controller name and animation name
* <p>
* This can be fired from either the client or the server, but optimally you would call it from the server
* <p>
* <b><u>DO NOT OVERRIDE</u></b>
*
* @param controllerName The name of the controller name the animation belongs to, or null to do an inefficient lazy search
* @param animName The name of the triggered animation to stop, or null to stop any currently playing triggered animation
*/
@ApiStatus.NonExtendable
default void stopTriggeredAnim(@Nullable String controllerName, @Nullable String animName) {
class_2586 blockEntity = (class_2586)this;
class_1937 level = blockEntity.method_10997();
if (level == null) {
GeckoLibConstants.LOGGER.error("Attempting to stop a triggered animation for a BlockEntity too early! Must wait until after the BlockEntity has been set in the world. (" + blockEntity.getClass().toString() + ")");
return;
}
if (level.method_8608()) {
AnimatableManager<GeoAnimatable> animatableManager = getAnimatableInstanceCache().getManagerForId(0);
if (controllerName != null) {
animatableManager.stopTriggeredAnimation(controllerName, animName);
}
else {
animatableManager.stopTriggeredAnimation(animName);
}
}
else {
GeckoLibServices.NETWORK.stopTriggeredBlockEntityAnim(blockEntity.method_11016(), (class_3218)level, controllerName, animName);
}
}
/**
* Returns the current age/tick of the animatable instance
* <p>
* By default this is just the animatable's age in ticks, but this method allows for non-ticking custom animatables to provide their own values
*
* @param blockEntity The BlockEntity representing this animatable
* @return The current tick/age of the animatable, for animation purposes
*/
@Override
default double getTick(Object blockEntity) {
return RenderUtil.getCurrentTick();
}
}
@@ -1,65 +0,0 @@
package software.bernie.geckolib.model;
import net.minecraft.class_2960;
import software.bernie.geckolib.animatable.GeoAnimatable;
/**
* {@link DefaultedGeoModel} specific to {@link net.minecraft.class_2248 Blocks}
* <p>
* Using this class pre-sorts provided asset paths into the "block" subdirectory
*/
public class DefaultedBlockGeoModel<T extends GeoAnimatable> extends DefaultedGeoModel<T> {
/**
* Create a new instance of this model class
* <p>
* The asset path should be the truncated relative path from the base folder
* <p>
* E.G.
* <pre>{@code
* new ResourceLocation("myMod", "workbench/sawmill")
* }</pre>
*/
public DefaultedBlockGeoModel(class_2960 assetSubpath) {
super(assetSubpath);
}
/**
* Returns the subtype string for this type of model
* <p>
* This allows for sorting of asset files into neat subdirectories for clean management.
*/
@Override
protected String subtype() {
return "block";
}
/**
* Changes the constructor-defined model path for this model to an alternate
* <p>
* This is useful if your animatable shares a model path with another animatable that differs in path to the texture and animations for this model
*/
@Override
public DefaultedBlockGeoModel<T> withAltModel(class_2960 altPath) {
return (DefaultedBlockGeoModel<T>)super.withAltModel(altPath);
}
/**
* Changes the constructor-defined animations path for this model to an alternate
* <p>
* This is useful if your animatable shares an animations path with another animatable that differs in path to the model and texture for this model
*/
@Override
public DefaultedBlockGeoModel<T> withAltAnimations(class_2960 altPath) {
return (DefaultedBlockGeoModel<T>)super.withAltAnimations(altPath);
}
/**
* Changes the constructor-defined texture path for this model to an alternate
* <p>
* This is useful if your animatable shares a texture path with another animatable that differs in path to the model and animations for this model
*/
@Override
public DefaultedBlockGeoModel<T> withAltTexture(class_2960 altPath) {
return (DefaultedBlockGeoModel<T>)super.withAltTexture(altPath);
}
}
@@ -1,250 +0,0 @@
package software.bernie.geckolib.model;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import software.bernie.geckolib.GeckoLibConstants;
import software.bernie.geckolib.animatable.GeoAnimatable;
import software.bernie.geckolib.animatable.GeoReplacedEntity;
import software.bernie.geckolib.animation.AnimatableManager;
import software.bernie.geckolib.animation.Animation;
import software.bernie.geckolib.animation.AnimationProcessor;
import software.bernie.geckolib.animation.AnimationState;
import software.bernie.geckolib.cache.GeckoLibCache;
import software.bernie.geckolib.cache.object.BakedGeoModel;
import software.bernie.geckolib.cache.object.GeoBone;
import software.bernie.geckolib.constant.DataTickets;
import software.bernie.geckolib.constant.dataticket.DataTicket;
import software.bernie.geckolib.loading.object.BakedAnimations;
import software.bernie.geckolib.renderer.GeoRenderer;
import software.bernie.geckolib.util.RenderUtil;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.DoubleSupplier;
import net.minecraft.class_1297;
import net.minecraft.class_1921;
import net.minecraft.class_2960;
import net.minecraft.class_310;
/**
* Base class for all code-based model objects
* <p>
* All models registered to a {@link GeoRenderer} must be an instance of this or one of its subclasses
*
* @see <a href="https://github.com/bernie-g/geckolib/wiki/Models">GeckoLib Wiki - Models</a>
*/
public abstract class GeoModel<T extends GeoAnimatable> {
private final AnimationProcessor<T> processor = new AnimationProcessor<>(this);
private BakedGeoModel currentModel = null;
private double animTime;
private double lastGameTickTime;
private long lastRenderedInstance = -1;
/**
* Returns the resource path for the {@link BakedGeoModel} (model json file) to render based on the provided animatable
*/
public class_2960 getModelResource(T animatable, @Nullable GeoRenderer<T> renderer) {
return getModelResource(animatable);
}
/**
* Returns the resource path for the {@link BakedGeoModel} (model json file) to render based on the provided animatable
*/
@Deprecated
public abstract class_2960 getModelResource(T animatable);
/**
* Returns the resource path for the texture file to render based on the provided animatable
*/
public class_2960 getTextureResource(T animatable, @Nullable GeoRenderer<T> renderer) {
return getTextureResource(animatable);
}
/**
* Returns the resource path for the texture file to render based on the provided animatable
*/
@Deprecated
public abstract class_2960 getTextureResource(T animatable);
/**
* Returns the resource path for the {@link BakedAnimations} (animation json file) to use for animations based on the provided animatable
*/
public abstract class_2960 getAnimationResource(T animatable);
/**
* Returns the resource path for the {@link BakedAnimations} (animation json file) fallback locations in the event
* your animation isn't present in the {@link #getAnimationResource(GeoAnimatable) primary resource}.
* <p>
* Should <b><u>NOT</u></b> be used as the primary animation resource path, and in general shouldn't be used
* at all unless you know what you are doing
*/
public class_2960[] getAnimationResourceFallbacks(T animatable) {
return new class_2960[0];
}
/**
* Override this and return true if Geckolib should crash when attempting to animate the model, but fails to find a bone
* <p>
* By default, GeckoLib will just gracefully ignore a missing bone, which might cause oddities with incorrect models or mismatching variables
*/
public boolean crashIfBoneMissing() {
return false;
}
/**
* Gets the default render type for this animatable, to be selected by default by the renderer using it
*
* @return Return the RenderType to use, or null to prevent the model rendering. Returning null will not prevent animation functions taking place
*/
@Nullable
public class_1921 getRenderType(T animatable, class_2960 texture) {
return class_1921.method_23578(texture);
}
/**
* Get the baked geo model object used for rendering from the given resource path
*/
public BakedGeoModel getBakedModel(class_2960 location) {
BakedGeoModel model = GeckoLibCache.getBakedModels().get(location);
if (model == null) {
if (!location.method_12832().contains("geo/"))
throw GeckoLibConstants.exception(location, "Invalid model resource path provided - GeckoLib models must be placed in assets/<modid>/geo/");
throw GeckoLibConstants.exception(location, "Unable to find model");
}
if (model != this.currentModel) {
this.processor.setActiveModel(model);
this.currentModel = model;
}
return this.currentModel;
}
/**
* Gets a bone from this model by name
*
* @param name The name of the bone
* @return An {@link Optional} containing the {@link software.bernie.geckolib.cache.object.GeoBone} if one matches, otherwise an empty Optional
*/
public Optional<GeoBone> getBone(String name) {
return Optional.ofNullable(getAnimationProcessor().getBone(name));
}
/**
* Gets the loaded {@link Animation} for the given animation {@code name}, if it exists
*
* @param animatable The {@code GeoAnimatable} instance being referred to
* @param name The name of the animation to retrieve
* @return The {@code Animation} instance for the provided {@code name}, or null if none match
*/
@Nullable
public Animation getAnimation(T animatable, String name) {
class_2960 location = getAnimationResource(animatable);
BakedAnimations bakedAnimations = GeckoLibCache.getBakedAnimations().get(location);
Animation animation = bakedAnimations != null ? bakedAnimations.getAnimation(name) : null;
if (animation != null)
return animation;
for (class_2960 fallbackLocation : getAnimationResourceFallbacks(animatable)) {
bakedAnimations = GeckoLibCache.getBakedAnimations().get(location = fallbackLocation);
animation = bakedAnimations != null ? bakedAnimations.getAnimation(name) : null;
if (animation != null)
return animation;
}
if (bakedAnimations == null) {
if (!location.method_12832().contains("animations/"))
throw GeckoLibConstants.exception(location, "Invalid animation resource path provided - GeckoLib animations must be placed in assets/<modid>/animations/");
throw GeckoLibConstants.exception(location, "Unable to find animation file.");
}
return null;
}
/**
* Gets the {@link AnimationProcessor} for this model.
*/
public AnimationProcessor<T> getAnimationProcessor() {
return this.processor;
}
/**
* Add additional {@link DataTicket DataTickets} to the {@link AnimationState} to be handled by your animation handler at render time
*
* @param animatable The animatable instance currently being animated
* @param instanceId The unique instance id of the animatable being animated
* @param dataConsumer The DataTicket + data consumer to be added to the AnimationEvent
*/
public void addAdditionalStateData(T animatable, long instanceId, BiConsumer<DataTicket<T>, T> dataConsumer) {}
/**
* This method is called once per render-frame for each {@link GeoAnimatable} being rendered
* <p>
* It is an internal method for automated animation parsing. Use {@link GeoModel#setCustomAnimations(GeoAnimatable, long, AnimationState)} for custom animation work
*/
@ApiStatus.Internal
public void handleAnimations(T animatable, long instanceId, AnimationState<T> animationState, float partialTick) {
class_310 mc = class_310.method_1551();
AnimatableManager<T> animatableManager = animatable.getAnimatableInstanceCache().getManagerForId(instanceId);
Double currentTick = animationState.getData(DataTickets.TICK);
if (currentTick == null)
currentTick = animatable instanceof class_1297 entity ? (double)entity.field_6012 : RenderUtil.getCurrentTick();
if (animatableManager.getFirstTickTime() == -1)
animatableManager.startedAt(currentTick + partialTick);
double currentFrameTime = animatable instanceof class_1297 || animatable instanceof GeoReplacedEntity ? currentTick + partialTick : currentTick - animatableManager.getFirstTickTime();
boolean isReRender = !animatableManager.isFirstTick() && currentFrameTime == animatableManager.getLastUpdateTime();
if (isReRender && instanceId == this.lastRenderedInstance)
return;
if (!mc.method_1493() || animatable.shouldPlayAnimsWhileGamePaused()) {
animatableManager.updatedAt(currentFrameTime);
double lastUpdateTime = animatableManager.getLastUpdateTime();
this.animTime += lastUpdateTime - this.lastGameTickTime;
this.lastGameTickTime = lastUpdateTime;
}
animationState.animationTick = this.animTime;
this.lastRenderedInstance = instanceId;
AnimationProcessor<T> processor = getAnimationProcessor();
processor.preAnimationSetup(animationState, this.animTime);
if (!processor.getRegisteredBones().isEmpty())
processor.tickAnimation(animatable, this, animatableManager, this.animTime, animationState, crashIfBoneMissing());
setCustomAnimations(animatable, instanceId, animationState);
}
/**
* This method is called once per render-frame for each {@link GeoAnimatable} being rendered
* <p>
* Override to set custom animations (such as head rotation, etc)
*
* @param animatable The {@code GeoAnimatable} instance currently being rendered
* @param instanceId The instance id of the {@code GeoAnimatable}
* @param animationState An {@link AnimationState} instance created to hold animation data for the {@code animatable} for this method call
*/
public void setCustomAnimations(T animatable, long instanceId, AnimationState<T> animationState) {}
/**
* This method is called once per render-frame for each {@link GeoAnimatable} being rendered
* <p>
* Use this method to set custom {@link software.bernie.geckolib.loading.math.value.Variable Variable} values via
* {@link software.bernie.geckolib.loading.math.MathParser#setVariable(String, DoubleSupplier) MathParser.setVariable}
*
* @param animationState The AnimationState data for the current render frame
* @param animTime The internal tick counter kept by the {@link AnimatableManager manager} for this animatable
*/
public void applyMolangQueries(AnimationState<T> animationState, double animTime) {}
}
@@ -1,272 +0,0 @@
package software.bernie.geckolib.renderer;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import org.joml.Matrix4f;
import org.joml.Vector3f;
import software.bernie.geckolib.GeckoLibServices;
import software.bernie.geckolib.animatable.GeoAnimatable;
import software.bernie.geckolib.animation.AnimationState;
import software.bernie.geckolib.cache.object.BakedGeoModel;
import software.bernie.geckolib.cache.object.GeoBone;
import software.bernie.geckolib.cache.texture.AnimatableTexture;
import software.bernie.geckolib.constant.DataTickets;
import software.bernie.geckolib.model.DefaultedBlockGeoModel;
import software.bernie.geckolib.model.GeoModel;
import software.bernie.geckolib.renderer.layer.GeoRenderLayer;
import software.bernie.geckolib.renderer.layer.GeoRenderLayersContainer;
import software.bernie.geckolib.util.RenderUtil;
import java.util.List;
import net.minecraft.class_1921;
import net.minecraft.class_2318;
import net.minecraft.class_2338;
import net.minecraft.class_2350;
import net.minecraft.class_2383;
import net.minecraft.class_2586;
import net.minecraft.class_2591;
import net.minecraft.class_2680;
import net.minecraft.class_4587;
import net.minecraft.class_4588;
import net.minecraft.class_4597;
import net.minecraft.class_7833;
import net.minecraft.class_7923;
import net.minecraft.class_827;
/**
* Base {@link GeoRenderer} class for rendering {@link class_2586 Blocks} specifically
* <p>
* All blocks added to be rendered by GeckoLib should use an instance of this class.
*/
public class GeoBlockRenderer<T extends class_2586 & GeoAnimatable> implements GeoRenderer<T>, class_827<T> {
protected final GeoRenderLayersContainer<T> renderLayers = new GeoRenderLayersContainer<>(this);
protected final GeoModel<T> model;
protected T animatable;
protected float scaleWidth = 1;
protected float scaleHeight = 1;
protected Matrix4f blockRenderTranslations = new Matrix4f();
protected Matrix4f modelRenderTranslations = new Matrix4f();
/**
* Creates a new defaulted renderer instance, using the blockentity's registered id as the file name for its assets
*/
public GeoBlockRenderer(class_2591<? extends T> blockEntityType) {
this(new DefaultedBlockGeoModel<>(class_7923.field_41181.method_10221(blockEntityType)));
}
public GeoBlockRenderer(GeoModel<T> model) {
this.model = model;
}
/**
* Gets the model instance for this renderer
*/
@Override
public GeoModel<T> getGeoModel() {
return this.model;
}
/**
* Gets the {@link GeoAnimatable} instance currently being rendered
*/
@Override
public T getAnimatable() {
return this.animatable;
}
/**
* Gets the id that represents the current animatable's instance for animation purposes
* <p>
* This is mostly useful for things like items, which have a single registered instance for all objects
*/
@Override
public long getInstanceId(T animatable) {
return animatable.method_11016().hashCode();
}
/**
* Returns the list of registered {@link GeoRenderLayer GeoRenderLayers} for this renderer
*/
@Override
public List<GeoRenderLayer<T>> getRenderLayers() {
return this.renderLayers.getRenderLayers();
}
/**
* Adds a {@link GeoRenderLayer} to this renderer, to be called after the main model is rendered each frame
*/
public GeoBlockRenderer<T> addRenderLayer(GeoRenderLayer<T> renderLayer) {
this.renderLayers.addLayer(renderLayer);
return this;
}
/**
* Sets a scale override for this renderer, telling GeckoLib to pre-scale the model
*/
public GeoBlockRenderer<T> withScale(float scale) {
return withScale(scale, scale);
}
/**
* Sets a scale override for this renderer, telling GeckoLib to pre-scale the model
*/
public GeoBlockRenderer<T> withScale(float scaleWidth, float scaleHeight) {
this.scaleWidth = scaleWidth;
this.scaleHeight = scaleHeight;
return this;
}
/**
* Called before rendering the model to buffer. Allows for render modifications and preparatory work such as scaling and translating
* <p>
* {@link class_4587} translations made here are kept until the end of the render process
*/
@Override
public void preRender(class_4587 poseStack, T animatable, BakedGeoModel model, @Nullable class_4597 bufferSource, @Nullable class_4588 buffer, boolean isReRender, float partialTick, int packedLight, int packedOverlay, int colour) {
this.blockRenderTranslations = new Matrix4f(poseStack.method_23760().method_23761());
if (!isReRender)
poseStack.method_22904(0.5, 0, 0.5);
scaleModelForRender(this.scaleWidth, this.scaleHeight, poseStack, animatable, model, isReRender, partialTick, packedLight, packedOverlay);
}
@Override
@ApiStatus.Internal
public void method_3569(T animatable, float partialTick, class_4587 poseStack, class_4597 bufferSource,
int packedLight, int packedOverlay) {
this.animatable = animatable;
defaultRender(poseStack, this.animatable, bufferSource, null, null, 0, partialTick, packedLight);
}
/**
* The actual render method that subtype renderers should override to handle their specific rendering tasks
* <p>
* {@link GeoRenderer#preRender} has already been called by this stage, and {@link GeoRenderer#postRender} will be called directly after
*/
@Override
public void actuallyRender(class_4587 poseStack, T animatable, BakedGeoModel model, @Nullable class_1921 renderType,
class_4597 bufferSource, @Nullable class_4588 buffer, boolean isReRender, float partialTick, int packedLight,
int packedOverlay, int colour) {
if (!isReRender) {
AnimationState<T> animationState = new AnimationState<T>(animatable, 0, 0, partialTick, false);
long instanceId = getInstanceId(animatable);
GeoModel<T> currentModel = getGeoModel();
animationState.setData(DataTickets.TICK, animatable.getTick(animatable));
animationState.setData(DataTickets.BLOCK_ENTITY, animatable);
currentModel.addAdditionalStateData(animatable, instanceId, animationState::setData);
rotateBlock(getFacing(animatable), poseStack);
currentModel.handleAnimations(animatable, instanceId, animationState, partialTick);
}
this.modelRenderTranslations = new Matrix4f(poseStack.method_23760().method_23761());
if (buffer != null)
GeoRenderer.super.actuallyRender(poseStack, animatable, model, renderType, bufferSource, buffer, isReRender, partialTick,
packedLight, packedOverlay, colour);
}
/**
* Called after all render operations are completed and the render pass is considered functionally complete.
* <p>
* Use this method to clean up any leftover persistent objects stored during rendering or any other post-render maintenance tasks as required
*/
@Override
public void doPostRenderCleanup() {
this.animatable = null;
}
/**
* Renders the provided {@link GeoBone} and its associated child bones
*/
@Override
public void renderRecursively(class_4587 poseStack, T animatable, GeoBone bone, class_1921 renderType, class_4597 bufferSource, class_4588 buffer, boolean isReRender, float partialTick, int packedLight,
int packedOverlay, int colour) {
if (bone.isTrackingMatrices()) {
Matrix4f poseState = new Matrix4f(poseStack.method_23760().method_23761());
Matrix4f localMatrix = RenderUtil.invertAndMultiplyMatrices(poseState, this.blockRenderTranslations);
Matrix4f worldState = new Matrix4f(localMatrix);
class_2338 pos = this.animatable.method_11016();
bone.setModelSpaceMatrix(RenderUtil.invertAndMultiplyMatrices(poseState, this.modelRenderTranslations));
bone.setLocalSpaceMatrix(localMatrix);
bone.setWorldSpaceMatrix(worldState.translate(new Vector3f(pos.method_10263(), pos.method_10264(), pos.method_10260())));
}
GeoRenderer.super.renderRecursively(poseStack, animatable, bone, renderType, bufferSource, buffer, isReRender, partialTick, packedLight, packedOverlay,
colour);
}
/**
* Rotate the {@link class_4587} based on the determined {@link class_2350} the block is facing
*/
protected void rotateBlock(class_2350 facing, class_4587 poseStack) {
switch (facing) {
case field_11035 -> poseStack.method_22907(class_7833.field_40716.rotationDegrees(180));
case field_11039 -> poseStack.method_22907(class_7833.field_40716.rotationDegrees(90));
case field_11043 -> poseStack.method_22907(class_7833.field_40716.rotationDegrees(0));
case field_11034 -> poseStack.method_22907(class_7833.field_40716.rotationDegrees(270));
case field_11036 -> poseStack.method_22907(class_7833.field_40714.rotationDegrees(90));
case field_11033 -> poseStack.method_22907(class_7833.field_40713.rotationDegrees(90));
}
}
/**
* Attempt to extract a direction from the block so that the model can be oriented correctly
*/
protected class_2350 getFacing(T block) {
class_2680 blockState = block.method_11010();
if (blockState.method_28498(class_2383.field_11177))
return blockState.method_11654(class_2383.field_11177);
if (blockState.method_28498(class_2318.field_10927))
return blockState.method_11654(class_2318.field_10927);
return class_2350.field_11043;
}
/**
* Update the current frame of a {@link AnimatableTexture potentially animated} texture used by this GeoRenderer
* <p>
* This should only be called immediately prior to rendering
*
* @see AnimatableTexture#setAndUpdate
*/
@Override
public void updateAnimatedTextureFrame(T animatable) {
AnimatableTexture.setAndUpdate(getTextureLocation(animatable));
}
/**
* Create and fire the relevant {@code CompileLayers} event hook for this renderer
*/
@Override
public void fireCompileRenderLayersEvent() {
GeckoLibServices.Client.EVENTS.fireCompileBlockRenderLayers(this);
}
/**
* Create and fire the relevant {@code Pre-Render} event hook for this renderer
*
* @return Whether the renderer should proceed based on the cancellation state of the event
*/
@Override
public boolean firePreRenderEvent(class_4587 poseStack, BakedGeoModel model, class_4597 bufferSource, float partialTick, int packedLight) {
return GeckoLibServices.Client.EVENTS.fireBlockPreRender(this, poseStack, model, bufferSource, partialTick, packedLight);
}
/**
* Create and fire the relevant {@code Post-Render} event hook for this renderer
*/
@Override
public void firePostRenderEvent(class_4587 poseStack, BakedGeoModel model, class_4597 bufferSource, float partialTick, int packedLight) {
GeckoLibServices.Client.EVENTS.fireBlockPostRender(this, poseStack, model, bufferSource, partialTick, packedLight);
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,69 +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.registry;
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
import net.minecraft.class_1792;
import net.minecraft.class_1842;
import net.minecraft.class_1845;
import net.minecraft.class_1856;
import net.minecraft.class_6880;
import net.minecraft.class_7699;
/**
* An extension of {@link class_1845.class_9665} to support ingredients.
*/
public interface FabricBrewingRecipeRegistryBuilder {
/**
* An event that is called when the brewing recipe registry is being built.
*/
Event<FabricBrewingRecipeRegistryBuilder.BuildCallback> BUILD = EventFactory.createArrayBacked(FabricBrewingRecipeRegistryBuilder.BuildCallback.class, listeners -> builder -> {
for (FabricBrewingRecipeRegistryBuilder.BuildCallback listener : listeners) {
listener.build(builder);
}
});
default void registerItemRecipe(class_1792 input, class_1856 ingredient, class_1792 output) {
throw new AssertionError("Must be implemented via interface injection");
}
default void registerPotionRecipe(class_6880<class_1842> input, class_1856 ingredient, class_6880<class_1842> output) {
throw new AssertionError("Must be implemented via interface injection");
}
default void registerRecipes(class_1856 ingredient, class_6880<class_1842> potion) {
throw new AssertionError("Must be implemented via interface injection");
}
default class_7699 getEnabledFeatures() {
throw new AssertionError("Must be implemented via interface injection");
}
/**
* Use this event to register custom brewing recipes.
*/
@FunctionalInterface
interface BuildCallback {
/**
* Called when the brewing recipe registry is being built.
*
* @param builder the {@link class_1845} instance
*/
void build(class_1845.class_9665 builder);
}
}
@@ -1,48 +0,0 @@
/*
* Copyright (c) Forge Development LLC and contributors
* SPDX-License-Identifier: LGPL-2.1-only
*/
package net.neoforged.neoforge.common.brewing;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
public class BrewingRecipe implements IBrewingRecipe {
private final Ingredient input;
private final Ingredient ingredient;
private final ItemStack output;
public BrewingRecipe(Ingredient input, Ingredient ingredient, ItemStack output) {
this.input = input;
this.ingredient = ingredient;
this.output = output;
}
@Override
public boolean isInput(ItemStack stack) {
return this.input.test(stack);
}
@Override
public ItemStack getOutput(ItemStack input, ItemStack ingredient) {
return isInput(input) && isIngredient(ingredient) ? getOutput().copy() : ItemStack.EMPTY;
}
public Ingredient getInput() {
return input;
}
public Ingredient getIngredient() {
return ingredient;
}
public ItemStack getOutput() {
return output;
}
@Override
public boolean isIngredient(ItemStack ingredient) {
return this.ingredient.test(ingredient);
}
}
@@ -1,38 +0,0 @@
/*
* Copyright (c) Forge Development LLC and contributors
* SPDX-License-Identifier: LGPL-2.1-only
*/
package net.neoforged.neoforge.common.brewing;
import static net.minecraft.world.item.alchemy.PotionBrewing.Builder;
import net.minecraft.world.item.ItemStack;
import net.neoforged.neoforge.event.brewing.RegisterBrewingRecipesEvent;
/**
* Interface for more flexible brewing recipes.
*
* <p>Register using {@link RegisterBrewingRecipesEvent} and {@link Builder#addRecipe(IBrewingRecipe)}.
*/
public interface IBrewingRecipe {
/**
* Returns true is the passed ItemStack is an input for this recipe. "Input"
* being the item that goes in one of the three bottom slots of the brewing
* stand (e.g: water bottle)
*/
boolean isInput(ItemStack input);
/**
* Returns true if the passed ItemStack is an ingredient for this recipe.
* "Ingredient" being the item that goes in the top slot of the brewing
* stand (e.g: nether wart)
*/
boolean isIngredient(ItemStack ingredient);
/**
* Returns the output when the passed input is brewed with the passed
* ingredient. Empty if invalid input or ingredient.
*/
ItemStack getOutput(ItemStack input, ItemStack ingredient);
}
@@ -1,35 +0,0 @@
/*
* Copyright (c) NeoForged and contributors
* SPDX-License-Identifier: LGPL-2.1-only
*/
package net.neoforged.neoforge.event.brewing;
import net.minecraft.core.RegistryAccess;
import net.minecraft.world.item.alchemy.PotionBrewing;
import net.neoforged.bus.api.Event;
import org.jetbrains.annotations.ApiStatus;
/**
* Event to register new brewing recipes.
*
* <p>Fired on both client and server side, on the main event bus.
*/
public class RegisterBrewingRecipesEvent extends Event {
private final PotionBrewing.Builder builder;
private final RegistryAccess registryAccess;
@ApiStatus.Internal
public RegisterBrewingRecipesEvent(PotionBrewing.Builder builder, RegistryAccess registryAccess) {
this.builder = builder;
this.registryAccess = registryAccess;
}
public PotionBrewing.Builder getBuilder() {
return builder;
}
public RegistryAccess getRegistryAccess() {
return registryAccess;
}
}