diff --git a/.tmp/software/bernie/geckolib/animatable/GeoBlockEntity.java b/.tmp/software/bernie/geckolib/animatable/GeoBlockEntity.java new file mode 100644 index 00000000..170ed02c --- /dev/null +++ b/.tmp/software/bernie/geckolib/animatable/GeoBlockEntity.java @@ -0,0 +1,146 @@ +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 GeckoLib Wiki - Block Animations + */ +public interface GeoBlockEntity extends GeoAnimatable { + /** + * Get server-synced animation data via its relevant {@link SerializableDataTicket}. + *

+ * Should only be used on the client-side + *

+ * DO NOT OVERRIDE + * + * @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 getAnimData(SerializableDataTicket dataTicket) { + return getAnimatableInstanceCache().getManagerForId(0).getData(dataTicket); + } + + /** + * Saves an arbitrary piece of data to this animatable's {@link AnimatableManager} + *

+ * DO NOT OVERRIDE + * + * @param dataTicket The DataTicket to sync the data for + * @param data The data to sync + */ + @ApiStatus.NonExtendable + default void setAnimData(SerializableDataTicket 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 + *

+ * This can be fired from either the client or the server, but optimally you would call it from the server + *

+ * DO NOT OVERRIDE + * + * @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 + *

+ * This can be fired from either the client or the server, but optimally you would call it from the server + *

+ * DO NOT OVERRIDE + * + * @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 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 + *

+ * 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(); + } +} diff --git a/.tmp/software/bernie/geckolib/model/DefaultedBlockGeoModel.java b/.tmp/software/bernie/geckolib/model/DefaultedBlockGeoModel.java new file mode 100644 index 00000000..799e55a8 --- /dev/null +++ b/.tmp/software/bernie/geckolib/model/DefaultedBlockGeoModel.java @@ -0,0 +1,65 @@ +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} + *

+ * Using this class pre-sorts provided asset paths into the "block" subdirectory + */ +public class DefaultedBlockGeoModel extends DefaultedGeoModel { + /** + * Create a new instance of this model class + *

+ * The asset path should be the truncated relative path from the base folder + *

+ * E.G. + *

{@code
+	 * 	new ResourceLocation("myMod", "workbench/sawmill")
+	 * }
+ */ + public DefaultedBlockGeoModel(class_2960 assetSubpath) { + super(assetSubpath); + } + + /** + * Returns the subtype string for this type of model + *

+ * 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 + *

+ * 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 withAltModel(class_2960 altPath) { + return (DefaultedBlockGeoModel)super.withAltModel(altPath); + } + + /** + * Changes the constructor-defined animations path for this model to an alternate + *

+ * 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 withAltAnimations(class_2960 altPath) { + return (DefaultedBlockGeoModel)super.withAltAnimations(altPath); + } + + /** + * Changes the constructor-defined texture path for this model to an alternate + *

+ * 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 withAltTexture(class_2960 altPath) { + return (DefaultedBlockGeoModel)super.withAltTexture(altPath); + } +} diff --git a/.tmp/software/bernie/geckolib/model/GeoModel.java b/.tmp/software/bernie/geckolib/model/GeoModel.java new file mode 100644 index 00000000..3e17328b --- /dev/null +++ b/.tmp/software/bernie/geckolib/model/GeoModel.java @@ -0,0 +1,250 @@ +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 + *

+ * All models registered to a {@link GeoRenderer} must be an instance of this or one of its subclasses + * + * @see GeckoLib Wiki - Models + */ +public abstract class GeoModel { + private final AnimationProcessor 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 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 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}. + *

+ * Should NOT 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 + *

+ * 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//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 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//animations/"); + + throw GeckoLibConstants.exception(location, "Unable to find animation file."); + } + + return null; + } + + /** + * Gets the {@link AnimationProcessor} for this model. + */ + public AnimationProcessor 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, T> dataConsumer) {} + + /** + * This method is called once per render-frame for each {@link GeoAnimatable} being rendered + *

+ * 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 animationState, float partialTick) { + class_310 mc = class_310.method_1551(); + AnimatableManager 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 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 + *

+ * 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 animationState) {} + + /** + * This method is called once per render-frame for each {@link GeoAnimatable} being rendered + *

+ * 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 animationState, double animTime) {} +} diff --git a/.tmp/software/bernie/geckolib/renderer/GeoBlockRenderer.java b/.tmp/software/bernie/geckolib/renderer/GeoBlockRenderer.java new file mode 100644 index 00000000..2f8bfa7d --- /dev/null +++ b/.tmp/software/bernie/geckolib/renderer/GeoBlockRenderer.java @@ -0,0 +1,272 @@ +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 + *

+ * All blocks added to be rendered by GeckoLib should use an instance of this class. + */ +public class GeoBlockRenderer implements GeoRenderer, class_827 { + protected final GeoRenderLayersContainer renderLayers = new GeoRenderLayersContainer<>(this); + protected final GeoModel 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 blockEntityType) { + this(new DefaultedBlockGeoModel<>(class_7923.field_41181.method_10221(blockEntityType))); + } + + public GeoBlockRenderer(GeoModel model) { + this.model = model; + } + + /** + * Gets the model instance for this renderer + */ + @Override + public GeoModel 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 + *

+ * 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> 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 addRenderLayer(GeoRenderLayer renderLayer) { + this.renderLayers.addLayer(renderLayer); + + return this; + } + + /** + * Sets a scale override for this renderer, telling GeckoLib to pre-scale the model + */ + public GeoBlockRenderer withScale(float scale) { + return withScale(scale, scale); + } + + /** + * Sets a scale override for this renderer, telling GeckoLib to pre-scale the model + */ + public GeoBlockRenderer 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 + *

+ * {@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 + *

+ * {@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 animationState = new AnimationState(animatable, 0, 0, partialTick, false); + long instanceId = getInstanceId(animatable); + GeoModel 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. + *

+ * 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 + *

+ * 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); + } +} diff --git a/common/src/main/java/com/craisinlord/antarchy/content/AntarchyObjects.java b/common/src/main/java/com/craisinlord/antarchy/content/AntarchyObjects.java index 9b3adf8b..27092e51 100644 --- a/common/src/main/java/com/craisinlord/antarchy/content/AntarchyObjects.java +++ b/common/src/main/java/com/craisinlord/antarchy/content/AntarchyObjects.java @@ -29,6 +29,7 @@ import com.craisinlord.antarchy.content.entity.ReverieEntity; import com.craisinlord.antarchy.content.entity.ScorpionEntity; import com.craisinlord.antarchy.content.block.entity.AntNestBlockEntity; import com.craisinlord.antarchy.content.block.entity.DreamCampfireBlockEntity; +import com.craisinlord.antarchy.content.block.entity.SeashellBlockEntity; import com.craisinlord.antarchy.content.block.entity.WaspNestBlockEntity; import java.util.function.Supplier; import net.minecraft.core.Holder; @@ -292,6 +293,10 @@ public final class AntarchyObjects { @SuppressWarnings("unchecked") public static Supplier GIANT_LILY_PAD = (Supplier) UNBOUND; @SuppressWarnings("unchecked") + public static Supplier LOTUS = (Supplier) UNBOUND; + @SuppressWarnings("unchecked") + public static Supplier SEASHELL = (Supplier) UNBOUND; + @SuppressWarnings("unchecked") public static Supplier> ANT_NEST_BLOCK_ENTITY = (Supplier>) UNBOUND; @SuppressWarnings("unchecked") public static Supplier> DREAM_CAMPFIRE_BLOCK_ENTITY = (Supplier>) UNBOUND; @@ -300,6 +305,8 @@ public final class AntarchyObjects { @SuppressWarnings("unchecked") public static Supplier> HUSHWEED_BLOCK_ENTITY = (Supplier>) UNBOUND; @SuppressWarnings("unchecked") + public static Supplier> SEASHELL_BLOCK_ENTITY = (Supplier>) UNBOUND; + @SuppressWarnings("unchecked") public static Supplier STINKY_GAS = (Supplier) UNBOUND; @SuppressWarnings("unchecked") public static Supplier STINKY_FLY = (Supplier) UNBOUND; @@ -401,10 +408,12 @@ public final class AntarchyObjects { Supplier squirrelNestBlock, Supplier brutalflyCocoonSpawner, Supplier giantLilyPad, + Supplier seashell, Supplier> antNestBlockEntity, Supplier> dreamCampfireBlockEntity, Supplier> waspNestBlockEntity, Supplier> hushweedBlockEntity, + Supplier> seashellBlockEntity, Supplier stinkyGas, Supplier stinkyFly, Supplier peachLeaves, @@ -500,10 +509,12 @@ public final class AntarchyObjects { SQUIRREL_NEST_BLOCK = squirrelNestBlock; BRUTALFLY_COCOON_SPAWNER = brutalflyCocoonSpawner; GIANT_LILY_PAD = giantLilyPad; + SEASHELL = seashell; ANT_NEST_BLOCK_ENTITY = antNestBlockEntity; DREAM_CAMPFIRE_BLOCK_ENTITY = dreamCampfireBlockEntity; WASP_NEST_BLOCK_ENTITY = waspNestBlockEntity; HUSHWEED_BLOCK_ENTITY = hushweedBlockEntity; + SEASHELL_BLOCK_ENTITY = seashellBlockEntity; STINKY_GAS = stinkyGas; STINKY_FLY = stinkyFly; PEACH_LEAVES_PARTICLE = peachLeaves; @@ -524,6 +535,10 @@ public final class AntarchyObjects { TENTACLE = supplier; } + public static void setLotus(Supplier supplier) { + LOTUS = supplier; + } + public static void setKrakensGraspTrident(Supplier> supplier) { KRAKENS_GRASP_TRIDENT = supplier; } diff --git a/common/src/main/java/com/craisinlord/antarchy/content/CreativeTabOrder.java b/common/src/main/java/com/craisinlord/antarchy/content/CreativeTabOrder.java index 8ce4587f..60b97f39 100644 --- a/common/src/main/java/com/craisinlord/antarchy/content/CreativeTabOrder.java +++ b/common/src/main/java/com/craisinlord/antarchy/content/CreativeTabOrder.java @@ -59,7 +59,7 @@ public final class CreativeTabOrder { "myrmite", "broodstone", "chiten_block", "chiten_spike", "amber_moss_block", "amber_moss_carpet" -> 8; case "ouranwood_leaves", "peach_leaves" -> 9; case "duplicator_sapling", "ouranwood_acorn", "peach_sapling", "corn_seeds" -> 10; - case "orange_milkweed", "pink_milkweed", "camellia", "spider_lily", "hushweed", "amber_lichen", "creepvine", + case "orange_milkweed", "pink_milkweed", "camellia", "spider_lily", "lotus", "hushweed", "amber_lichen", "creepvine", "triffid_goo_block", "cloud_block", "wasp_nest", "red_ant_nest", "brown_ant_nest", "rainbow_ant_nest", "termite_nest", "star_coral", "star_coral_fan", "star_coral_block", @@ -179,6 +179,7 @@ public final class CreativeTabOrder { case "dead_star_coral" -> 17; case "dead_star_coral_fan" -> 18; case "dead_star_coral_block" -> 19; + case "lotus" -> 20; case "blood_crystal_block" -> 0; case "small_blood_crystal_bud" -> 1; case "medium_blood_crystal_bud" -> 2; diff --git a/common/src/main/java/com/craisinlord/antarchy/content/block/GiantLilyPadBlock.java b/common/src/main/java/com/craisinlord/antarchy/content/block/GiantLilyPadBlock.java index be01b968..a3986713 100644 --- a/common/src/main/java/com/craisinlord/antarchy/content/block/GiantLilyPadBlock.java +++ b/common/src/main/java/com/craisinlord/antarchy/content/block/GiantLilyPadBlock.java @@ -1,5 +1,6 @@ package com.craisinlord.antarchy.content.block; +import com.craisinlord.antarchy.content.AntarchyObjects; import com.craisinlord.antarchy.content.AntarchyTags; import com.mojang.serialization.MapCodec; import java.util.ArrayList; @@ -8,6 +9,7 @@ import java.util.List; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; import net.minecraft.util.StringRepresentable; import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.level.BlockGetter; @@ -15,6 +17,7 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.BonemealableBlock; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.RenderShape; import net.minecraft.world.level.block.state.BlockBehaviour; @@ -25,7 +28,7 @@ import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; import org.jetbrains.annotations.Nullable; -public final class GiantLilyPadBlock extends Block { +public final class GiantLilyPadBlock extends Block implements BonemealableBlock { public static final MapCodec CODEC = Block.simpleCodec(GiantLilyPadBlock::new); public static final EnumProperty SHAPE = EnumProperty.create("shape", Shape.class); public static final EnumProperty TILE_POSITION = EnumProperty.create("tile_position", TilePosition.class); @@ -73,6 +76,68 @@ public final class GiantLilyPadBlock extends Block { return isSupported(level, pos); } + @Override + public boolean isValidBonemealTarget(LevelReader level, BlockPos pos, BlockState state) { + if (isThreeByThreeCenter(state)) { + return level.isEmptyBlock(pos.above()); + } + + return state.getValue(SHAPE) != Shape.THREE_BY_THREE; + } + + @Override + public boolean isBonemealSuccess(Level level, RandomSource random, BlockPos pos, BlockState state) { + return true; + } + + @Override + public void performBonemeal(ServerLevel level, RandomSource random, BlockPos pos, BlockState state) { + if (isThreeByThreeCenter(state)) { + growLotus(level, pos); + return; + } + + if (state.getValue(SHAPE) == Shape.THREE_BY_THREE) { + return; + } + + spreadNearby(level, random, pos); + } + + private static boolean isThreeByThreeCenter(BlockState state) { + return state.getValue(SHAPE) == Shape.THREE_BY_THREE && state.getValue(TILE_POSITION) == TilePosition.CENTER; + } + + private static void growLotus(ServerLevel level, BlockPos padPos) { + BlockPos abovePos = padPos.above(); + if (!level.isEmptyBlock(abovePos)) { + return; + } + + BlockState lotusState = AntarchyObjects.LOTUS.get().defaultBlockState(); + if (lotusState.canSurvive(level, abovePos)) { + level.setBlock(abovePos, lotusState, Block.UPDATE_ALL); + } + } + + private static void spreadNearby(ServerLevel level, RandomSource random, BlockPos origin) { + for (int attempt = 0; attempt < 6; attempt++) { + int dx = random.nextInt(5) - 2; + int dz = random.nextInt(5) - 2; + if (dx == 0 && dz == 0) { + continue; + } + + BlockPos candidate = origin.offset(dx, 0, dz); + if (!level.isEmptyBlock(candidate) || !isSupported(level, candidate)) { + continue; + } + + level.setBlock(candidate, AntarchyObjects.GIANT_LILY_PAD.get().defaultBlockState(), Block.UPDATE_ALL); + return; + } + } + @Override protected BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor level, BlockPos pos, BlockPos neighborPos) { if (!state.canSurvive(level, pos)) { diff --git a/common/src/main/java/com/craisinlord/antarchy/content/block/LotusBlock.java b/common/src/main/java/com/craisinlord/antarchy/content/block/LotusBlock.java new file mode 100644 index 00000000..b2e2ce3e --- /dev/null +++ b/common/src/main/java/com/craisinlord/antarchy/content/block/LotusBlock.java @@ -0,0 +1,107 @@ +package com.craisinlord.antarchy.content.block; + +import com.mojang.serialization.MapCodec; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.particles.DustParticleOptions; +import net.minecraft.util.RandomSource; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.RenderShape; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; +import org.joml.Vector3f; + +public class LotusBlock extends Block { + public static final MapCodec CODEC = simpleCodec(LotusBlock::new); + public static final BooleanProperty HANGING = BlockStateProperties.HANGING; + private static final VoxelShape SHAPE = Block.box(3.0D, 0.0D, 3.0D, 13.0D, 13.0D, 13.0D); + private static final Vector3f POLLEN_COLOR = new Vector3f(1.0F, 0.85F, 0.2F); + + public LotusBlock(BlockBehaviour.Properties properties) { + super(properties); + this.registerDefaultState(this.stateDefinition.any().setValue(HANGING, false)); + } + + @Override + public MapCodec codec() { + return CODEC; + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + builder.add(HANGING); + } + + @Override + public BlockState getStateForPlacement(BlockPlaceContext context) { + Level level = context.getLevel(); + BlockPos pos = context.getClickedPos(); + boolean canHang = canSurvive(this.defaultBlockState().setValue(HANGING, true), level, pos); + boolean canStand = canSurvive(this.defaultBlockState().setValue(HANGING, false), level, pos); + + if (context.getClickedFace() == Direction.DOWN && canHang) { + return this.defaultBlockState().setValue(HANGING, true); + } + + if (canStand) { + return this.defaultBlockState().setValue(HANGING, false); + } + + return canHang ? this.defaultBlockState().setValue(HANGING, true) : null; + } + + @Override + protected RenderShape getRenderShape(BlockState state) { + return RenderShape.MODEL; + } + + @Override + protected VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) { + return SHAPE; + } + + @Override + protected boolean canSurvive(BlockState state, LevelReader level, BlockPos pos) { + if (state.getValue(HANGING)) { + BlockPos abovePos = pos.above(); + return level.getBlockState(abovePos).isFaceSturdy(level, abovePos, Direction.DOWN); + } + + BlockPos belowPos = pos.below(); + return level.getBlockState(belowPos).isFaceSturdy(level, belowPos, Direction.UP); + } + + @Override + protected BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor level, BlockPos pos, BlockPos neighborPos) { + Direction supportDirection = state.getValue(HANGING) ? Direction.UP : Direction.DOWN; + if (direction == supportDirection && !state.canSurvive(level, pos)) { + return Blocks.AIR.defaultBlockState(); + } + + return super.updateShape(state, direction, neighborState, level, pos, neighborPos); + } + + @Override + public void animateTick(BlockState state, Level level, BlockPos pos, RandomSource random) { + if (random.nextInt(10) != 0) { + return; + } + + double x = pos.getX() + 0.5D + (random.nextDouble() - 0.5D) * 0.6D; + double z = pos.getZ() + 0.5D + (random.nextDouble() - 0.5D) * 0.6D; + double y = state.getValue(HANGING) ? pos.getY() + 0.2D : pos.getY() + 0.8D; + double motionY = state.getValue(HANGING) ? -0.02D : 0.015D; + level.addParticle(new DustParticleOptions(POLLEN_COLOR, 1.0F), x, y, z, 0.0D, motionY, 0.0D); + } +} diff --git a/common/src/main/java/com/craisinlord/antarchy/content/block/SeashellBlock.java b/common/src/main/java/com/craisinlord/antarchy/content/block/SeashellBlock.java new file mode 100644 index 00000000..8c6439c3 --- /dev/null +++ b/common/src/main/java/com/craisinlord/antarchy/content/block/SeashellBlock.java @@ -0,0 +1,240 @@ +package com.craisinlord.antarchy.content.block; + +import com.craisinlord.antarchy.content.AntarchyObjects; +import com.craisinlord.antarchy.content.block.entity.SeashellBlockEntity; +import com.mojang.serialization.MapCodec; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.ItemInteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.BaseEntityBlock; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.EntityBlock; +import net.minecraft.world.level.block.HorizontalDirectionalBlock; +import net.minecraft.world.level.block.RenderShape; +import net.minecraft.world.level.block.SimpleWaterloggedBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityTicker; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.block.state.properties.DirectionProperty; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; +import org.jetbrains.annotations.Nullable; + +public final class SeashellBlock extends BaseEntityBlock implements SimpleWaterloggedBlock { + public static final MapCodec CODEC = Block.simpleCodec(SeashellBlock::new); + public static final DirectionProperty FACING = HorizontalDirectionalBlock.FACING; + public static final BooleanProperty POWERED = BlockStateProperties.POWERED; + public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; + + private static final VoxelShape SHAPE = Block.box(1.0D, 0.0D, 1.0D, 15.0D, 5.333333D, 15.0D); + + public SeashellBlock(BlockBehaviour.Properties properties) { + super(properties); + this.registerDefaultState(this.stateDefinition.any() + .setValue(FACING, Direction.NORTH) + .setValue(POWERED, false) + .setValue(WATERLOGGED, false)); + } + + @Override + public MapCodec codec() { + return CODEC; + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + builder.add(FACING, POWERED, WATERLOGGED); + } + + @Override + public BlockState getStateForPlacement(BlockPlaceContext context) { + FluidState fluidState = context.getLevel().getFluidState(context.getClickedPos()); + boolean powered = context.getLevel().hasNeighborSignal(context.getClickedPos()); + return this.defaultBlockState() + .setValue(FACING, context.getHorizontalDirection().getOpposite()) + .setValue(POWERED, powered) + .setValue(WATERLOGGED, fluidState.getType() == Fluids.WATER); + } + + @Override + protected RenderShape getRenderShape(BlockState state) { + return RenderShape.ENTITYBLOCK_ANIMATED; + } + + @Override + protected VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) { + return SHAPE; + } + + @Override + protected VoxelShape getCollisionShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) { + return SHAPE; + } + + @Override + protected VoxelShape getOcclusionShape(BlockState state, BlockGetter level, BlockPos pos) { + return SHAPE; + } + + @Override + protected BlockState rotate(BlockState state, net.minecraft.world.level.block.Rotation rotation) { + return state.setValue(FACING, rotation.rotate(state.getValue(FACING))); + } + + @Override + protected BlockState mirror(BlockState state, net.minecraft.world.level.block.Mirror mirror) { + return state.rotate(mirror.getRotation(state.getValue(FACING))); + } + + @Override + protected FluidState getFluidState(BlockState state) { + return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state); + } + + @Override + protected BlockState updateShape( + BlockState state, + Direction direction, + BlockState neighborState, + LevelAccessor level, + BlockPos pos, + BlockPos neighborPos + ) { + if (state.getValue(WATERLOGGED)) { + level.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(level)); + } + + if (!state.canSurvive(level, pos)) { + return Blocks.AIR.defaultBlockState(); + } + + if (level instanceof Level actualLevel && !actualLevel.isClientSide) { + this.updatePowerState(actualLevel, pos, state); + } + + return super.updateShape(state, direction, neighborState, level, pos, neighborPos); + } + + @Override + protected boolean canSurvive(BlockState state, LevelReader level, BlockPos pos) { + return level.getBlockState(pos.below()).isFaceSturdy(level, pos.below(), Direction.UP); + } + + @Override + protected void neighborChanged( + BlockState state, + Level level, + BlockPos pos, + Block block, + BlockPos neighborPos, + boolean movedByPiston + ) { + super.neighborChanged(state, level, pos, block, neighborPos, movedByPiston); + if (!level.isClientSide) { + this.updatePowerState(level, pos, state); + } + } + + @Override + protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean movedByPiston) { + super.onPlace(state, level, pos, oldState, movedByPiston); + if (!level.isClientSide) { + this.updatePowerState(level, pos, state); + } + } + + @Override + protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean movedByPiston) { + if (!state.is(newState.getBlock()) && level.getBlockEntity(pos) instanceof SeashellBlockEntity seashell) { + seashell.dropContents(level, pos); + } + super.onRemove(state, level, pos, newState, movedByPiston); + } + + @Override + protected ItemInteractionResult useItemOn( + ItemStack stack, + BlockState state, + Level level, + BlockPos pos, + Player player, + InteractionHand hand, + BlockHitResult hitResult + ) { + if (!(level.getBlockEntity(pos) instanceof SeashellBlockEntity seashell)) { + return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; + } + + if (!stack.isEmpty()) { + if (level.isClientSide) { + return seashell.canAcceptItem(player, stack) ? ItemInteractionResult.SUCCESS : ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; + } + + if (seashell.tryInsert(player, hand, stack)) { + level.playSound(null, pos, SoundEvents.ITEM_FRAME_ADD_ITEM, SoundSource.BLOCKS, 0.6F, 0.95F + level.random.nextFloat() * 0.1F); + return ItemInteractionResult.CONSUME; + } + + return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; + } + + if (level.isClientSide) { + return seashell.hasAnyContents() ? ItemInteractionResult.SUCCESS : ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; + } + + if (seashell.tryRemove(player, hand)) { + level.playSound(null, pos, SoundEvents.ITEM_FRAME_REMOVE_ITEM, SoundSource.BLOCKS, 0.6F, 0.95F + level.random.nextFloat() * 0.1F); + return ItemInteractionResult.CONSUME; + } + + return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; + } + + @Override + public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { + return new SeashellBlockEntity(pos, state); + } + + @Override + public BlockEntityTicker getTicker(Level level, BlockState state, BlockEntityType blockEntityType) { + return level.isClientSide + ? createTickerHelper(blockEntityType, AntarchyObjects.SEASHELL_BLOCK_ENTITY.get(), SeashellBlockEntity::clientTick) + : createTickerHelper(blockEntityType, AntarchyObjects.SEASHELL_BLOCK_ENTITY.get(), SeashellBlockEntity::serverTick); + } + + private void updatePowerState(Level level, BlockPos pos, BlockState state) { + boolean powered = level.hasNeighborSignal(pos); + if (state.getValue(POWERED) == powered) { + if (level.getBlockEntity(pos) instanceof SeashellBlockEntity seashell) { + seashell.syncVisualState(powered); + } + return; + } + + BlockState updatedState = state.setValue(POWERED, powered); + level.setBlock(pos, updatedState, Block.UPDATE_ALL); + if (level.getBlockEntity(pos) instanceof SeashellBlockEntity seashell) { + seashell.onPowerStateChanged(powered); + } + } +} diff --git a/common/src/main/java/com/craisinlord/antarchy/content/block/entity/SeashellBlockEntity.java b/common/src/main/java/com/craisinlord/antarchy/content/block/entity/SeashellBlockEntity.java new file mode 100644 index 00000000..b2367c28 --- /dev/null +++ b/common/src/main/java/com/craisinlord/antarchy/content/block/entity/SeashellBlockEntity.java @@ -0,0 +1,261 @@ +package com.craisinlord.antarchy.content.block.entity; + +import com.craisinlord.antarchy.content.AntarchyObjects; +import com.craisinlord.antarchy.content.block.SeashellBlock; +import java.util.ArrayList; +import java.util.List; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.NonNullList; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.Containers; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.ChestMenu; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.Vec3; +import org.jetbrains.annotations.Nullable; +import software.bernie.geckolib.animatable.GeoBlockEntity; +import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache; +import software.bernie.geckolib.animation.AnimatableManager; +import software.bernie.geckolib.animation.AnimationController; +import software.bernie.geckolib.animation.PlayState; +import software.bernie.geckolib.animation.RawAnimation; +import software.bernie.geckolib.util.GeckoLibUtil; + +public final class SeashellBlockEntity extends RandomizableContainerBlockEntity implements GeoBlockEntity { + private static final String MAIN_CONTROLLER = "main_controller"; + private static final String TRANSITION_CONTROLLER = "transition_controller"; + private static final String OPEN_TRIGGER = "close_to_open"; + private static final String CLOSE_TRIGGER = "open_to_close"; + private static final RawAnimation OPEN_ANIM = RawAnimation.begin().thenPlayAndHold("open"); + private static final RawAnimation CLOSED_ANIM = RawAnimation.begin().thenPlayAndHold("closed"); + private static final Component TITLE = Component.translatable("block.antarchy.seashell"); + + private final AnimatableInstanceCache animatableCache = GeckoLibUtil.createInstanceCache(this); + private NonNullList items = NonNullList.withSize(9, ItemStack.EMPTY); + private boolean visualOpen; + private boolean initializedVisualState; + + public SeashellBlockEntity(BlockPos pos, BlockState blockState) { + super(AntarchyObjects.SEASHELL_BLOCK_ENTITY.get(), pos, blockState); + this.visualOpen = blockState.getValue(SeashellBlock.POWERED); + } + + public static void serverTick(Level level, BlockPos pos, BlockState state, SeashellBlockEntity seashell) { + seashell.syncVisualState(state.getValue(SeashellBlock.POWERED)); + } + + public static void clientTick(Level level, BlockPos pos, BlockState state, SeashellBlockEntity seashell) { + seashell.syncVisualState(state.getValue(SeashellBlock.POWERED)); + } + + public boolean canAcceptItem(@Nullable Player player, ItemStack stack) { + this.unpackLootTable(player); + return !stack.isEmpty() && this.getFirstEmptySlot() >= 0; + } + + public boolean tryInsert(@Nullable Player player, InteractionHand hand, ItemStack heldStack) { + this.unpackLootTable(player); + int slot = this.getFirstEmptySlot(); + if (slot < 0 || heldStack.isEmpty()) { + return false; + } + + ItemStack inserted = heldStack.copyWithCount(1); + this.items.set(slot, inserted); + if (player == null || !player.getAbilities().instabuild) { + heldStack.shrink(1); + } + + this.setChangedAndSync(); + return true; + } + + public boolean tryRemove(Player player, InteractionHand hand) { + this.unpackLootTable(player); + int slot = this.getLastFilledSlot(); + if (slot < 0) { + return false; + } + + ItemStack removed = this.items.get(slot); + this.items.set(slot, ItemStack.EMPTY); + if (player.getItemInHand(hand).isEmpty()) { + player.setItemInHand(hand, removed); + } else if (!player.addItem(removed)) { + player.drop(removed, false); + } + + this.setChangedAndSync(); + return true; + } + + public boolean hasAnyContents() { + return this.items.stream().anyMatch(stack -> !stack.isEmpty()); + } + + public void dropContents(Level level, BlockPos pos) { + this.unpackLootTable(null); + Containers.dropContents(level, pos, this.items); + this.items = NonNullList.withSize(9, ItemStack.EMPTY); + this.setChanged(); + } + + public void onPowerStateChanged(boolean open) { + this.syncVisualState(open); + this.triggerAnim(TRANSITION_CONTROLLER, open ? OPEN_TRIGGER : CLOSE_TRIGGER); + this.setChangedAndSync(); + } + + public void syncVisualState(boolean open) { + if (!this.initializedVisualState) { + this.visualOpen = open; + this.initializedVisualState = true; + return; + } + + this.visualOpen = open; + } + + public boolean isVisualOpen() { + return this.visualOpen; + } + + public List getDisplayedStacks() { + List inserted = new ArrayList<>(); + for (ItemStack stack : this.items) { + if (!stack.isEmpty()) { + inserted.add(stack); + } + } + + List displayed = new ArrayList<>(inserted.size()); + for (int i = 0; i < inserted.size(); i++) { + displayed.add(new DisplayedStack(inserted.get(i), displayOffsetFor(i))); + } + return displayed; + } + + @Override + public void registerControllers(AnimatableManager.ControllerRegistrar controllers) { + controllers.add(new AnimationController<>(this, MAIN_CONTROLLER, state -> + state.setAndContinue(this.visualOpen ? OPEN_ANIM : CLOSED_ANIM))); + controllers.add(new AnimationController<>(this, TRANSITION_CONTROLLER, state -> PlayState.STOP) + .triggerableAnim(OPEN_TRIGGER, RawAnimation.begin().thenPlay(OPEN_TRIGGER)) + .triggerableAnim(CLOSE_TRIGGER, RawAnimation.begin().thenPlay(CLOSE_TRIGGER))); + } + + @Override + public AnimatableInstanceCache getAnimatableInstanceCache() { + return this.animatableCache; + } + + @Override + protected Component getDefaultName() { + return TITLE; + } + + @Override + protected NonNullList getItems() { + return this.items; + } + + @Override + protected void setItems(NonNullList items) { + this.items = items; + } + + @Override + protected AbstractContainerMenu createMenu(int containerId, Inventory inventory) { + return ChestMenu.threeRows(containerId, inventory, this); + } + + @Override + public int getMaxStackSize() { + return 1; + } + + @Override + public boolean canPlaceItem(int slot, ItemStack stack) { + return !stack.isEmpty() && this.items.get(slot).isEmpty(); + } + + @Override + public int getContainerSize() { + return this.items.size(); + } + + @Override + protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.saveAdditional(tag, registries); + tag.putBoolean("VisualOpen", this.visualOpen); + tag.putBoolean("VisualInitialized", this.initializedVisualState); + } + + @Override + protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.loadAdditional(tag, registries); + this.visualOpen = tag.getBoolean("VisualOpen"); + this.initializedVisualState = tag.getBoolean("VisualInitialized"); + } + + private void setChangedAndSync() { + this.setChanged(); + if (this.level != null) { + BlockState state = this.getBlockState(); + this.level.sendBlockUpdated(this.worldPosition, state, state, Block.UPDATE_CLIENTS); + } + } + + private int getFirstEmptySlot() { + for (int i = 0; i < this.items.size(); i++) { + if (this.items.get(i).isEmpty()) { + return i; + } + } + return -1; + } + + private int getLastFilledSlot() { + for (int i = this.items.size() - 1; i >= 0; i--) { + if (!this.items.get(i).isEmpty()) { + return i; + } + } + return -1; + } + + private static Vec3 displayOffsetFor(int insertionIndex) { + return switch (insertionIndex) { + case 0 -> offset(1, 0); + case 1 -> offset(0, 0); + case 2 -> offset(2, 0); + case 3 -> offset(1, 1); + case 4 -> offset(0, 1); + case 5 -> offset(2, 1); + case 6 -> offset(1, 2); + case 7 -> offset(0, 2); + case 8 -> offset(2, 2); + default -> Vec3.ZERO; + }; + } + + private static Vec3 offset(int column, int row) { + double x = -0.22D + column * 0.22D; + double z = -0.22D + row * 0.22D; + return new Vec3(x, 0.155D, z); + } + + public record DisplayedStack(ItemStack stack, Vec3 offset) { + } +} diff --git a/common/src/main/java/com/craisinlord/antarchy/content/client/model/KrakensGraspThrownTridentModel.java b/common/src/main/java/com/craisinlord/antarchy/content/client/model/KrakensGraspThrownTridentModel.java new file mode 100644 index 00000000..c5fced09 --- /dev/null +++ b/common/src/main/java/com/craisinlord/antarchy/content/client/model/KrakensGraspThrownTridentModel.java @@ -0,0 +1,22 @@ +package com.craisinlord.antarchy.content.client.model; + +import com.craisinlord.antarchy.content.entity.kraken.KrakensGraspThrownTrident; +import net.minecraft.resources.ResourceLocation; +import software.bernie.geckolib.model.GeoModel; + +public class KrakensGraspThrownTridentModel extends GeoModel { + @Override + public ResourceLocation getModelResource(KrakensGraspThrownTrident animatable) { + return ResourceLocation.fromNamespaceAndPath("antarchy", "geo/krakens_grasp.geo.json"); + } + + @Override + public ResourceLocation getTextureResource(KrakensGraspThrownTrident animatable) { + return ResourceLocation.fromNamespaceAndPath("antarchy", "textures/item/krakens_grasp/krakens_grasp.png"); + } + + @Override + public ResourceLocation getAnimationResource(KrakensGraspThrownTrident animatable) { + return ResourceLocation.fromNamespaceAndPath("antarchy", "animations/static_item.animation.json"); + } +} diff --git a/common/src/main/java/com/craisinlord/antarchy/content/client/model/SeashellModel.java b/common/src/main/java/com/craisinlord/antarchy/content/client/model/SeashellModel.java new file mode 100644 index 00000000..a678775a --- /dev/null +++ b/common/src/main/java/com/craisinlord/antarchy/content/client/model/SeashellModel.java @@ -0,0 +1,27 @@ +package com.craisinlord.antarchy.content.client.model; + +import com.craisinlord.antarchy.Antarchy; +import com.craisinlord.antarchy.content.block.entity.SeashellBlockEntity; +import net.minecraft.resources.ResourceLocation; +import software.bernie.geckolib.model.GeoModel; + +public final class SeashellModel extends GeoModel { + private static final ResourceLocation MODEL = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "geo/seashell.geo.json"); + private static final ResourceLocation TEXTURE = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "textures/block/seashell.png"); + private static final ResourceLocation ANIMATION = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "animations/seashell.animation.json"); + + @Override + public ResourceLocation getModelResource(SeashellBlockEntity animatable) { + return MODEL; + } + + @Override + public ResourceLocation getTextureResource(SeashellBlockEntity animatable) { + return TEXTURE; + } + + @Override + public ResourceLocation getAnimationResource(SeashellBlockEntity animatable) { + return ANIMATION; + } +} diff --git a/common/src/main/java/com/craisinlord/antarchy/content/client/renderer/KrakensGraspThrownTridentRenderer.java b/common/src/main/java/com/craisinlord/antarchy/content/client/renderer/KrakensGraspThrownTridentRenderer.java new file mode 100644 index 00000000..8f7ddd21 --- /dev/null +++ b/common/src/main/java/com/craisinlord/antarchy/content/client/renderer/KrakensGraspThrownTridentRenderer.java @@ -0,0 +1,13 @@ +package com.craisinlord.antarchy.content.client.renderer; + +import com.craisinlord.antarchy.content.client.model.KrakensGraspThrownTridentModel; +import com.craisinlord.antarchy.content.entity.kraken.KrakensGraspThrownTrident; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import software.bernie.geckolib.renderer.GeoEntityRenderer; + +public class KrakensGraspThrownTridentRenderer extends GeoEntityRenderer { + public KrakensGraspThrownTridentRenderer(EntityRendererProvider.Context context) { + super(context, new KrakensGraspThrownTridentModel()); + this.shadowRadius = 0.0F; + } +} diff --git a/common/src/main/java/com/craisinlord/antarchy/content/client/renderer/SeashellRenderer.java b/common/src/main/java/com/craisinlord/antarchy/content/client/renderer/SeashellRenderer.java new file mode 100644 index 00000000..65cbc5a4 --- /dev/null +++ b/common/src/main/java/com/craisinlord/antarchy/content/client/renderer/SeashellRenderer.java @@ -0,0 +1,73 @@ +package com.craisinlord.antarchy.content.client.renderer; + +import com.craisinlord.antarchy.content.block.entity.SeashellBlockEntity; +import com.craisinlord.antarchy.content.client.model.SeashellModel; +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; +import net.minecraft.core.Direction; +import net.minecraft.world.item.ItemDisplayContext; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.phys.Vec3; +import software.bernie.geckolib.cache.object.BakedGeoModel; +import software.bernie.geckolib.renderer.GeoBlockRenderer; + +public final class SeashellRenderer extends GeoBlockRenderer { + public SeashellRenderer(BlockEntityRendererProvider.Context context) { + super(new SeashellModel()); + } + + @Override + public void actuallyRender( + PoseStack poseStack, + SeashellBlockEntity animatable, + BakedGeoModel model, + net.minecraft.client.renderer.RenderType renderType, + MultiBufferSource bufferSource, + com.mojang.blaze3d.vertex.VertexConsumer buffer, + boolean isReRender, + float partialTick, + int packedLight, + int packedOverlay, + int colour + ) { + super.actuallyRender(poseStack, animatable, model, renderType, bufferSource, buffer, isReRender, partialTick, packedLight, packedOverlay, colour); + if (isReRender) { + return; + } + + float yaw = -animatable.getBlockState().getValue(com.craisinlord.antarchy.content.block.SeashellBlock.FACING).toYRot(); + for (SeashellBlockEntity.DisplayedStack displayedStack : animatable.getDisplayedStacks()) { + this.renderDisplayItem(poseStack, bufferSource, displayedStack.stack(), displayedStack.offset(), yaw, packedLight, packedOverlay); + } + } + + private void renderDisplayItem( + PoseStack poseStack, + MultiBufferSource bufferSource, + ItemStack stack, + Vec3 localOffset, + float yaw, + int packedLight, + int packedOverlay + ) { + poseStack.pushPose(); + poseStack.translate(0.5D, 0.0D, 0.5D); + poseStack.mulPose(com.mojang.math.Axis.YP.rotationDegrees(yaw)); + poseStack.translate(localOffset.x(), localOffset.y(), localOffset.z()); + poseStack.mulPose(com.mojang.math.Axis.XP.rotationDegrees(90.0F)); + poseStack.scale(0.22F, 0.22F, 0.22F); + Minecraft.getInstance().getItemRenderer().renderStatic( + stack, + ItemDisplayContext.FIXED, + packedLight, + packedOverlay, + poseStack, + bufferSource, + null, + 0 + ); + poseStack.popPose(); + } +} diff --git a/common/src/main/java/com/craisinlord/antarchy/content/entity/kraken/KrakensGraspThrownTrident.java b/common/src/main/java/com/craisinlord/antarchy/content/entity/kraken/KrakensGraspThrownTrident.java index 240141ac..4dc20d41 100644 --- a/common/src/main/java/com/craisinlord/antarchy/content/entity/kraken/KrakensGraspThrownTrident.java +++ b/common/src/main/java/com/craisinlord/antarchy/content/entity/kraken/KrakensGraspThrownTrident.java @@ -11,16 +11,20 @@ import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.projectile.AbstractArrow; -import net.minecraft.world.entity.projectile.ItemSupplier; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.EntityHitResult; import net.minecraft.world.phys.Vec3; +import software.bernie.geckolib.animatable.GeoEntity; +import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache; +import software.bernie.geckolib.animation.AnimatableManager; +import software.bernie.geckolib.util.GeckoLibUtil; -public class KrakensGraspThrownTrident extends AbstractArrow implements ItemSupplier { +public class KrakensGraspThrownTrident extends AbstractArrow implements GeoEntity { private boolean dealtDamage; private boolean returning; + private final AnimatableInstanceCache geoCache = GeckoLibUtil.createInstanceCache(this); public KrakensGraspThrownTrident(EntityType entityType, Level level) { super(entityType, level); @@ -32,8 +36,12 @@ public class KrakensGraspThrownTrident extends AbstractArrow implements ItemSupp } @Override - public ItemStack getItem() { - return new ItemStack(AntarchyObjects.KRAKENS_GRASP.get()); + public void registerControllers(AnimatableManager.ControllerRegistrar controllers) { + } + + @Override + public AnimatableInstanceCache getAnimatableInstanceCache() { + return this.geoCache; } @Override @@ -94,6 +102,8 @@ public class KrakensGraspThrownTrident extends AbstractArrow implements ItemSupp boolean hurt = target.hurt(damageSource, (float) AntarchySettings.krakensGraspThrownDamage()); if (hurt) { KrakensGraspItem.strikeLightning(target, serverLevel); + TentacleEntity.spawnAt(serverLevel, new Vec3(target.getX(), target.getY(), target.getZ()), + owner instanceof LivingEntity livingOwner ? livingOwner : null); } this.dealtDamage = true; diff --git a/common/src/main/java/com/craisinlord/antarchy/content/item/KrakensGraspItem.java b/common/src/main/java/com/craisinlord/antarchy/content/item/KrakensGraspItem.java index 51a44d3d..5d44a35a 100644 --- a/common/src/main/java/com/craisinlord/antarchy/content/item/KrakensGraspItem.java +++ b/common/src/main/java/com/craisinlord/antarchy/content/item/KrakensGraspItem.java @@ -58,11 +58,6 @@ public class KrakensGraspItem extends TridentItem implements GeoItem { .build(); } - @Override - public net.minecraft.world.item.UseAnim getUseAnimation(ItemStack stack) { - return net.minecraft.world.item.UseAnim.NONE; - } - @Override public void inventoryTick(ItemStack stack, Level level, Entity entity, int slotId, boolean isSelected) { super.inventoryTick(stack, level, entity, slotId, isSelected); diff --git a/common/src/main/java/com/craisinlord/antarchy/content/worldgen/elythia/GiantLilyPadPatchFeature.java b/common/src/main/java/com/craisinlord/antarchy/content/worldgen/elythia/GiantLilyPadPatchFeature.java new file mode 100644 index 00000000..ecf972d8 --- /dev/null +++ b/common/src/main/java/com/craisinlord/antarchy/content/worldgen/elythia/GiantLilyPadPatchFeature.java @@ -0,0 +1,101 @@ +package com.craisinlord.antarchy.content.worldgen.elythia; + +import com.craisinlord.antarchy.content.AntarchyObjects; +import com.mojang.serialization.Codec; +import net.minecraft.core.BlockPos; +import net.minecraft.tags.FluidTags; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; + +import java.util.ArrayList; +import java.util.List; + +public final class GiantLilyPadPatchFeature extends Feature { + public GiantLilyPadPatchFeature(Codec codec) { + super(codec); + } + + @Override + public boolean place(FeaturePlaceContext context) { + WorldGenLevel level = context.level(); + RandomSource random = context.random(); + BlockPos origin = context.origin(); + boolean placedAny = false; + + for (int i = 0; i < 12; i++) { + int anchorX = origin.getX() + random.nextInt(17) - 8; + int anchorZ = origin.getZ() + random.nextInt(17) - 8; + int surfaceY = level.getHeight(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, anchorX, anchorZ) - 1; + BlockPos anchorFluidPos = new BlockPos(anchorX, surfaceY, anchorZ); + if (!level.getFluidState(anchorFluidPos).is(FluidTags.WATER) || !level.getFluidState(anchorFluidPos).isSource()) { + continue; + } + + int size = rollFootprintSize(random); + List footprint = new ArrayList<>(size * size); + boolean valid = true; + for (int row = 0; row < size && valid; row++) { + for (int column = 0; column < size; column++) { + BlockPos fluidPos = new BlockPos(anchorX + column, surfaceY, anchorZ + row); + if (!level.getFluidState(fluidPos).is(FluidTags.WATER) || !level.getFluidState(fluidPos).isSource()) { + valid = false; + break; + } + + BlockPos padPos = fluidPos.above(); + if (!level.isEmptyBlock(padPos)) { + valid = false; + break; + } + + footprint.add(padPos); + } + } + + if (!valid) { + continue; + } + + Block giantLilyPad = AntarchyObjects.GIANT_LILY_PAD.get(); + BlockState padState = giantLilyPad.defaultBlockState(); + for (BlockPos padPos : footprint) { + level.setBlock(padPos, padState, Block.UPDATE_ALL); + } + + placedAny = true; + + if (size == 3 && random.nextFloat() < 0.5F) { + BlockPos centerPos = new BlockPos(anchorX + 1, surfaceY, anchorZ + 1).above(); + placeLotus(level, centerPos.above()); + } + } + + return placedAny; + } + + private static int rollFootprintSize(RandomSource random) { + float roll = random.nextFloat(); + if (roll < 0.5F) { + return 1; + } + + return roll < 0.8F ? 2 : 3; + } + + private void placeLotus(WorldGenLevel level, BlockPos pos) { + if (!level.isEmptyBlock(pos)) { + return; + } + + BlockState lotusState = AntarchyObjects.LOTUS.get().defaultBlockState(); + if (lotusState.canSurvive(level, pos)) { + level.setBlock(pos, lotusState, Block.UPDATE_ALL); + } + } +} diff --git a/common/src/main/java/com/craisinlord/antarchy/content/worldgen/ocean/SeashellFeature.java b/common/src/main/java/com/craisinlord/antarchy/content/worldgen/ocean/SeashellFeature.java new file mode 100644 index 00000000..e0a83d83 --- /dev/null +++ b/common/src/main/java/com/craisinlord/antarchy/content/worldgen/ocean/SeashellFeature.java @@ -0,0 +1,65 @@ +package com.craisinlord.antarchy.content.worldgen.ocean; + +import com.craisinlord.antarchy.Antarchy; +import com.craisinlord.antarchy.content.AntarchyObjects; +import com.craisinlord.antarchy.content.block.SeashellBlock; +import com.craisinlord.antarchy.content.block.entity.SeashellBlockEntity; +import com.mojang.serialization.Codec; +import net.minecraft.core.BlockPos; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.storage.loot.LootTable; +import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; + +public final class SeashellFeature extends Feature { + private static final ResourceKey LOOT_TABLE = ResourceKey.create( + Registries.LOOT_TABLE, + ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "chests/seashell") + ); + + public SeashellFeature(Codec codec) { + super(codec); + } + + @Override + public boolean place(FeaturePlaceContext context) { + WorldGenLevel level = context.level(); + RandomSource random = context.random(); + BlockPos origin = context.origin(); + boolean placedAny = false; + + for (int i = 0; i < 8; i++) { + int x = origin.getX() + random.nextInt(17) - 8; + int z = origin.getZ() + random.nextInt(17) - 8; + int floorY = level.getHeight(Heightmap.Types.OCEAN_FLOOR_WG, x, z); + BlockPos shellPos = new BlockPos(x, floorY, z); + + if (!level.getFluidState(shellPos).isSource()) { + continue; + } + + BlockState state = AntarchyObjects.SEASHELL.get().defaultBlockState() + .setValue(SeashellBlock.FACING, net.minecraft.core.Direction.Plane.HORIZONTAL.getRandomDirection(random)) + .setValue(SeashellBlock.WATERLOGGED, true) + .setValue(SeashellBlock.POWERED, false); + if (!state.canSurvive(level, shellPos)) { + continue; + } + + level.setBlock(shellPos, state, 2); + if (level.getBlockEntity(shellPos) instanceof SeashellBlockEntity seashell) { + seashell.setLootTable(LOOT_TABLE, random.nextLong()); + } + placedAny = true; + } + + return placedAny; + } +} diff --git a/common/src/main/resources/assets/antarchy/animations/seashell.animation.json b/common/src/main/resources/assets/antarchy/animations/seashell.animation.json new file mode 100644 index 00000000..c97e7f6b --- /dev/null +++ b/common/src/main/resources/assets/antarchy/animations/seashell.animation.json @@ -0,0 +1,62 @@ +{ + "format_version": "1.8.0", + "animations": { + "close_to_open": { + "loop": "hold_on_last_frame", + "animation_length": 0.375, + "bones": { + "upper_moving": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "0.375": { + "vector": [-90, 0, 0], + "easing": "easeOutBack" + } + } + } + } + }, + "closed": { + "loop": "hold_on_last_frame", + "bones": { + "upper_moving": { + "rotation": { + "vector": [0, 0, 0] + } + } + } + }, + "open_to_close": { + "loop": "hold_on_last_frame", + "animation_length": 0.4167, + "bones": { + "upper_moving": { + "rotation": { + "0.0": { + "vector": [-90, 0, 0], + "easing": "easeOutBack" + }, + "0.4167": { + "vector": [0, 0, 0], + "easing": "easeInOutBack", + "easingArgs": [0.5] + } + } + } + } + }, + "open": { + "loop": "hold_on_last_frame", + "bones": { + "upper_moving": { + "rotation": { + "vector": [-90, 0, 0], + "easing": "easeOutBack" + } + } + } + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/antarchy/blockstates/lotus.json b/common/src/main/resources/assets/antarchy/blockstates/lotus.json new file mode 100644 index 00000000..91b0e7f0 --- /dev/null +++ b/common/src/main/resources/assets/antarchy/blockstates/lotus.json @@ -0,0 +1,6 @@ +{ + "variants": { + "hanging=false": { "model": "antarchy:block/lotus" }, + "hanging=true": { "model": "antarchy:block/lotus", "x": 180 } + } +} diff --git a/common/src/main/resources/assets/antarchy/blockstates/seashell.json b/common/src/main/resources/assets/antarchy/blockstates/seashell.json new file mode 100644 index 00000000..1e35228b --- /dev/null +++ b/common/src/main/resources/assets/antarchy/blockstates/seashell.json @@ -0,0 +1,20 @@ +{ + "variants": { + "facing=north,powered=false,waterlogged=false": { "model": "builtin/entity" }, + "facing=north,powered=false,waterlogged=true": { "model": "builtin/entity" }, + "facing=north,powered=true,waterlogged=false": { "model": "builtin/entity" }, + "facing=north,powered=true,waterlogged=true": { "model": "builtin/entity" }, + "facing=south,powered=false,waterlogged=false": { "model": "builtin/entity" }, + "facing=south,powered=false,waterlogged=true": { "model": "builtin/entity" }, + "facing=south,powered=true,waterlogged=false": { "model": "builtin/entity" }, + "facing=south,powered=true,waterlogged=true": { "model": "builtin/entity" }, + "facing=east,powered=false,waterlogged=false": { "model": "builtin/entity" }, + "facing=east,powered=false,waterlogged=true": { "model": "builtin/entity" }, + "facing=east,powered=true,waterlogged=false": { "model": "builtin/entity" }, + "facing=east,powered=true,waterlogged=true": { "model": "builtin/entity" }, + "facing=west,powered=false,waterlogged=false": { "model": "builtin/entity" }, + "facing=west,powered=false,waterlogged=true": { "model": "builtin/entity" }, + "facing=west,powered=true,waterlogged=false": { "model": "builtin/entity" }, + "facing=west,powered=true,waterlogged=true": { "model": "builtin/entity" } + } +} diff --git a/common/src/main/resources/assets/antarchy/geo/seashell.geo.json b/common/src/main/resources/assets/antarchy/geo/seashell.geo.json new file mode 100644 index 00000000..73910555 --- /dev/null +++ b/common/src/main/resources/assets/antarchy/geo/seashell.geo.json @@ -0,0 +1,173 @@ +{ + "format_version": "1.12.0", + "minecraft:geometry": [ + { + "description": { + "identifier": "geometry.unknown", + "texture_width": 64, + "texture_height": 64, + "visible_bounds_width": 3, + "visible_bounds_height": 2.5, + "visible_bounds_offset": [0, 0.75, 0] + }, + "bones": [ + { + "name": "seashell", + "pivot": [0, 0, 0] + }, + { + "name": "lower", + "parent": "seashell", + "pivot": [0, 0, 0], + "cubes": [ + { + "origin": [-7, 0, -7], + "size": [14, 2, 14], + "uv": { + "north": {"uv": [14, 15], "uv_size": [14, 2]}, + "east": {"uv": [0, 15], "uv_size": [14, 2]}, + "south": {"uv": [42, 15], "uv_size": [14, 2]}, + "west": {"uv": [28, 15], "uv_size": [14, 2]}, + "up": {"uv": [14, 0], "uv_size": [14, 14]}, + "down": {"uv": [28, 14], "uv_size": [14, -14]} + } + }, + { + "origin": [-7, 2, -7], + "size": [14, 1, 1], + "uv": { + "north": {"uv": [14, 14], "uv_size": [14, 1]}, + "east": {"uv": [13, 14], "uv_size": [1, 1]}, + "south": {"uv": [42, 14], "uv_size": [14, 1]}, + "west": {"uv": [28, 14], "uv_size": [1, 1]}, + "up": {"uv": [14, 0], "uv_size": [14, 1]}, + "down": {"uv": [28, 14], "uv_size": [14, -14]} + } + }, + { + "origin": [-7, 2, -6], + "size": [1, 1, 12], + "uv": { + "north": {"uv": [14, 14], "uv_size": [14, 1]}, + "east": {"uv": [1, 14], "uv_size": [12, 1]}, + "south": {"uv": [42, 14], "uv_size": [14, 1]}, + "west": {"uv": [29, 14], "uv_size": [12, 1]}, + "up": {"uv": [14, 1], "uv_size": [1, 12]}, + "down": {"uv": [28, 14], "uv_size": [14, -14]} + } + }, + { + "origin": [6, 2, -6], + "size": [1, 1, 12], + "uv": { + "north": {"uv": [14, 14], "uv_size": [14, 1]}, + "east": {"uv": [1, 14], "uv_size": [12, 1]}, + "south": {"uv": [42, 14], "uv_size": [14, 1]}, + "west": {"uv": [29, 14], "uv_size": [12, 1]}, + "up": {"uv": [27, 1], "uv_size": [1, 12]}, + "down": {"uv": [28, 14], "uv_size": [14, -14]} + } + }, + { + "origin": [-7, 2, 6], + "size": [14, 1, 1], + "uv": { + "north": {"uv": [14, 14], "uv_size": [14, 1]}, + "east": {"uv": [13, 14], "uv_size": [1, 1]}, + "south": {"uv": [42, 14], "uv_size": [14, 1]}, + "west": {"uv": [28, 14], "uv_size": [1, 1]}, + "up": {"uv": [14, 0], "uv_size": [14, 1]}, + "down": {"uv": [28, 14], "uv_size": [14, -14]} + } + } + ] + }, + { + "name": "upper_moving", + "parent": "seashell", + "pivot": [0, 2.5, 7], + "cubes": [ + { + "origin": [-2, 1.5, 7], + "size": [4, 2, 1], + "inflate": 0.01, + "uv": { + "north": {"uv": [2, 34], "uv_size": [4, 2]}, + "east": {"uv": [1, 34], "uv_size": [1, 2]}, + "south": {"uv": [7, 34], "uv_size": [4, 2]}, + "west": {"uv": [6, 34], "uv_size": [1, 2]}, + "up": {"uv": [2, 33], "uv_size": [4, 1]}, + "down": {"uv": [6, 34], "uv_size": [4, -1]} + } + }, + { + "origin": [-7, 3.5, -7], + "size": [14, 1, 14], + "inflate": 0.01, + "uv": { + "north": {"uv": [14, 31], "uv_size": [14, 1]}, + "east": {"uv": [0, 31], "uv_size": [14, 1]}, + "south": {"uv": [42, 31], "uv_size": [14, 1]}, + "west": {"uv": [28, 31], "uv_size": [14, 1]}, + "up": {"uv": [14, 17], "uv_size": [14, 14]}, + "down": {"uv": [28, 31], "uv_size": [14, -14]} + } + }, + { + "origin": [-7, 2.5, 6], + "size": [14, 1, 1], + "inflate": 0.01, + "uv": { + "north": {"uv": [14, 14], "uv_size": [14, 1]}, + "east": {"uv": [13, 14], "uv_size": [1, 1]}, + "south": {"uv": [42, 14], "uv_size": [14, 1]}, + "west": {"uv": [28, 14], "uv_size": [1, 1]}, + "up": {"uv": [14, 0], "uv_size": [14, 1]}, + "down": {"uv": [28, 1], "uv_size": [14, -1]} + } + }, + { + "origin": [6, 2.5, -6], + "size": [1, 1, 12], + "inflate": 0.01, + "uv": { + "north": {"uv": [14, 14], "uv_size": [14, 1]}, + "east": {"uv": [1, 14], "uv_size": [12, 1]}, + "south": {"uv": [42, 14], "uv_size": [14, 1]}, + "west": {"uv": [29, 32], "uv_size": [12, 1]}, + "up": {"uv": [27, 1], "uv_size": [1, 12]}, + "down": {"uv": [41, 13], "uv_size": [1, -12]} + } + }, + { + "origin": [-7, 2.5, -7], + "size": [14, 1, 1], + "inflate": 0.01, + "uv": { + "north": {"uv": [14, 32], "uv_size": [14, 1]}, + "east": {"uv": [13, 14], "uv_size": [1, 1]}, + "south": {"uv": [42, 32], "uv_size": [14, 1]}, + "west": {"uv": [28, 32], "uv_size": [1, 1]}, + "up": {"uv": [14, 0], "uv_size": [14, 1]}, + "down": {"uv": [28, 1], "uv_size": [14, -1]} + } + }, + { + "origin": [-7, 2.5, -6], + "size": [1, 1, 12], + "inflate": 0.01, + "uv": { + "north": {"uv": [14, 14], "uv_size": [14, 1]}, + "east": {"uv": [1, 32], "uv_size": [12, 1]}, + "south": {"uv": [42, 14], "uv_size": [14, 1]}, + "west": {"uv": [29, 14], "uv_size": [12, 1]}, + "up": {"uv": [14, 1], "uv_size": [1, 12]}, + "down": {"uv": [28, 13], "uv_size": [1, -12]} + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/common/src/main/resources/assets/antarchy/lang/en_us.json b/common/src/main/resources/assets/antarchy/lang/en_us.json index c340bff9..55597be8 100644 --- a/common/src/main/resources/assets/antarchy/lang/en_us.json +++ b/common/src/main/resources/assets/antarchy/lang/en_us.json @@ -41,7 +41,10 @@ "block.antarchy.pink_milkweed": "Pink Milkweed", "block.antarchy.camellia": "Camellia", "block.antarchy.spider_lily": "Spider Lily", + "block.antarchy.lotus": "Lotus", + "item.antarchy.lotus": "Lotus", "block.antarchy.giant_lily_pad": "Giant Lily Pad", + "block.antarchy.seashell": "Seashell", "block.antarchy.hushweed": "Hushweed", "block.antarchy.umbral_moss_block": "Umbral Moss Block", "block.antarchy.umbral_moss_carpet": "Umbral Moss Carpet", @@ -233,6 +236,7 @@ "item.antarchy.dream_lantern": "Dream Lantern", "item.antarchy.dream_campfire": "Dream Campfire", "item.antarchy.giant_lily_pad": "Giant Lily Pad", + "item.antarchy.seashell": "Seashell", "item.antarchy.nightmare_scale": "Nightmare Scale", "item.antarchy.nightmare_helmet": "Nightmare Helmet", "item.antarchy.nightmare_chestplate": "Nightmare Chestplate", diff --git a/common/src/main/resources/assets/antarchy/models/block/lotus.json b/common/src/main/resources/assets/antarchy/models/block/lotus.json new file mode 100644 index 00000000..a1b802d2 --- /dev/null +++ b/common/src/main/resources/assets/antarchy/models/block/lotus.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cross", + "textures": { + "cross": "antarchy:block/lotus" + } +} diff --git a/common/src/main/resources/assets/antarchy/models/item/cheep.json b/common/src/main/resources/assets/antarchy/models/item/cheep.json new file mode 100644 index 00000000..4429a18f --- /dev/null +++ b/common/src/main/resources/assets/antarchy/models/item/cheep.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "antarchy:item/cheep" + } +} diff --git a/common/src/main/resources/assets/antarchy/models/item/lotus.json b/common/src/main/resources/assets/antarchy/models/item/lotus.json new file mode 100644 index 00000000..2e3e72b7 --- /dev/null +++ b/common/src/main/resources/assets/antarchy/models/item/lotus.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "antarchy:block/lotus" + } +} diff --git a/common/src/main/resources/assets/antarchy/models/item/seashell.json b/common/src/main/resources/assets/antarchy/models/item/seashell.json new file mode 100644 index 00000000..48b6692a --- /dev/null +++ b/common/src/main/resources/assets/antarchy/models/item/seashell.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "antarchy:block/seashell" + } +} diff --git a/common/src/main/resources/assets/antarchy/textures/block/seashell.png b/common/src/main/resources/assets/antarchy/textures/block/seashell.png new file mode 100644 index 00000000..4c957b83 Binary files /dev/null and b/common/src/main/resources/assets/antarchy/textures/block/seashell.png differ diff --git a/common/src/main/resources/data/antarchy/loot_table/blocks/lotus.json b/common/src/main/resources/data/antarchy/loot_table/blocks/lotus.json new file mode 100644 index 00000000..2c7f5cb8 --- /dev/null +++ b/common/src/main/resources/data/antarchy/loot_table/blocks/lotus.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1.0, + "conditions": [ + { "condition": "minecraft:survives_explosion" } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "antarchy:lotus" + } + ] + } + ], + "random_sequence": "antarchy:blocks/lotus" +} diff --git a/common/src/main/resources/data/antarchy/loot_table/blocks/seashell.json b/common/src/main/resources/data/antarchy/loot_table/blocks/seashell.json new file mode 100644 index 00000000..da9adf20 --- /dev/null +++ b/common/src/main/resources/data/antarchy/loot_table/blocks/seashell.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "antarchy:seashell" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} diff --git a/common/src/main/resources/data/antarchy/loot_table/chests/seashell.json b/common/src/main/resources/data/antarchy/loot_table/chests/seashell.json new file mode 100644 index 00000000..047f84e5 --- /dev/null +++ b/common/src/main/resources/data/antarchy/loot_table/chests/seashell.json @@ -0,0 +1,23 @@ +{ + "type": "minecraft:chest", + "pools": [ + { + "rolls": { + "type": "minecraft:uniform", + "min": 2, + "max": 5 + }, + "entries": [ + { "type": "minecraft:item", "name": "minecraft:nautilus_shell", "weight": 8 }, + { "type": "minecraft:item", "name": "minecraft:prismarine_shard", "weight": 10 }, + { "type": "minecraft:item", "name": "minecraft:prismarine_crystals", "weight": 8 }, + { "type": "minecraft:item", "name": "minecraft:kelp", "weight": 12 }, + { "type": "minecraft:item", "name": "minecraft:seagrass", "weight": 10 }, + { "type": "minecraft:item", "name": "minecraft:tropical_fish", "weight": 4 }, + { "type": "minecraft:item", "name": "minecraft:bone_meal", "weight": 8 }, + { "type": "minecraft:item", "name": "antarchy:star_coral", "weight": 3 }, + { "type": "minecraft:item", "name": "antarchy:giant_lily_pad", "weight": 1 } + ] + } + ] +} diff --git a/common/src/main/resources/data/antarchy/loot_table/entities/cheep.json b/common/src/main/resources/data/antarchy/loot_table/entities/cheep.json index 9c830ca5..ea3b5bba 100644 --- a/common/src/main/resources/data/antarchy/loot_table/entities/cheep.json +++ b/common/src/main/resources/data/antarchy/loot_table/entities/cheep.json @@ -1,5 +1,15 @@ { "type": "minecraft:entity", - "pools": [], + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "antarchy:cheep" + } + ] + } + ], "random_sequence": "antarchy:entities/cheep" } diff --git a/common/src/main/resources/data/antarchy/recipe/pink_dye_from_lotus.json b/common/src/main/resources/data/antarchy/recipe/pink_dye_from_lotus.json new file mode 100644 index 00000000..e3a7b1a3 --- /dev/null +++ b/common/src/main/resources/data/antarchy/recipe/pink_dye_from_lotus.json @@ -0,0 +1,11 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "ingredients": [ + { "item": "antarchy:lotus" } + ], + "result": { + "count": 2, + "id": "minecraft:pink_dye" + } +} diff --git a/common/src/main/resources/data/antarchy/tags/worldgen/biome/has_seashell.json b/common/src/main/resources/data/antarchy/tags/worldgen/biome/has_seashell.json new file mode 100644 index 00000000..d70e35cc --- /dev/null +++ b/common/src/main/resources/data/antarchy/tags/worldgen/biome/has_seashell.json @@ -0,0 +1,14 @@ +{ + "replace": false, + "values": [ + "#minecraft:is_ocean", + { + "id": "#neoforge:is_ocean", + "required": false + }, + { + "id": "#c:ocean", + "required": false + } + ] +} diff --git a/common/src/main/resources/data/antarchy/worldgen/biome/elythia_ocean.json b/common/src/main/resources/data/antarchy/worldgen/biome/elythia_ocean.json index da24502b..95764482 100644 --- a/common/src/main/resources/data/antarchy/worldgen/biome/elythia_ocean.json +++ b/common/src/main/resources/data/antarchy/worldgen/biome/elythia_ocean.json @@ -54,7 +54,8 @@ [ "minecraft:sea_pickle", "minecraft:warm_ocean_vegetation", - "minecraft:kelp_warm" + "minecraft:kelp_warm", + "antarchy:giant_lily_pad_patch" ], [] ], diff --git a/common/src/main/resources/data/antarchy/worldgen/biome/elythia_river.json b/common/src/main/resources/data/antarchy/worldgen/biome/elythia_river.json index 8b8caa79..b31c4bd8 100644 --- a/common/src/main/resources/data/antarchy/worldgen/biome/elythia_river.json +++ b/common/src/main/resources/data/antarchy/worldgen/biome/elythia_river.json @@ -55,7 +55,8 @@ [], [ "antarchy:elythia_meadow_flora", - "minecraft:patch_sugar_cane" + "minecraft:patch_sugar_cane", + "antarchy:giant_lily_pad_patch" ], [] ], diff --git a/common/src/main/resources/data/antarchy/worldgen/configured_feature/giant_lily_pad_patch.json b/common/src/main/resources/data/antarchy/worldgen/configured_feature/giant_lily_pad_patch.json new file mode 100644 index 00000000..5188ad45 --- /dev/null +++ b/common/src/main/resources/data/antarchy/worldgen/configured_feature/giant_lily_pad_patch.json @@ -0,0 +1,4 @@ +{ + "type": "antarchy:giant_lily_pad_patch", + "config": {} +} diff --git a/common/src/main/resources/data/antarchy/worldgen/configured_feature/seashell_patch.json b/common/src/main/resources/data/antarchy/worldgen/configured_feature/seashell_patch.json new file mode 100644 index 00000000..c9987613 --- /dev/null +++ b/common/src/main/resources/data/antarchy/worldgen/configured_feature/seashell_patch.json @@ -0,0 +1,4 @@ +{ + "type": "antarchy:seashell_patch", + "config": {} +} diff --git a/common/src/main/resources/data/antarchy/worldgen/placed_feature/giant_lily_pad_patch.json b/common/src/main/resources/data/antarchy/worldgen/placed_feature/giant_lily_pad_patch.json new file mode 100644 index 00000000..b1b0dd8d --- /dev/null +++ b/common/src/main/resources/data/antarchy/worldgen/placed_feature/giant_lily_pad_patch.json @@ -0,0 +1,9 @@ +{ + "feature": "antarchy:giant_lily_pad_patch", + "placement": [ + { "type": "minecraft:rarity_filter", "chance": 6 }, + { "type": "minecraft:in_square" }, + { "type": "minecraft:heightmap", "heightmap": "MOTION_BLOCKING_NO_LEAVES" }, + { "type": "minecraft:biome" } + ] +} diff --git a/common/src/main/resources/data/antarchy/worldgen/placed_feature/seashell_patch.json b/common/src/main/resources/data/antarchy/worldgen/placed_feature/seashell_patch.json new file mode 100644 index 00000000..d51c19d1 --- /dev/null +++ b/common/src/main/resources/data/antarchy/worldgen/placed_feature/seashell_patch.json @@ -0,0 +1,19 @@ +{ + "feature": "antarchy:seashell_patch", + "placement": [ + { + "type": "minecraft:rarity_filter", + "chance": 10 + }, + { + "type": "minecraft:in_square" + }, + { + "type": "minecraft:heightmap", + "heightmap": "OCEAN_FLOOR_WG" + }, + { + "type": "minecraft:biome" + } + ] +} diff --git a/common/src/main/resources/data/minecraft/tags/block/flowers.json b/common/src/main/resources/data/minecraft/tags/block/flowers.json index 14c5c999..d794cdec 100644 --- a/common/src/main/resources/data/minecraft/tags/block/flowers.json +++ b/common/src/main/resources/data/minecraft/tags/block/flowers.json @@ -2,6 +2,7 @@ "replace": false, "values": [ "antarchy:camellia", + "antarchy:lotus", "antarchy:orange_milkweed", "antarchy:pink_milkweed", "antarchy:spider_lily" diff --git a/common/src/main/resources/data/minecraft/tags/block/small_flowers.json b/common/src/main/resources/data/minecraft/tags/block/small_flowers.json index b41d7661..ae42e249 100644 --- a/common/src/main/resources/data/minecraft/tags/block/small_flowers.json +++ b/common/src/main/resources/data/minecraft/tags/block/small_flowers.json @@ -1,6 +1,7 @@ { "replace": false, "values": [ + "antarchy:lotus", "antarchy:spider_lily" ] } diff --git a/common/src/main/resources/data/minecraft/tags/item/fishes.json b/common/src/main/resources/data/minecraft/tags/item/fishes.json new file mode 100644 index 00000000..12df0487 --- /dev/null +++ b/common/src/main/resources/data/minecraft/tags/item/fishes.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "antarchy:cheep" + ] +} diff --git a/common/src/main/resources/data/minecraft/tags/item/flowers.json b/common/src/main/resources/data/minecraft/tags/item/flowers.json index 14c5c999..d794cdec 100644 --- a/common/src/main/resources/data/minecraft/tags/item/flowers.json +++ b/common/src/main/resources/data/minecraft/tags/item/flowers.json @@ -2,6 +2,7 @@ "replace": false, "values": [ "antarchy:camellia", + "antarchy:lotus", "antarchy:orange_milkweed", "antarchy:pink_milkweed", "antarchy:spider_lily" diff --git a/common/src/main/resources/data/minecraft/tags/item/small_flowers.json b/common/src/main/resources/data/minecraft/tags/item/small_flowers.json index b41d7661..ae42e249 100644 --- a/common/src/main/resources/data/minecraft/tags/item/small_flowers.json +++ b/common/src/main/resources/data/minecraft/tags/item/small_flowers.json @@ -1,6 +1,7 @@ { "replace": false, "values": [ + "antarchy:lotus", "antarchy:spider_lily" ] } diff --git a/fabric/src/main/java/com/craisinlord/antarchy/fabric/AntarchyFabric.java b/fabric/src/main/java/com/craisinlord/antarchy/fabric/AntarchyFabric.java index f3d23fb8..88330f92 100644 --- a/fabric/src/main/java/com/craisinlord/antarchy/fabric/AntarchyFabric.java +++ b/fabric/src/main/java/com/craisinlord/antarchy/fabric/AntarchyFabric.java @@ -115,6 +115,14 @@ public final class AntarchyFabric implements ModInitializer { Registries.PLACED_FEATURE, ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "star_coral_patch") ); + private static final TagKey HAS_SEASHELL = TagKey.create( + Registries.BIOME, + ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "has_seashell") + ); + private static final ResourceKey SEASHELL_PATCH = ResourceKey.create( + Registries.PLACED_FEATURE, + ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "seashell_patch") + ); @Override public void onInitialize() { AntarchyFabricNetworking.register(); @@ -218,6 +226,11 @@ public final class AntarchyFabric implements ModInitializer { GenerationStep.Decoration.VEGETAL_DECORATION, STAR_CORAL_PATCH ); + BiomeModifications.addFeature( + BiomeSelectors.tag(HAS_SEASHELL), + GenerationStep.Decoration.VEGETAL_DECORATION, + SEASHELL_PATCH + ); BiomeModifications.addSpawn( BiomeSelectors.tag(APPLE_COW_SPAWN_BIOMES), net.minecraft.world.entity.MobCategory.CREATURE, diff --git a/fabric/src/main/java/com/craisinlord/antarchy/fabric/AntarchyFabricContent.java b/fabric/src/main/java/com/craisinlord/antarchy/fabric/AntarchyFabricContent.java index 480bcd53..dce90ea2 100644 --- a/fabric/src/main/java/com/craisinlord/antarchy/fabric/AntarchyFabricContent.java +++ b/fabric/src/main/java/com/craisinlord/antarchy/fabric/AntarchyFabricContent.java @@ -258,6 +258,7 @@ public final class AntarchyFabricContent { AntarchyObjects.setOctopusBomb(AntarchyFabricEntities.OCTOPUS_BOMB); AntarchyObjects.setTentacle(AntarchyFabricEntities.TENTACLE); AntarchyObjects.setKrakensGraspTrident(AntarchyFabricEntities.KRAKENS_GRASP_TRIDENT); + AntarchyObjects.setLotus(() -> AntarchyFabricBlocks.LOTUS.get()); AntarchyObjects.setKrakenTentacle(() -> AntarchyFabricItems.KRAKEN_TENTACLE.get()); AntarchyObjects.setKrakensGrasp(() -> AntarchyFabricItems.KRAKENS_GRASP.get()); AntarchyObjects.setOuranwoodDeer(AntarchyFabricEntities.OURANWOOD_DEER); @@ -281,7 +282,7 @@ public final class AntarchyFabricContent { AntarchyObjects.setLumenBlock(() -> AntarchyFabricBlocks.LUMEN_BLOCK.get()); AntarchyObjects.setLumenFroglight(() -> AntarchyFabricBlocks.LUMEN_FROGLIGHT.get()); AntarchyObjects.setPeachLeavesParticle(() -> AntarchyFabricMisc.PEACH_LEAVES_PARTICLE.get()); - // AntarchyObjects.setDorrieInventoryMenu(AntarchyFabricMisc.DORRIE_INVENTORY_MENU); + AntarchyObjects.setDorrieInventoryMenu(AntarchyFabricMisc.DORRIE_INVENTORY_MENU); AntarchyObjects.bind( AntarchyFabricEntities.EASTER_BUNNY, AntarchyFabricEntities.FLYING_SQUIRREL, @@ -306,7 +307,7 @@ public final class AntarchyFabricContent { (java.util.function.Supplier) AntarchyFabricEntities.BOMBER, (java.util.function.Supplier) AntarchyFabricEntities.BED_BUG, AntarchyFabricEntities.CHEEP, - () -> { throw new IllegalStateException("Dorrie is not part of this update yet."); }, + AntarchyFabricEntities.DORRIE, () -> AntarchyFabricBlocks.DUPLICATOR_LOG.get(), () -> AntarchyFabricBlocks.DUPLICATOR_SAPLING.get(), () -> AntarchyFabricBlocks.DUCT_TAPE.get(), @@ -371,10 +372,12 @@ public final class AntarchyFabricContent { () -> AntarchyFabricBlocks.OURANWOOD_SQUIRREL_NEST.get(), () -> AntarchyFabricBlocks.BRUTALFLY_COCOON_SPAWNER.get(), () -> AntarchyFabricBlocks.GIANT_LILY_PAD.get(), + () -> AntarchyFabricBlocks.SEASHELL.get(), () -> AntarchyFabricBlocks.ANT_NEST_BLOCK_ENTITY.get(), () -> AntarchyFabricBlocks.DREAM_CAMPFIRE_BLOCK_ENTITY.get(), () -> AntarchyFabricBlocks.WASP_NEST_BLOCK_ENTITY.get(), () -> AntarchyFabricBlocks.HUSHWEED_BLOCK_ENTITY.get(), + () -> AntarchyFabricBlocks.SEASHELL_BLOCK_ENTITY.get(), () -> AntarchyFabricMisc.STINKY_GAS.get(), () -> AntarchyFabricMisc.STINKY_FLY.get(), () -> AntarchyFabricMisc.PEACH_LEAVES_PARTICLE.get(), diff --git a/fabric/src/main/java/com/craisinlord/antarchy/fabric/client/AntarchyFabricClientBootstrap.java b/fabric/src/main/java/com/craisinlord/antarchy/fabric/client/AntarchyFabricClientBootstrap.java index 61b2ff3b..92cfcbe7 100644 --- a/fabric/src/main/java/com/craisinlord/antarchy/fabric/client/AntarchyFabricClientBootstrap.java +++ b/fabric/src/main/java/com/craisinlord/antarchy/fabric/client/AntarchyFabricClientBootstrap.java @@ -72,6 +72,10 @@ public final class AntarchyFabricClientBootstrap { (net.minecraft.world.level.block.entity.BlockEntityType) AntarchyFabricBlocks.DREAM_CAMPFIRE_BLOCK_ENTITY.get(), (BlockEntityRendererProvider) CampfireRenderer::new ); + BlockEntityRendererRegistry.register( + (net.minecraft.world.level.block.entity.BlockEntityType) AntarchyFabricBlocks.SEASHELL_BLOCK_ENTITY.get(), + (BlockEntityRendererProvider) SeashellRenderer::new + ); EntityRendererRegistry.register(AntarchyFabricEntities.EASTER_BUNNY.get(), EasterBunnyRenderer::new); EntityRendererRegistry.register(AntarchyFabricEntities.FLYING_SQUIRREL.get(), FlyingSquirrelRenderer::new); @@ -100,7 +104,7 @@ public final class AntarchyFabricClientBootstrap { EntityRendererRegistry.register(AntarchyFabricEntities.KRAKEN.get(), KrakenRenderer::new); EntityRendererRegistry.register(AntarchyFabricEntities.KRAKEN_PART.get(), MultipartPartRenderer::new); EntityRendererRegistry.register(AntarchyFabricEntities.TENTACLE.get(), com.craisinlord.antarchy.content.client.renderer.TentacleRenderer::new); - EntityRendererRegistry.register(AntarchyFabricEntities.KRAKENS_GRASP_TRIDENT.get(), ThrownItemRenderer::new); + EntityRendererRegistry.register(AntarchyFabricEntities.KRAKENS_GRASP_TRIDENT.get(), com.craisinlord.antarchy.content.client.renderer.KrakensGraspThrownTridentRenderer::new); EntityRendererRegistry.register(AntarchyFabricEntities.MISSILE_SQUID.get(), MissileSquidRenderer::new); EntityRendererRegistry.register(AntarchyFabricEntities.OCTOPUS_BOMB.get(), OctopusBombRenderer::new); EntityRendererRegistry.register(AntarchyFabricEntities.NIGHTMARE.get(), NightmareRenderer::new); @@ -113,7 +117,6 @@ public final class AntarchyFabricClientBootstrap { EntityRendererRegistry.register(AntarchyFabricEntities.GROWTH_RAY_PROJECTILE.get(), SizeRayProjectileRenderer::new); EntityRendererRegistry.register(AntarchyFabricEntities.LUCID_BOLT.get(), LucidBoltRenderer::new); EntityRendererRegistry.register(AntarchyFabricEntities.LUCID_PEARL_PROJECTILE.get(), ThrownItemRenderer::new); - EntityRendererRegistry.register(AntarchyFabricEntities.KRAKENS_GRASP_TRIDENT.get(), ThrownItemRenderer::new); EntityRendererRegistry.register(AntarchyFabricEntities.HUSH_PROJECTILE.get(), HushProjectileRenderer::new); EntityRendererRegistry.register(AntarchyFabricEntities.BRUTALFLY_ORB.get(), BrutalflyOrbRenderer::new); EntityRendererRegistry.register(AntarchyFabricEntities.UPWARD_FALLING_BLOCK.get(), UpwardFallingBlockRenderer::new); @@ -122,8 +125,7 @@ public final class AntarchyFabricClientBootstrap { EntityRendererRegistry.register(AntarchyFabricEntities.TORETERROR.get(), ToreterrorRenderer::new); EntityRendererRegistry.register(AntarchyFabricEntities.WATER_BOMB.get(), WaterBombRenderer::new); EntityRendererRegistry.register(AntarchyFabricEntities.CHEEP.get(), com.craisinlord.antarchy.content.client.renderer.CheepRenderer::new); - // Dorrie is not part of this update yet. - // EntityRendererRegistry.register(AntarchyFabricEntities.DORRIE.get(), com.craisinlord.antarchy.content.client.renderer.DorrieRenderer::new); + EntityRendererRegistry.register(AntarchyFabricEntities.DORRIE.get(), com.craisinlord.antarchy.content.client.renderer.DorrieRenderer::new); EntityRendererRegistry.register(AntarchyFabricEntities.OURANWOOD_DEER.get(), com.craisinlord.antarchy.content.client.renderer.OuranwoodDeerRenderer::new); EntityRendererRegistry.register(AntarchyFabricEntities.GLIMMER.get(), com.craisinlord.antarchy.content.client.renderer.glimmer.GlimmerRenderer::new); EntityRendererRegistry.register(AntarchyFabricEntities.ELKA.get(), com.craisinlord.antarchy.content.client.renderer.ElkaRenderer::new); @@ -252,6 +254,7 @@ public final class AntarchyFabricClientBootstrap { BlockRenderLayerMap.INSTANCE.putBlock(AntarchyFabricBlocks.PINK_MILKWEED.get(), RenderType.cutout()); BlockRenderLayerMap.INSTANCE.putBlock(AntarchyFabricBlocks.CAMELLIA.get(), RenderType.cutout()); BlockRenderLayerMap.INSTANCE.putBlock(AntarchyFabricBlocks.SPIDER_LILY.get(), RenderType.cutout()); + BlockRenderLayerMap.INSTANCE.putBlock(AntarchyFabricBlocks.LOTUS.get(), RenderType.cutout()); BlockRenderLayerMap.INSTANCE.putBlock(AntarchyFabricBlocks.GIANT_LILY_PAD.get(), RenderType.cutout()); BlockRenderLayerMap.INSTANCE.putBlock(AntarchyFabricBlocks.HUSHWEED.get(), RenderType.cutout()); BlockRenderLayerMap.INSTANCE.putBlock(AntarchyFabricBlocks.CORNEA_STALK.get(), RenderType.cutout()); diff --git a/fabric/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricBlocks.java b/fabric/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricBlocks.java index e241c595..2f0dc719 100644 --- a/fabric/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricBlocks.java +++ b/fabric/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricBlocks.java @@ -16,6 +16,7 @@ import com.craisinlord.antarchy.content.block.entity.AntNestBlockEntity; import com.craisinlord.antarchy.content.block.entity.DreamCampfireBlockEntity; import com.craisinlord.antarchy.content.block.entity.HushweedBlockEntity; import com.craisinlord.antarchy.content.block.entity.PotentNyxiteBlockEntity; +import com.craisinlord.antarchy.content.block.entity.SeashellBlockEntity; import com.craisinlord.antarchy.content.block.entity.WaspNestBlockEntity; import com.craisinlord.antarchy.content.fluid.BileLiquidBlock; import com.craisinlord.antarchy.content.fluid.LumenLiquidBlock; @@ -353,6 +354,10 @@ public final class AntarchyFabricBlocks { public static final DeferredBlock GIANT_LILY_PAD = BLOCKS.register("giant_lily_pad", () -> new GiantLilyPadBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.LILY_PAD))); + public static final DeferredBlock LOTUS = BLOCKS.register("lotus", + () -> new com.craisinlord.antarchy.content.block.LotusBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.SPORE_BLOSSOM))); + public static final DeferredBlock SEASHELL = BLOCKS.register("seashell", + () -> new SeashellBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.TURTLE_EGG).noOcclusion())); public static final DeferredBlock OURANWOOD_SIGN = BLOCKS.register("ouranwood_sign", @@ -1008,6 +1013,11 @@ public final class AntarchyFabricBlocks { (pos, state) -> new PotentNyxiteBlockEntity(pos, state, AntarchyFabricBlocks::potentNyxiteBlockEntityType), POTENT_NYXITE.get() ).build(null)); + public static final DeferredHolder, BlockEntityType> SEASHELL_BLOCK_ENTITY = BLOCK_ENTITY_TYPES.register("seashell", + () -> BlockEntityType.Builder.of( + SeashellBlockEntity::new, + SEASHELL.get() + ).build(null)); @@ -1027,6 +1037,10 @@ public final class AntarchyFabricBlocks { return POTENT_NYXITE_BLOCK_ENTITY.get(); } + private static BlockEntityType seashellBlockEntityType() { + return SEASHELL_BLOCK_ENTITY.get(); + } + private static Block smallBloodCrystalBudBlock() { diff --git a/fabric/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricEntities.java b/fabric/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricEntities.java index f1f948e8..8b54c6e4 100644 --- a/fabric/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricEntities.java +++ b/fabric/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricEntities.java @@ -598,12 +598,11 @@ public final class AntarchyFabricEntities { - // Dorrie is not part of this update yet. - // public static final DeferredHolder, EntityType> DORRIE = ENTITY_TYPES.register("dorrie", - // () -> EntityType.Builder.of(com.craisinlord.antarchy.content.entity.DorrieEntity::new, MobCategory.CREATURE) - // .sized(1.6F, 1.4F) - // .clientTrackingRange(10) - // .build("dorrie")); + public static final DeferredHolder, EntityType> DORRIE = ENTITY_TYPES.register("dorrie", + () -> EntityType.Builder.of(com.craisinlord.antarchy.content.entity.DorrieEntity::new, MobCategory.CREATURE) + .sized(1.6F, 1.4F) + .clientTrackingRange(10) + .build("dorrie")); public static final DeferredHolder, EntityType> OURANWOOD_DEER = ENTITY_TYPES.register("ouranwood_deer", diff --git a/fabric/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricEntityAttributes.java b/fabric/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricEntityAttributes.java index 1c82accb..078d9ee0 100644 --- a/fabric/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricEntityAttributes.java +++ b/fabric/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricEntityAttributes.java @@ -307,8 +307,7 @@ public final class AntarchyFabricEntityAttributes { FabricDefaultAttributeRegistry.register(AntarchyFabricEntities.EMPEROR_SCORPION.get(), EmperorScorpionEntity.createAttributes().build()); FabricDefaultAttributeRegistry.register(AntarchyFabricEntities.TORETERROR.get(), ToreterrorEntity.createAttributes().build()); FabricDefaultAttributeRegistry.register(AntarchyFabricEntities.CHEEP.get(), com.craisinlord.antarchy.content.entity.CheepEntity.createAttributes().build()); - // Dorrie is not part of this update yet. - // FabricDefaultAttributeRegistry.register(AntarchyFabricEntities.DORRIE.get(), com.craisinlord.antarchy.content.entity.DorrieEntity.createAttributes().build()); + FabricDefaultAttributeRegistry.register(AntarchyFabricEntities.DORRIE.get(), com.craisinlord.antarchy.content.entity.DorrieEntity.createAttributes().build()); FabricDefaultAttributeRegistry.register(AntarchyFabricEntities.OURANWOOD_DEER.get(), com.craisinlord.antarchy.content.entity.OuranwoodDeerEntity.createAttributes().build()); FabricDefaultAttributeRegistry.register(AntarchyFabricEntities.GLIMMER.get(), com.craisinlord.antarchy.content.entity.glimmer.GlimmerEntity.createAttributes().build()); FabricDefaultAttributeRegistry.register(AntarchyFabricEntities.ELKA.get(), com.craisinlord.antarchy.content.entity.ElkaEntity.createAttributes().build()); diff --git a/fabric/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricItems.java b/fabric/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricItems.java index a7e9409d..abacab8e 100644 --- a/fabric/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricItems.java +++ b/fabric/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricItems.java @@ -403,6 +403,8 @@ public final class AntarchyFabricItems { public static final DeferredItem GIANT_LILY_PAD_ITEM = ITEMS.register("giant_lily_pad", () -> new PlaceOnWaterBlockItem(AntarchyFabricBlocks.GIANT_LILY_PAD.get(), new Item.Properties())); + public static final DeferredItem SEASHELL_ITEM = ITEMS.registerSimpleBlockItem(AntarchyFabricBlocks.SEASHELL); + public static final DeferredItem LOTUS_ITEM = ITEMS.registerSimpleBlockItem(AntarchyFabricBlocks.LOTUS); public static final DeferredItem OURANWOOD_SIGN_ITEM = ITEMS.register("ouranwood_sign", @@ -1472,10 +1474,15 @@ public final class AntarchyFabricItems { public static final DeferredItem CHEEP_SPAWN_EGG = ITEMS.register("cheep_spawn_egg", () -> new DeferredSpawnEggItem(AntarchyFabricEntities.CHEEP, 0xFF00AA, 0x00FF44, new Item.Properties())); + public static final DeferredItem CHEEP_ITEM = ITEMS.register("cheep", + () -> new Item(new Item.Properties() + .food(new net.minecraft.world.food.FoodProperties.Builder() + .nutrition(2) + .saturationModifier(0.1F) + .build()))); - // Dorrie is not part of this update yet. - // public static final DeferredItem DORRIE_SPAWN_EGG = ITEMS.register("dorrie_spawn_egg", - // () -> new DeferredSpawnEggItem(AntarchyFabricEntities.DORRIE, 0x6F8CFF, 0xD2F2FF, new Item.Properties())); + public static final DeferredItem DORRIE_SPAWN_EGG = ITEMS.register("dorrie_spawn_egg", + () -> new DeferredSpawnEggItem(AntarchyFabricEntities.DORRIE, 0x6F8CFF, 0xD2F2FF, new Item.Properties())); public static final DeferredItem OURANWOOD_DEER_SPAWN_EGG = ITEMS.register("ouranwood_deer_spawn_egg", diff --git a/fabric/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricMisc.java b/fabric/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricMisc.java index c6b3bf88..eb204364 100644 --- a/fabric/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricMisc.java +++ b/fabric/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricMisc.java @@ -26,6 +26,7 @@ import com.craisinlord.antarchy.content.worldgen.cavaryn.CavarynBileCystFeature; import com.craisinlord.antarchy.content.worldgen.cavaryn.CavarynBileVeinFeature; import com.craisinlord.antarchy.content.worldgen.cavaryn.CavarynCreepvineFeature; import com.craisinlord.antarchy.content.worldgen.cavaryn.CavarynWallAmberMossFeature; +import com.craisinlord.antarchy.content.worldgen.ocean.SeashellFeature; import com.craisinlord.antarchy.content.worldgen.overworld.CornPatchFeature; import com.craisinlord.antarchy.content.worldgen.thoraxis.NyxiteSpikeConfiguration; import com.craisinlord.antarchy.content.worldgen.thoraxis.AntiwaterSpringsConfiguration; @@ -691,6 +692,8 @@ public final class AntarchyFabricMisc { public static final DeferredHolder, com.craisinlord.antarchy.content.worldgen.ocean.StarCoralPatchFeature> STAR_CORAL_PATCH = FEATURES.register("star_coral_patch", () -> new com.craisinlord.antarchy.content.worldgen.ocean.StarCoralPatchFeature(NoneFeatureConfiguration.CODEC)); + public static final DeferredHolder, SeashellFeature> SEASHELL_PATCH = FEATURES.register("seashell_patch", + () -> new SeashellFeature(NoneFeatureConfiguration.CODEC)); public static final DeferredHolder, ElythiaFloraFeature> ELYTHIA_BUTTERFLY_FIELDS_FLORA = FEATURES.register("butterfly_fields_flora", @@ -748,6 +751,9 @@ public final class AntarchyFabricMisc { public static final DeferredHolder, LumenLilyPadFeature> LUMEN_LILY_PADS = FEATURES.register("lumen_lily_pads", () -> new LumenLilyPadFeature(NoneFeatureConfiguration.CODEC)); + public static final DeferredHolder, com.craisinlord.antarchy.content.worldgen.elythia.GiantLilyPadPatchFeature> GIANT_LILY_PAD_PATCH = FEATURES.register("giant_lily_pad_patch", + () -> new com.craisinlord.antarchy.content.worldgen.elythia.GiantLilyPadPatchFeature(NoneFeatureConfiguration.CODEC)); + public static final DeferredHolder, LumenStreamFeature> LUMEN_STREAM = FEATURES.register("lumen_streams", () -> new LumenStreamFeature(NoneFeatureConfiguration.CODEC)); diff --git a/fabric/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricSpawnPlacements.java b/fabric/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricSpawnPlacements.java index 9a1c4d32..7a1df6dd 100644 --- a/fabric/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricSpawnPlacements.java +++ b/fabric/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricSpawnPlacements.java @@ -273,8 +273,7 @@ public final class AntarchyFabricSpawnPlacements { SpawnPlacements.register(AntarchyFabricEntities.MISSILE_SQUID.get(), SpawnPlacementTypes.IN_WATER, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, MissileSquidEntity::canSpawn); SpawnPlacements.register(AntarchyFabricEntities.OCTOPUS_BOMB.get(), SpawnPlacementTypes.IN_WATER, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, OctopusBombEntity::canSpawn); SpawnPlacements.register(AntarchyFabricEntities.CHEEP.get(), SpawnPlacementTypes.IN_WATER, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, net.minecraft.world.entity.animal.AbstractFish::checkSurfaceWaterAnimalSpawnRules); - // Dorrie is not part of this update yet. - // SpawnPlacements.register(AntarchyFabricEntities.DORRIE.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, net.minecraft.world.entity.animal.Animal::checkAnimalSpawnRules); + SpawnPlacements.register(AntarchyFabricEntities.DORRIE.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, net.minecraft.world.entity.animal.Animal::checkAnimalSpawnRules); SpawnPlacements.register(AntarchyFabricEntities.OURANWOOD_DEER.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, net.minecraft.world.entity.animal.Animal::checkAnimalSpawnRules); SpawnPlacements.register(AntarchyFabricEntities.GLIMMER.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, com.craisinlord.antarchy.content.entity.glimmer.GlimmerEntity::checkGlimmerSpawnRules); SpawnPlacements.register(AntarchyFabricEntities.ELKA.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, net.minecraft.world.entity.animal.Animal::checkAnimalSpawnRules); diff --git a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyNeoforge.java b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyNeoforge.java index 240c61c7..f54a9242 100644 --- a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyNeoforge.java +++ b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyNeoforge.java @@ -219,7 +219,7 @@ public class AntarchyNeoforge { (java.util.function.Supplier) AntarchyNeoforgeEntites.BOMBER, (java.util.function.Supplier) AntarchyNeoforgeEntites.BED_BUG, AntarchyNeoforgeEntites.CHEEP, - () -> { throw new IllegalStateException("Dorrie is not part of this update yet."); }, + AntarchyNeoforgeEntites.DORRIE, () -> AntarchyNeoforgeBlocks.DUPLICATOR_LOG.get(), () -> AntarchyNeoforgeBlocks.DUPLICATOR_SAPLING.get(), () -> AntarchyNeoforgeBlocks.DUCT_TAPE.get(), @@ -284,10 +284,12 @@ public class AntarchyNeoforge { () -> AntarchyNeoforgeBlocks.OURANWOOD_SQUIRREL_NEST.get(), () -> AntarchyNeoforgeBlocks.BRUTALFLY_COCOON_SPAWNER.get(), () -> AntarchyNeoforgeBlocks.GIANT_LILY_PAD.get(), + () -> AntarchyNeoforgeBlocks.SEASHELL.get(), () -> AntarchyNeoforgeBlocks.ANT_NEST_BLOCK_ENTITY.get(), () -> AntarchyNeoforgeBlocks.DREAM_CAMPFIRE_BLOCK_ENTITY.get(), () -> AntarchyNeoforgeBlocks.WASP_NEST_BLOCK_ENTITY.get(), () -> AntarchyNeoforgeBlocks.HUSHWEED_BLOCK_ENTITY.get(), + () -> AntarchyNeoforgeBlocks.SEASHELL_BLOCK_ENTITY.get(), () -> AntarchyNeoforgeMisc.STINKY_GAS.get(), () -> AntarchyNeoforgeMisc.STINKY_FLY.get(), () -> AntarchyNeoforgeMisc.PEACH_LEAVES_PARTICLE.get(), @@ -298,6 +300,7 @@ public class AntarchyNeoforge { AntarchyObjects.setOctopusBomb(AntarchyNeoforgeEntites.OCTOPUS_BOMB); AntarchyObjects.setTentacle(AntarchyNeoforgeEntites.TENTACLE); AntarchyObjects.setKrakensGraspTrident(AntarchyNeoforgeEntites.KRAKENS_GRASP_TRIDENT); + AntarchyObjects.setLotus(() -> AntarchyNeoforgeBlocks.LOTUS.get()); AntarchyObjects.setKrakenTentacle(() -> AntarchyNeoforgeItems.KRAKEN_TENTACLE.get()); AntarchyObjects.setKrakensGrasp(() -> AntarchyNeoforgeItems.KRAKENS_GRASP.get()); AntarchyObjects.setOuranwoodDeer(AntarchyNeoforgeEntites.OURANWOOD_DEER); @@ -320,8 +323,7 @@ public class AntarchyNeoforge { AntarchyObjects.setLumenBlock(() -> AntarchyNeoforgeBlocks.LUMEN_BLOCK.get()); AntarchyObjects.setLumenFroglight(() -> AntarchyNeoforgeBlocks.LUMEN_FROGLIGHT.get()); AntarchyObjects.setPeachLeavesParticle(() -> AntarchyNeoforgeMisc.PEACH_LEAVES_PARTICLE.get()); - // Dorrie is not part of this update yet. - // AntarchyObjects.setDorrieInventoryMenu(AntarchyNeoforgeMisc.DORRIE_INVENTORY_MENU); + AntarchyObjects.setDorrieInventoryMenu(AntarchyNeoforgeMisc.DORRIE_INVENTORY_MENU); } private static boolean isModLoaded(String modId) { diff --git a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/client/AntarchyNeoForgeClient.java b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/client/AntarchyNeoForgeClient.java index 63396b67..25117d28 100644 --- a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/client/AntarchyNeoForgeClient.java +++ b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/client/AntarchyNeoForgeClient.java @@ -85,6 +85,7 @@ public final class AntarchyNeoForgeClient { @SubscribeEvent public static void registerRenderers(EntityRenderersEvent.RegisterRenderers event) { event.registerBlockEntityRenderer(AntarchyNeoforgeBlocks.DREAM_CAMPFIRE_BLOCK_ENTITY.get(), CampfireRenderer::new); + event.registerBlockEntityRenderer(AntarchyNeoforgeBlocks.SEASHELL_BLOCK_ENTITY.get(), SeashellRenderer::new); event.registerEntityRenderer(AntarchyNeoforgeEntites.EASTER_BUNNY.get(), context -> withParalyzedGeoLayer(new EasterBunnyRenderer(context))); event.registerEntityRenderer(AntarchyNeoforgeEntites.FLYING_SQUIRREL.get(), context -> withParalyzedGeoLayer(new FlyingSquirrelRenderer(context))); event.registerEntityRenderer(AntarchyNeoforgeEntites.CATERPILLAR.get(), context -> withParalyzedGeoLayer(new CaterpillarRenderer(context))); @@ -111,7 +112,7 @@ public final class AntarchyNeoForgeClient { event.registerEntityRenderer(AntarchyNeoforgeEntites.CLOUD_SHARK.get(), context -> withParalyzedGeoLayer(new CloudSharkRenderer(context))); event.registerEntityRenderer(AntarchyNeoforgeEntites.KRAKEN.get(), context -> withParalyzedGeoLayer(new KrakenRenderer(context))); event.registerEntityRenderer(AntarchyNeoforgeEntites.TENTACLE.get(), com.craisinlord.antarchy.content.client.renderer.TentacleRenderer::new); - event.registerEntityRenderer(AntarchyNeoforgeEntites.KRAKENS_GRASP_TRIDENT.get(), ThrownItemRenderer::new); + event.registerEntityRenderer(AntarchyNeoforgeEntites.KRAKENS_GRASP_TRIDENT.get(), com.craisinlord.antarchy.content.client.renderer.KrakensGraspThrownTridentRenderer::new); event.registerEntityRenderer(AntarchyNeoforgeEntites.MISSILE_SQUID.get(), context -> withParalyzedGeoLayer(new MissileSquidRenderer(context))); event.registerEntityRenderer(AntarchyNeoforgeEntites.OCTOPUS_BOMB.get(), context -> withParalyzedGeoLayer(new OctopusBombRenderer(context))); event.registerEntityRenderer(AntarchyNeoforgeEntites.NIGHTMARE.get(), context -> withParalyzedGeoLayer(new NightmareRenderer(context))); @@ -124,7 +125,6 @@ public final class AntarchyNeoForgeClient { event.registerEntityRenderer(AntarchyNeoforgeEntites.GROWTH_RAY_PROJECTILE.get(), SizeRayProjectileRenderer::new); event.registerEntityRenderer(AntarchyNeoforgeEntites.LUCID_BOLT.get(), LucidBoltRenderer::new); event.registerEntityRenderer(AntarchyNeoforgeEntites.LUCID_PEARL_PROJECTILE.get(), ThrownItemRenderer::new); - event.registerEntityRenderer(AntarchyNeoforgeEntites.KRAKENS_GRASP_TRIDENT.get(), ThrownItemRenderer::new); event.registerEntityRenderer(AntarchyNeoforgeEntites.HUSH_PROJECTILE.get(), HushProjectileRenderer::new); event.registerEntityRenderer(AntarchyNeoforgeEntites.BRUTALFLY_ORB.get(), BrutalflyOrbRenderer::new); event.registerEntityRenderer(AntarchyNeoforgeEntites.UPWARD_FALLING_BLOCK.get(), com.craisinlord.antarchy.content.client.renderer.UpwardFallingBlockRenderer::new); @@ -133,8 +133,7 @@ public final class AntarchyNeoForgeClient { event.registerEntityRenderer(AntarchyNeoforgeEntites.TORETERROR.get(), ToreterrorRenderer::new); event.registerEntityRenderer(AntarchyNeoforgeEntites.WATER_BOMB.get(), WaterBombRenderer::new); event.registerEntityRenderer(AntarchyNeoforgeEntites.CHEEP.get(), context -> withParalyzedGeoLayer(new com.craisinlord.antarchy.content.client.renderer.CheepRenderer(context))); - // Dorrie is not part of this update yet. - // event.registerEntityRenderer(AntarchyNeoforgeEntites.DORRIE.get(), context -> new com.craisinlord.antarchy.content.client.renderer.DorrieRenderer(context)); + event.registerEntityRenderer(AntarchyNeoforgeEntites.DORRIE.get(), context -> new com.craisinlord.antarchy.content.client.renderer.DorrieRenderer(context)); event.registerEntityRenderer(AntarchyNeoforgeEntites.OURANWOOD_DEER.get(), context -> new com.craisinlord.antarchy.content.client.renderer.OuranwoodDeerRenderer(context)); event.registerEntityRenderer(AntarchyNeoforgeEntites.GLIMMER.get(), context -> withParalyzedGeoLayer(new com.craisinlord.antarchy.content.client.renderer.glimmer.GlimmerRenderer(context))); event.registerEntityRenderer(AntarchyNeoforgeEntites.ELKA.get(), context -> new com.craisinlord.antarchy.content.client.renderer.ElkaRenderer(context)); @@ -497,6 +496,7 @@ public final class AntarchyNeoForgeClient { ItemBlockRenderTypes.setRenderLayer(AntarchyNeoforgeBlocks.PINK_MILKWEED.get(), RenderType.cutout()); ItemBlockRenderTypes.setRenderLayer(AntarchyNeoforgeBlocks.CAMELLIA.get(), RenderType.cutout()); ItemBlockRenderTypes.setRenderLayer(AntarchyNeoforgeBlocks.SPIDER_LILY.get(), RenderType.cutout()); + ItemBlockRenderTypes.setRenderLayer(AntarchyNeoforgeBlocks.LOTUS.get(), RenderType.cutout()); ItemBlockRenderTypes.setRenderLayer(AntarchyNeoforgeBlocks.GIANT_LILY_PAD.get(), RenderType.cutout()); ItemBlockRenderTypes.setRenderLayer(AntarchyNeoforgeBlocks.HUSHWEED.get(), RenderType.cutout()); ItemBlockRenderTypes.setRenderLayer(AntarchyNeoforgeBlocks.CORNEA_STALK.get(), RenderType.cutout()); diff --git a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeBlocks.java b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeBlocks.java index 1fbfc3c0..e2799365 100644 --- a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeBlocks.java +++ b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeBlocks.java @@ -8,6 +8,7 @@ import com.craisinlord.antarchy.content.block.entity.AntNestBlockEntity; import com.craisinlord.antarchy.content.block.entity.DreamCampfireBlockEntity; import com.craisinlord.antarchy.content.block.entity.HushweedBlockEntity; import com.craisinlord.antarchy.content.block.entity.PotentNyxiteBlockEntity; +import com.craisinlord.antarchy.content.block.entity.SeashellBlockEntity; import com.craisinlord.antarchy.content.block.entity.WaspNestBlockEntity; import com.craisinlord.antarchy.content.fluid.BileLiquidBlock; import com.craisinlord.antarchy.content.fluid.LumenLiquidBlock; @@ -91,6 +92,10 @@ public final class AntarchyNeoforgeBlocks { () -> new com.craisinlord.antarchy.content.block.SpiderLilyBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.POPPY))); public static final DeferredBlock GIANT_LILY_PAD = BLOCKS.register("giant_lily_pad", () -> new GiantLilyPadBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.LILY_PAD))); + public static final DeferredBlock LOTUS = BLOCKS.register("lotus", + () -> new com.craisinlord.antarchy.content.block.LotusBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.SPORE_BLOSSOM))); + public static final DeferredBlock SEASHELL = BLOCKS.register("seashell", + () -> new SeashellBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.TURTLE_EGG).noOcclusion())); public static final DeferredBlock OURANWOOD_SIGN = BLOCKS.register("ouranwood_sign", () -> new StandingSignBlock(AntarchyWoodTypes.OURANWOOD, BlockBehaviour.Properties.ofFullCopy(Blocks.JUNGLE_SIGN))); public static final DeferredBlock OURANWOOD_WALL_SIGN = BLOCKS.register("ouranwood_wall_sign", @@ -446,6 +451,11 @@ public final class AntarchyNeoforgeBlocks { (pos, state) -> new PotentNyxiteBlockEntity(pos, state, AntarchyNeoforgeItems::potentNyxiteBlockEntityType), POTENT_NYXITE.get() ).build(null)); + public static final DeferredHolder, BlockEntityType> SEASHELL_BLOCK_ENTITY = BLOCK_ENTITY_TYPES.register("seashell", + () -> BlockEntityType.Builder.of( + SeashellBlockEntity::new, + SEASHELL.get() + ).build(null)); private AntarchyNeoforgeBlocks() {} diff --git a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeCreativeModeTabs.java b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeCreativeModeTabs.java index b8fc6296..6245ef58 100644 --- a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeCreativeModeTabs.java +++ b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeCreativeModeTabs.java @@ -81,8 +81,7 @@ public class AntarchyNeoforgeCreativeModeTabs { event.accept(AntarchyNeoforgeItems.BASILISK_SPAWN_EGG.get()); event.accept(AntarchyNeoforgeItems.EMPEROR_SCORPION_SPAWN_EGG.get()); event.accept(AntarchyNeoforgeItems.TORETERROR_SPAWN_EGG.get()); - // Dorrie is not part of this update yet. - // event.accept(AntarchyNeoforgeItems.DORRIE_SPAWN_EGG.get()); + event.accept(AntarchyNeoforgeItems.DORRIE_SPAWN_EGG.get()); event.accept(AntarchyNeoforgeItems.OURANWOOD_DEER_SPAWN_EGG.get()); event.accept(AntarchyNeoforgeItems.GLIMMER_SPAWN_EGG.get()); event.accept(AntarchyNeoforgeItems.ELKA_SPAWN_EGG.get()); @@ -100,7 +99,9 @@ public class AntarchyNeoforgeCreativeModeTabs { event.accept(AntarchyNeoforgeItems.PINK_MILKWEED_ITEM.get()); event.accept(AntarchyNeoforgeItems.CAMELLIA_ITEM.get()); event.accept(AntarchyNeoforgeItems.SPIDER_LILY_ITEM.get()); + event.accept(AntarchyNeoforgeItems.LOTUS_ITEM.get()); event.accept(AntarchyNeoforgeItems.GIANT_LILY_PAD_ITEM.get()); + event.accept(AntarchyNeoforgeItems.SEASHELL_ITEM.get()); event.accept(AntarchyNeoforgeItems.HUSHWEED_ITEM.get()); event.accept(AntarchyNeoforgeItems.INFESTED_ROOTED_DIRT_ITEM.get()); event.accept(AntarchyNeoforgeItems.INFESTED_COARSE_DIRT_ITEM.get()); @@ -182,6 +183,7 @@ public class AntarchyNeoforgeCreativeModeTabs { event.accept(AntarchyNeoforgeItems.COOKED_CORNDOG.get()); event.accept(AntarchyNeoforgeItems.RAW_VENISON.get()); event.accept(AntarchyNeoforgeItems.COOKED_VENISON.get()); + event.accept(AntarchyNeoforgeItems.CHEEP_ITEM.get()); event.accept(AntarchyNeoforgeItems.ROOT_BEER.get()); event.accept(AntarchyNeoforgeItems.RAINBOW_SUGAR.get()); event.accept(AntarchyNeoforgeItems.BIG_BERTHA_BLADE.get()); diff --git a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeEntites.java b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeEntites.java index 2d79e54e..5ad7b21a 100644 --- a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeEntites.java +++ b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeEntites.java @@ -315,12 +315,11 @@ public final class AntarchyNeoforgeEntites { .sized(1.0F, 1.2F) .clientTrackingRange(8) .build("cheep")); - // Dorrie is not part of this update yet. - // public static final DeferredHolder, EntityType> DORRIE = ENTITY_TYPES.register("dorrie", - // () -> EntityType.Builder.of(DorrieEntity::new, MobCategory.CREATURE) - // .sized(1.6F, 1.4F) - // .clientTrackingRange(10) - // .build("dorrie")); + public static final DeferredHolder, EntityType> DORRIE = ENTITY_TYPES.register("dorrie", + () -> EntityType.Builder.of(DorrieEntity::new, MobCategory.CREATURE) + .sized(1.6F, 1.4F) + .clientTrackingRange(10) + .build("dorrie")); public static final DeferredHolder, EntityType> OURANWOOD_DEER = ENTITY_TYPES.register("ouranwood_deer", () -> EntityType.Builder.of(OuranwoodDeerEntity::new, MobCategory.CREATURE) .sized(0.9F, 1.4F) diff --git a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeEntityAttributes.java b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeEntityAttributes.java index 1e84116e..2b7aacb0 100644 --- a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeEntityAttributes.java +++ b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeEntityAttributes.java @@ -75,8 +75,7 @@ public class AntarchyNeoforgeEntityAttributes { event.put(AntarchyNeoforgeEntites.MOLEWORM.get(), MolewormEntity.createAttributes().build()); event.put(AntarchyNeoforgeEntites.MOLEVORE.get(), MolevoreEntity.createAttributes().build()); event.put(AntarchyNeoforgeEntites.CHEEP.get(), com.craisinlord.antarchy.content.entity.CheepEntity.createAttributes().build()); - // Dorrie is not part of this update yet. - // event.put(AntarchyNeoforgeEntites.DORRIE.get(), com.craisinlord.antarchy.content.entity.DorrieEntity.createAttributes().build()); + event.put(AntarchyNeoforgeEntites.DORRIE.get(), com.craisinlord.antarchy.content.entity.DorrieEntity.createAttributes().build()); event.put(AntarchyNeoforgeEntites.OURANWOOD_DEER.get(), com.craisinlord.antarchy.content.entity.OuranwoodDeerEntity.createAttributes().build()); event.put(AntarchyNeoforgeEntites.GLIMMER.get(), com.craisinlord.antarchy.content.entity.glimmer.GlimmerEntity.createAttributes().build()); event.put(AntarchyNeoforgeEntites.ELKA.get(), ElkaEntity.createAttributes().build()); diff --git a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeItems.java b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeItems.java index a3806df0..f69c38bd 100644 --- a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeItems.java +++ b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeItems.java @@ -181,6 +181,8 @@ public final class AntarchyNeoforgeItems { public static final DeferredItem SPIDER_LILY_ITEM = ITEMS.registerSimpleBlockItem(AntarchyNeoforgeBlocks.SPIDER_LILY); public static final DeferredItem GIANT_LILY_PAD_ITEM = ITEMS.register("giant_lily_pad", () -> new PlaceOnWaterBlockItem(AntarchyNeoforgeBlocks.GIANT_LILY_PAD.get(), new Item.Properties())); + public static final DeferredItem SEASHELL_ITEM = ITEMS.registerSimpleBlockItem(AntarchyNeoforgeBlocks.SEASHELL); + public static final DeferredItem LOTUS_ITEM = ITEMS.registerSimpleBlockItem(AntarchyNeoforgeBlocks.LOTUS); public static final DeferredItem OURANWOOD_SIGN_ITEM = ITEMS.register("ouranwood_sign", () -> new net.minecraft.world.item.SignItem(new Item.Properties().stacksTo(16), AntarchyNeoforgeBlocks.OURANWOOD_SIGN.get(), AntarchyNeoforgeBlocks.OURANWOOD_WALL_SIGN.get())); public static final DeferredItem OURANWOOD_HANGING_SIGN_ITEM = ITEMS.register("ouranwood_hanging_sign", @@ -606,9 +608,8 @@ public final class AntarchyNeoforgeItems { // Spawn eggs public static final DeferredItem EASTER_BUNNY_SPAWN_EGG = ITEMS.register("easter_bunny_spawn_egg", () -> new DeferredSpawnEggItem(AntarchyNeoforgeEntites.EASTER_BUNNY, 0xFFF2B2, 0xFF85B5, new Item.Properties())); - // Dorrie is not part of this update yet. - // public static final DeferredItem DORRIE_SPAWN_EGG = ITEMS.register("dorrie_spawn_egg", - // () -> new DeferredSpawnEggItem(AntarchyNeoforgeEntites.DORRIE, 0x6F8CFF, 0xD2F2FF, new Item.Properties())); + public static final DeferredItem DORRIE_SPAWN_EGG = ITEMS.register("dorrie_spawn_egg", + () -> new DeferredSpawnEggItem(AntarchyNeoforgeEntites.DORRIE, 0x6F8CFF, 0xD2F2FF, new Item.Properties())); public static final DeferredItem OURANWOOD_DEER_SPAWN_EGG = ITEMS.register("ouranwood_deer_spawn_egg", () -> new DeferredSpawnEggItem(AntarchyNeoforgeEntites.OURANWOOD_DEER, 0x8A6D4B, 0xE8D9B5, new Item.Properties())); public static final DeferredItem GLIMMER_SPAWN_EGG = ITEMS.register("glimmer_spawn_egg", @@ -702,6 +703,12 @@ public final class AntarchyNeoforgeItems { () -> new DeferredSpawnEggItem(AntarchyNeoforgeEntites.TORETERROR, 0x90EE90, 0x5C4033, new Item.Properties().rarity(Rarity.EPIC))); public static final DeferredItem CHEEP_SPAWN_EGG = ITEMS.register("cheep_spawn_egg", () -> new DeferredSpawnEggItem(AntarchyNeoforgeEntites.CHEEP, 0xAA22FF, 0x22FF44, new Item.Properties())); + public static final DeferredItem CHEEP_ITEM = ITEMS.register("cheep", + () -> new Item(new Item.Properties() + .food(new net.minecraft.world.food.FoodProperties.Builder() + .nutrition(2) + .saturationModifier(0.1F) + .build()))); public static final DeferredItem CREEPING_HORROR_EGG_ITEM = ITEMS.register("creeping_horror_egg", () -> new MobComingSoonTooltipItem(new Item.Properties().rarity(Rarity.RARE))); public static final DeferredItem LURKING_TERROR_EGG_ITEM = ITEMS.register("lurking_terror_egg", diff --git a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeMisc.java b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeMisc.java index 1eca9358..9eb57043 100644 --- a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeMisc.java +++ b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeMisc.java @@ -12,6 +12,7 @@ import com.craisinlord.antarchy.content.effect.StinkyMobEffect; import com.craisinlord.antarchy.content.worldgen.ants.BrownAntNestFeature; import com.craisinlord.antarchy.content.worldgen.ants.RainbowAntNestFeature; import com.craisinlord.antarchy.content.worldgen.ants.RedAntNestFeature; +import com.craisinlord.antarchy.content.worldgen.ocean.SeashellFeature; import com.craisinlord.antarchy.content.worldgen.elythia.*; import com.craisinlord.antarchy.neoforge.worldgen.CornPatchFeature; import com.craisinlord.antarchy.neoforge.worldgen.LumenLilyPadFeature; @@ -241,6 +242,8 @@ public final class AntarchyNeoforgeMisc { () -> new CornPatchFeature(NoneFeatureConfiguration.CODEC)); public static final DeferredHolder, com.craisinlord.antarchy.content.worldgen.ocean.StarCoralPatchFeature> STAR_CORAL_PATCH = FEATURES.register("star_coral_patch", () -> new com.craisinlord.antarchy.content.worldgen.ocean.StarCoralPatchFeature(NoneFeatureConfiguration.CODEC)); + public static final DeferredHolder, SeashellFeature> SEASHELL_PATCH = FEATURES.register("seashell_patch", + () -> new SeashellFeature(NoneFeatureConfiguration.CODEC)); public static final DeferredHolder, ElythiaFloraFeature> ELYTHIA_BUTTERFLY_FIELDS_FLORA = FEATURES.register("butterfly_fields_flora", () -> new ElythiaFloraFeature(NoneFeatureConfiguration.CODEC, ElythiaFloraFeature.Variant.BUTTERFLY_FIELDS)); public static final DeferredHolder, ElythiaSurfaceCoverFeature> ELYTHIA_SURFACE_COVER = FEATURES.register("elythia_surface_cover", @@ -265,6 +268,8 @@ public final class AntarchyNeoforgeMisc { () -> new LumenPoolFeature(NoneFeatureConfiguration.CODEC)); public static final DeferredHolder, LumenLilyPadFeature> LUMEN_LILY_PADS = FEATURES.register("lumen_lily_pads", () -> new LumenLilyPadFeature(NoneFeatureConfiguration.CODEC)); + public static final DeferredHolder, com.craisinlord.antarchy.content.worldgen.elythia.GiantLilyPadPatchFeature> GIANT_LILY_PAD_PATCH = FEATURES.register("giant_lily_pad_patch", + () -> new com.craisinlord.antarchy.content.worldgen.elythia.GiantLilyPadPatchFeature(NoneFeatureConfiguration.CODEC)); public static final DeferredHolder, LumenStreamFeature> LUMEN_STREAM = FEATURES.register("lumen_streams", () -> new LumenStreamFeature(NoneFeatureConfiguration.CODEC)); public static final DeferredHolder, LumenSpireFeature> LUMEN_SPIRE = FEATURES.register("lumen_spires", diff --git a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeSpawnPlacements.java b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeSpawnPlacements.java index 3be87c86..f81cbacc 100644 --- a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeSpawnPlacements.java +++ b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeSpawnPlacements.java @@ -48,8 +48,7 @@ public class AntarchyNeoforgeSpawnPlacements { event.register(AntarchyNeoforgeEntites.BASILISK.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, BasiliskEntity::canSpawn, RegisterSpawnPlacementsEvent.Operation.OR); event.register(AntarchyNeoforgeEntites.EMPEROR_SCORPION.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, EmperorScorpionEntity::canSpawn, RegisterSpawnPlacementsEvent.Operation.OR); event.register(AntarchyNeoforgeEntites.CHEEP.get(), SpawnPlacementTypes.IN_WATER, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, AbstractFish::checkSurfaceWaterAnimalSpawnRules, RegisterSpawnPlacementsEvent.Operation.OR); - // Dorrie is not part of this update yet. - // event.register(AntarchyNeoforgeEntites.DORRIE.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, net.minecraft.world.entity.animal.Animal::checkAnimalSpawnRules, RegisterSpawnPlacementsEvent.Operation.OR); + event.register(AntarchyNeoforgeEntites.DORRIE.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, net.minecraft.world.entity.animal.Animal::checkAnimalSpawnRules, RegisterSpawnPlacementsEvent.Operation.OR); event.register(AntarchyNeoforgeEntites.OURANWOOD_DEER.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, net.minecraft.world.entity.animal.Animal::checkAnimalSpawnRules, RegisterSpawnPlacementsEvent.Operation.OR); event.register(AntarchyNeoforgeEntites.GLIMMER.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, com.craisinlord.antarchy.content.entity.glimmer.GlimmerEntity::checkGlimmerSpawnRules, RegisterSpawnPlacementsEvent.Operation.OR); event.register(AntarchyNeoforgeEntites.ELKA.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, net.minecraft.world.entity.animal.Animal::checkAnimalSpawnRules, RegisterSpawnPlacementsEvent.Operation.OR); diff --git a/neoforge/src/main/resources/data/antarchy/neoforge/biome_modifier/seashell_in_oceans.json b/neoforge/src/main/resources/data/antarchy/neoforge/biome_modifier/seashell_in_oceans.json new file mode 100644 index 00000000..f6cd05f7 --- /dev/null +++ b/neoforge/src/main/resources/data/antarchy/neoforge/biome_modifier/seashell_in_oceans.json @@ -0,0 +1,6 @@ +{ + "type": "neoforge:add_features", + "biomes": "#antarchy:has_seashell", + "features": ["antarchy:seashell_patch"], + "step": "vegetal_decoration" +}