commit e3e26d810acfa8c33081085427f583ba7eebfd89 Author: ItsBlackGear Date: Sun Jul 10 00:16:25 2022 -0400 Initial commit diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c37caf --- /dev/null +++ b/.gitignore @@ -0,0 +1,118 @@ +# User-specific stuff +.idea/ + +*.iml +*.ipr +*.iws + +# IntelliJ +out/ +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +.gradle +build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Cache of project +.gradletasknamecache + +**/build/ + +# Common working directory +run/ + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..4a26737 --- /dev/null +++ b/build.gradle @@ -0,0 +1,51 @@ +plugins { + id "architectury-plugin" version "3.4-SNAPSHOT" + id "dev.architectury.loom" version "0.11.0-SNAPSHOT" apply false +} + +architectury { + minecraft = rootProject.minecraft_version +} + +subprojects { + apply plugin: "dev.architectury.loom" + + loom { + silentMojangMappingsLicense() + } + + dependencies { + minecraft "com.mojang:minecraft:${rootProject.minecraft_version}" + // The following line declares the mojmap mappings, you may use other mappings as well + mappings loom.officialMojangMappings() + // The following line declares the yarn mappings you may select this one as well. + // mappings "net.fabricmc:yarn:@YARN_MAPPINGS@:v2" + } +} + +allprojects { + apply plugin: "java" + apply plugin: "architectury-plugin" + apply plugin: "maven-publish" + + archivesBaseName = rootProject.archives_base_name + version = rootProject.mod_version + group = rootProject.maven_group + + repositories { + // Add repositories to retrieve artifacts from in here. + // You should only use this when depending on other mods because + // Loom adds the essential maven repositories to download Minecraft and libraries from automatically. + // See https://docs.gradle.org/current/userguide/declaring_repositories.html + // for more information about repositories. + } + + tasks.withType(JavaCompile) { + options.encoding = "UTF-8" + options.release = 17 + } + + java { + withSourcesJar() + } +} diff --git a/common/build.gradle b/common/build.gradle new file mode 100644 index 0000000..23cdc19 --- /dev/null +++ b/common/build.gradle @@ -0,0 +1,27 @@ +dependencies { + // We depend on fabric loader here to use the fabric @Environment annotations and get the mixin dependencies + // Do NOT use other classes from fabric loader + modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" +} + +architectury { + common() +} + +loom { + accessWidenerPath.set(file("src/main/resources/wildbackport.accesswidener")) +} + +publishing { + publications { + mavenCommon(MavenPublication) { + artifactId = rootProject.archives_base_name + from components.java + } + } + + // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. + repositories { + // Add repositories to publish to here. + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/WildBackport.java b/common/src/main/java/com/cursedcauldron/wildbackport/WildBackport.java new file mode 100644 index 0000000..911a69d --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/WildBackport.java @@ -0,0 +1,53 @@ +package com.cursedcauldron.wildbackport; + +import com.cursedcauldron.wildbackport.client.registry.WBParticleTypes; +import com.cursedcauldron.wildbackport.client.registry.WBSoundEvents; +import com.cursedcauldron.wildbackport.common.registry.WBBiomes; +import com.cursedcauldron.wildbackport.common.registry.WBBlockEntities; +import com.cursedcauldron.wildbackport.common.registry.WBBlocks; +import com.cursedcauldron.wildbackport.common.registry.WBEnchantments; +import com.cursedcauldron.wildbackport.common.registry.WBGameEvents; +import com.cursedcauldron.wildbackport.common.registry.WBItems; +import com.cursedcauldron.wildbackport.common.registry.WBPositionSources; +import com.cursedcauldron.wildbackport.common.registry.entity.WBActivities; +import com.cursedcauldron.wildbackport.common.registry.entity.WBEntities; +import com.cursedcauldron.wildbackport.common.registry.entity.WBMemoryModules; +import com.cursedcauldron.wildbackport.common.registry.entity.WBSensorTypes; +import com.cursedcauldron.wildbackport.common.tag.WBBiomeTags; +import com.cursedcauldron.wildbackport.common.tag.WBBlockTags; +import com.cursedcauldron.wildbackport.common.tag.WBEntityTypeTags; +import com.cursedcauldron.wildbackport.common.tag.WBGameEventTags; +import com.cursedcauldron.wildbackport.common.tag.WBItemTags; +import com.mojang.logging.LogUtils; +import org.slf4j.Logger; + +//<> + +public class WildBackport { + public static final String MOD_ID = "wildbackport"; + public static final Logger LOGGER = LogUtils.getLogger(); + + public static void bootstrap() { + // Registries + WBActivities.ACTIVITIES.register(); + WBBiomes.BIOMES.register(); + WBBlockEntities.BLOCKS.register(); + WBBlocks.BLOCKS.register(); + WBEnchantments.ENCHANTMENTS.register(); + WBEntities.ENTITIES.register(); + WBGameEvents.EVENTS.register(); + WBItems.ITEMS.register(); + WBMemoryModules.MEMORIES.register(); + WBParticleTypes.PARTICLES.register(); + WBPositionSources.SOURCES.register(); + WBSensorTypes.SENSORS.register(); + WBSoundEvents.SOUNDS.register(); + + // Tags + WBBiomeTags.TAGS.bootstrap(); + WBBlockTags.TAGS.bootstrap(); + WBEntityTypeTags.TAGS.bootstrap(); + WBGameEventTags.TAGS.bootstrap(); + WBItemTags.TAGS.bootstrap(); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/client/ClientSetup.java b/common/src/main/java/com/cursedcauldron/wildbackport/client/ClientSetup.java new file mode 100644 index 0000000..1af0ceb --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/client/ClientSetup.java @@ -0,0 +1,77 @@ +package com.cursedcauldron.wildbackport.client; + +import com.cursedcauldron.wildbackport.client.particle.SculkChargeParticle; +import com.cursedcauldron.wildbackport.client.particle.SculkChargePopParticle; +import com.cursedcauldron.wildbackport.client.particle.SculkSoulParticle; +import com.cursedcauldron.wildbackport.client.particle.ShriekParticle; +import com.cursedcauldron.wildbackport.client.particle.SonicBoomParticle; +import com.cursedcauldron.wildbackport.client.registry.WBParticleTypes; +import com.cursedcauldron.wildbackport.client.render.AllayRenderer; +import com.cursedcauldron.wildbackport.client.render.ChestBoatRenderer; +import com.cursedcauldron.wildbackport.client.render.FrogRenderer; +import com.cursedcauldron.wildbackport.client.render.TadpoleRenderer; +import com.cursedcauldron.wildbackport.client.render.WardenRenderer; +import com.cursedcauldron.wildbackport.client.render.model.AllayModel; +import com.cursedcauldron.wildbackport.client.render.model.ChestBoatModel; +import com.cursedcauldron.wildbackport.client.render.model.FrogModel; +import com.cursedcauldron.wildbackport.client.render.model.TadpoleModel; +import com.cursedcauldron.wildbackport.client.render.model.WardenModel; +import com.cursedcauldron.wildbackport.common.registry.WBBlocks; +import com.cursedcauldron.wildbackport.common.registry.entity.WBEntities; +import com.cursedcauldron.wildbackport.core.api.ColorRegistry; +import com.cursedcauldron.wildbackport.core.api.ParticleRegistry; +import com.cursedcauldron.wildbackport.core.api.RenderRegistry; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.renderer.BiomeColors; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.world.entity.vehicle.Boat; +import net.minecraft.world.level.FoliageColor; + +@Environment(EnvType.CLIENT) +public class ClientSetup { + /** + * Runs features at initializing + */ + public static void onClient() { + // Colors + ColorRegistry.register((state, getter, pos, tint) -> (getter == null || pos == null) ? FoliageColor.getDefaultColor() : BiomeColors.getAverageFoliageColor(getter, pos), WBBlocks.MANGROVE_LEAVES); + ColorRegistry.register((stack, tint) -> 9619016, WBBlocks.MANGROVE_LEAVES); + + // Entity Renderers + RenderRegistry.setLayerDefinition(AllayRenderer.MODEL_LAYER, AllayModel::createBodyLayer); + RenderRegistry.setEntityRender(WBEntities.ALLAY, AllayRenderer::new); + RenderRegistry.setLayerDefinition(WardenRenderer.MODEL_LAYER, WardenModel::createBodyLayer); + RenderRegistry.setEntityRender(WBEntities.WARDEN, WardenRenderer::new); + RenderRegistry.setLayerDefinition(FrogRenderer.MODEL_LAYER, FrogModel::createBodyLayer); + RenderRegistry.setEntityRender(WBEntities.FROG, FrogRenderer::new); + RenderRegistry.setLayerDefinition(TadpoleRenderer.MODEL_LAYER, TadpoleModel::createBodyLayer); + RenderRegistry.setEntityRender(WBEntities.TADPOLE, TadpoleRenderer::new); + for (Boat.Type type : Boat.Type.values()) RenderRegistry.setLayerDefinition(ChestBoatModel.createChestBoat(type), () -> ChestBoatModel.createBodyModel(true)); + RenderRegistry.setEntityRender(WBEntities.MANGROVE_BOAT, context -> new ChestBoatRenderer(context, false)); + RenderRegistry.setEntityRender(WBEntities.CHEST_BOAT, context -> new ChestBoatRenderer(context, true)); + + // Particle Renderers + ParticleRegistry.create(WBParticleTypes.SCULK_SOUL, SculkSoulParticle.Provider::new); + ParticleRegistry.create(WBParticleTypes.SCULK_CHARGE, SculkChargeParticle.Provider::new); + ParticleRegistry.create(WBParticleTypes.SCULK_CHARGE_POP, SculkChargePopParticle.Provider::new); + ParticleRegistry.create(WBParticleTypes.SHRIEK, ShriekParticle.Provider::new); + ParticleRegistry.create(WBParticleTypes.SONIC_BOOM, SonicBoomParticle.Provider::new); + } + + /** + * Runs features post bootstrap + */ + public static void onPostClient() { + // Block Render Types + RenderRegistry.setBlockRenderType(RenderType.cutout(), + WBBlocks.SCULK_VEIN.get(), + WBBlocks.SCULK_SHRIEKER.get(), + WBBlocks.FROGSPAWN.get(), + WBBlocks.MANGROVE_ROOTS.get(), + WBBlocks.MANGROVE_TRAPDOOR.get(), + WBBlocks.MANGROVE_PROPAGULE.get(), + WBBlocks.POTTED_MANGROVE_PROPAGULE.get() + ); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/client/animation/FrogAnimations.java b/common/src/main/java/com/cursedcauldron/wildbackport/client/animation/FrogAnimations.java new file mode 100644 index 0000000..f233982 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/client/animation/FrogAnimations.java @@ -0,0 +1,69 @@ +package com.cursedcauldron.wildbackport.client.animation; + +import com.cursedcauldron.wildbackport.client.animation.api.Animation; +import com.cursedcauldron.wildbackport.client.animation.api.AnimationHelper; +import com.cursedcauldron.wildbackport.client.animation.api.Keyframe; +import com.cursedcauldron.wildbackport.client.animation.api.Transformation; + +public class FrogAnimations { + public static final Animation CROAKING = Animation.Builder.create(4.5F).looping() + .addBoneAnimation("croaking_body", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.6667F, AnimationHelper.translate(0.0F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.7083F, AnimationHelper.translate(0.0F, 1.0F, 0.0F), Transformation.Interpolations.LINEAL), new Keyframe(3.2083F, AnimationHelper.translate(0.0F, 1.0F, 0.0F), Transformation.Interpolations.LINEAL), new Keyframe(3.25F, AnimationHelper.translate(0.0F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL))) + .addBoneAnimation("croaking_body", new Transformation(Transformation.Targets.SCALE, new Keyframe(0.6667F, AnimationHelper.scale(1.0F, 1.0F, 1.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.7083F, AnimationHelper.scale(1.0F, 1.0F, 1.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.7917F, AnimationHelper.scale(1.3F, 2.1F, 1.6F), Transformation.Interpolations.LINEAL), new Keyframe(0.875F, AnimationHelper.scale(1.3F, 2.1F, 1.6F), Transformation.Interpolations.LINEAL), new Keyframe(0.9583F, AnimationHelper.scale(1.0F, 1.0F, 1.0F), Transformation.Interpolations.LINEAL), new Keyframe(2.5F, AnimationHelper.scale(1.0F, 1.0F, 1.0F), Transformation.Interpolations.LINEAL), new Keyframe(2.5833F, AnimationHelper.scale(1.3F, 2.1F, 1.6F), Transformation.Interpolations.LINEAL), new Keyframe(2.6667F, AnimationHelper.scale(1.3F, 2.1F, 1.6F), Transformation.Interpolations.LINEAL), new Keyframe(2.75F, AnimationHelper.scale(1.0F, 1.0F, 1.0F), Transformation.Interpolations.LINEAL), new Keyframe(2.8333F, AnimationHelper.scale(1.0F, 1.0F, 1.0F), Transformation.Interpolations.LINEAL), new Keyframe(2.9167F, AnimationHelper.scale(1.3F, 2.1F, 1.6F), Transformation.Interpolations.LINEAL), new Keyframe(3.125F, AnimationHelper.scale(1.3F, 2.1F, 1.8F), Transformation.Interpolations.LINEAL), new Keyframe(3.2083F, AnimationHelper.scale(1.0F, 1.0F, 1.0F), Transformation.Interpolations.LINEAL), new Keyframe(3.25F, AnimationHelper.scale(1.0F, 1.0F, 1.0F), Transformation.Interpolations.LINEAL))) + .build(); + + public static final Animation WALKING = Animation.Builder.create(1.25F).looping() + .addBoneAnimation("left_arm", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0F, AnimationHelper.rotation(0.0F, -5.0F, 0.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.2917F, AnimationHelper.rotation(7.5F, -2.67F, -7.5F), Transformation.Interpolations.LINEAL), new Keyframe(0.625F, AnimationHelper.rotation(0.0F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.7917F, AnimationHelper.rotation(22.5F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL), new Keyframe(1.125F, AnimationHelper.rotation(-45.0F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL), new Keyframe(1.25F, AnimationHelper.rotation(0.0F, -5.0F, 0.0F), Transformation.Interpolations.LINEAL))) + .addBoneAnimation("left_arm", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0F, AnimationHelper.translate(0.0F, 0.1F, -2.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.2917F, AnimationHelper.translate(-0.5F, -0.25F, -0.13F), Transformation.Interpolations.LINEAL), new Keyframe(0.625F, AnimationHelper.translate(-0.5F, 0.1F, 2.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.9583F, AnimationHelper.translate(0.5F, 1.0F, -0.11F), Transformation.Interpolations.LINEAL), new Keyframe(1.25F, AnimationHelper.translate(0.0F, 0.1F, -2.0F), Transformation.Interpolations.LINEAL))) + .addBoneAnimation("right_arm", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0F, AnimationHelper.rotation(0.0F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.125F, AnimationHelper.rotation(22.5F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.4583F, AnimationHelper.rotation(-45.0F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.625F, AnimationHelper.rotation(0.0F, 5.0F, 0.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.9583F, AnimationHelper.rotation(7.5F, 2.33F, 7.5F), Transformation.Interpolations.LINEAL), new Keyframe(1.25F, AnimationHelper.rotation(0.0F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL))) + .addBoneAnimation("right_arm", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0F, AnimationHelper.translate(0.5F, 0.1F, 2.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.2917F, AnimationHelper.translate(-0.5F, 1.0F, 0.12F), Transformation.Interpolations.LINEAL), new Keyframe(0.625F, AnimationHelper.translate(0.0F, 0.1F, -2.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.9583F, AnimationHelper.translate(0.5F, -0.25F, -0.13F), Transformation.Interpolations.LINEAL), new Keyframe(1.25F, AnimationHelper.translate(0.5F, 0.1F, 2.0F), Transformation.Interpolations.LINEAL))) + .addBoneAnimation("left_leg", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0F, AnimationHelper.rotation(0.0F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.1667F, AnimationHelper.rotation(0.0F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.2917F, AnimationHelper.rotation(45.0F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.625F, AnimationHelper.rotation(-45.0F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.7917F, AnimationHelper.rotation(0.0F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL), new Keyframe(1.25F, AnimationHelper.rotation(0.0F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL))) + .addBoneAnimation("left_leg", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0F, AnimationHelper.translate(0.0F, 0.1F, 1.2F), Transformation.Interpolations.LINEAL), new Keyframe(0.1667F, AnimationHelper.translate(0.0F, 0.1F, 2.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.4583F, AnimationHelper.translate(0.0F, 2.0F, 1.06F), Transformation.Interpolations.LINEAL), new Keyframe(0.7917F, AnimationHelper.translate(0.0F, 0.1F, -1.0F), Transformation.Interpolations.LINEAL), new Keyframe(1.25F, AnimationHelper.translate(0.0F, 0.1F, 1.2F), Transformation.Interpolations.LINEAL))) + .addBoneAnimation("right_leg", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0F, AnimationHelper.rotation(-33.75F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.0417F, AnimationHelper.rotation(-45.0F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.1667F, AnimationHelper.rotation(0.0F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.7917F, AnimationHelper.rotation(0.0F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.9583F, AnimationHelper.rotation(45.0F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL), new Keyframe(1.25F, AnimationHelper.rotation(-33.75F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL))) + .addBoneAnimation("right_leg", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0F, AnimationHelper.translate(0.0F, 1.14F, 0.11F), Transformation.Interpolations.LINEAL), new Keyframe(0.1667F, AnimationHelper.translate(0.0F, 0.1F, -1.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.7917F, AnimationHelper.translate(0.0F, 0.1F, 2.0F), Transformation.Interpolations.LINEAL), new Keyframe(1.125F, AnimationHelper.translate(0.0F, 2.0F, 0.95F), Transformation.Interpolations.LINEAL), new Keyframe(1.25F, AnimationHelper.translate(0.0F, 1.14F, 0.11F), Transformation.Interpolations.LINEAL))) + .addBoneAnimation("body", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0F, AnimationHelper.rotation(0.0F, 5.0F, 0.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.2917F, AnimationHelper.rotation(-7.5F, 0.33F, 7.5F), Transformation.Interpolations.LINEAL), new Keyframe(0.625F, AnimationHelper.rotation(0.0F, -5.0F, 0.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.9583F, AnimationHelper.rotation(-7.5F, 0.33F, -7.5F), Transformation.Interpolations.LINEAL), new Keyframe(1.25F, AnimationHelper.rotation(0.0F, 5.0F, 0.0F), Transformation.Interpolations.LINEAL))) + .build(); + + public static final Animation LONG_JUMPING = Animation.Builder.create(0.5F) + .addBoneAnimation("body", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0F, AnimationHelper.rotation(-22.5F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.5F, AnimationHelper.rotation(-22.5F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL))) + .addBoneAnimation("body", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0F, AnimationHelper.translate(0.0F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.5F, AnimationHelper.translate(0.0F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL))) + .addBoneAnimation("left_arm", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0F, AnimationHelper.rotation(-56.14F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.5F, AnimationHelper.rotation(-56.14F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL))) + .addBoneAnimation("left_arm", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0F, AnimationHelper.translate(0.0F, 1.0F, 0.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.5F, AnimationHelper.translate(0.0F, 1.0F, 0.0F), Transformation.Interpolations.LINEAL))) + .addBoneAnimation("right_arm", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0F, AnimationHelper.rotation(-56.14F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.5F, AnimationHelper.rotation(-56.14F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL))) + .addBoneAnimation("right_arm", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0F, AnimationHelper.translate(0.0F, 1.0F, 0.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.5F, AnimationHelper.translate(0.0F, 1.0F, 0.0F), Transformation.Interpolations.LINEAL))) + .addBoneAnimation("left_leg", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0F, AnimationHelper.rotation(45.0F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.5F, AnimationHelper.rotation(45.0F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL))) + .addBoneAnimation("left_leg", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0F, AnimationHelper.translate(0.0F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.5F, AnimationHelper.translate(0.0F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL))) + .addBoneAnimation("right_leg", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0F, AnimationHelper.rotation(45.0F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.5F, AnimationHelper.rotation(45.0F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL))) + .addBoneAnimation("right_leg", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0F, AnimationHelper.translate(0.0F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL), new Keyframe(0.5F, AnimationHelper.translate(0.0F, 0.0F, 0.0F), Transformation.Interpolations.LINEAL))) + .build(); + + public static final Animation USING_TONGUE = Animation.Builder.create(0.5f) + .addBoneAnimation("head", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.LINEAL), new Keyframe(0.0833f, AnimationHelper.rotation(-60.0f, 0.0f, 0.0f), Transformation.Interpolations.LINEAL), new Keyframe(0.4167f, AnimationHelper.rotation(-60.0f, 0.0f, 0.0f), Transformation.Interpolations.LINEAL), new Keyframe(0.5f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.LINEAL))) + .addBoneAnimation("head", new Transformation(Transformation.Targets.SCALE, new Keyframe(0.0f, AnimationHelper.rotation(1.0f, 1.0f, 1.0f), Transformation.Interpolations.LINEAL), new Keyframe(0.0833f, AnimationHelper.rotation(0.998f, 1.0f, 1.0f), Transformation.Interpolations.LINEAL), new Keyframe(0.4167f, AnimationHelper.rotation(0.998f, 1.0f, 1.0f), Transformation.Interpolations.LINEAL), new Keyframe(0.5f, AnimationHelper.rotation(1.0f, 1.0f, 1.0f), Transformation.Interpolations.LINEAL))) + .addBoneAnimation("tongue", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.LINEAL), new Keyframe(0.0833f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.LINEAL), new Keyframe(0.4167f, AnimationHelper.rotation(-18.0f, 0.0f, 0.0f), Transformation.Interpolations.LINEAL), new Keyframe(0.5f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.LINEAL))) + .addBoneAnimation("tongue", new Transformation(Transformation.Targets.SCALE, new Keyframe(0.0833f, AnimationHelper.scale(1.0, 1.0, 1.0), Transformation.Interpolations.LINEAL), new Keyframe(0.1667f, AnimationHelper.scale(0.5, 1.0, 5.0), Transformation.Interpolations.LINEAL), new Keyframe(0.4167f, AnimationHelper.scale(1.0, 1.0, 1.0), Transformation.Interpolations.LINEAL))) + .build(); + + public static final Animation SWIMMING = Animation.Builder.create(1.04167F).looping() + .addBoneAnimation("body", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0F, AnimationHelper.rotation(0.0F, 0.0F, 0.0F), Transformation.Interpolations.CATMULL), new Keyframe(0.3333F, AnimationHelper.rotation(10.0F, 0.0F, 0.0F), Transformation.Interpolations.CATMULL), new Keyframe(0.6667F, AnimationHelper.rotation(-10.0F, 0.0F, 0.0F), Transformation.Interpolations.CATMULL), new Keyframe(1.0417F, AnimationHelper.rotation(0.0F, 0.0F, 0.0F), Transformation.Interpolations.CATMULL))) + .addBoneAnimation("left_arm", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0F, AnimationHelper.rotation(90.0F, 22.5F, 0.0F), Transformation.Interpolations.CATMULL), new Keyframe(0.4583F, AnimationHelper.rotation(45.0F, 22.5F, 0.0F), Transformation.Interpolations.CATMULL), new Keyframe(0.6667F, AnimationHelper.rotation(-22.5F, -22.5F, -22.5F), Transformation.Interpolations.CATMULL), new Keyframe(0.875F, AnimationHelper.rotation(-45.0F, -22.5F, 0.0F), Transformation.Interpolations.CATMULL), new Keyframe(0.9583F, AnimationHelper.rotation(22.5F, 0.0F, 22.5F), Transformation.Interpolations.CATMULL), new Keyframe(1.0417F, AnimationHelper.rotation(90.0F, 22.5F, 0.0F), Transformation.Interpolations.CATMULL))) + .addBoneAnimation("left_arm", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0F, AnimationHelper.translate(0.0F, -0.64F, 2.0F), Transformation.Interpolations.CATMULL), new Keyframe(0.4583F, AnimationHelper.translate(0.0F, -0.64F, 0.0F), Transformation.Interpolations.CATMULL), new Keyframe(0.6667F, AnimationHelper.translate(0.0F, 0.0F, 0.0F), Transformation.Interpolations.CATMULL), new Keyframe(0.875F, AnimationHelper.translate(0.0F, -0.27F, -1.14F), Transformation.Interpolations.CATMULL), new Keyframe(0.9583F, AnimationHelper.translate(0.0F, -1.45F, 0.43F), Transformation.Interpolations.CATMULL), new Keyframe(1.0417F, AnimationHelper.translate(0.0F, -0.64F, 2.0F), Transformation.Interpolations.CATMULL))) + .addBoneAnimation("right_arm", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0F, AnimationHelper.rotation(90.0F, -22.5F, 0.0F), Transformation.Interpolations.CATMULL), new Keyframe(0.4583F, AnimationHelper.rotation(45.0F, -22.5F, 0.0F), Transformation.Interpolations.CATMULL), new Keyframe(0.6667F, AnimationHelper.rotation(-22.5F, 22.5F, 22.5F), Transformation.Interpolations.CATMULL), new Keyframe(0.875F, AnimationHelper.rotation(-45.0F, 22.5F, 0.0F), Transformation.Interpolations.CATMULL), new Keyframe(0.9583F, AnimationHelper.rotation(22.5F, 0.0F, -22.5F), Transformation.Interpolations.CATMULL), new Keyframe(1.0417F, AnimationHelper.rotation(90.0F, -22.5F, 0.0F), Transformation.Interpolations.CATMULL))) + .addBoneAnimation("right_arm", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0F, AnimationHelper.translate(0.0F, -0.64F, 2.0F), Transformation.Interpolations.CATMULL), new Keyframe(0.4583F, AnimationHelper.translate(0.0F, -0.64F, 0.0F), Transformation.Interpolations.CATMULL), new Keyframe(0.6667F, AnimationHelper.translate(0.0F, 0.0F, 0.0F), Transformation.Interpolations.CATMULL), new Keyframe(0.875F, AnimationHelper.translate(0.0F, -0.27F, -1.14F), Transformation.Interpolations.CATMULL), new Keyframe(0.9583F, AnimationHelper.translate(0.0F, -1.45F, 0.43F), Transformation.Interpolations.CATMULL), new Keyframe(1.0417F, AnimationHelper.translate(0.0F, -0.64F, 2.0F), Transformation.Interpolations.CATMULL))) + .addBoneAnimation("left_leg", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0F, AnimationHelper.rotation(90.0F, 0.0F, 0.0F), Transformation.Interpolations.CATMULL), new Keyframe(0.25F, AnimationHelper.rotation(90.0F, 0.0F, 0.0F), Transformation.Interpolations.CATMULL), new Keyframe(0.4583F, AnimationHelper.rotation(67.5F, -45.0F, 0.0F), Transformation.Interpolations.CATMULL), new Keyframe(0.7917F, AnimationHelper.rotation(90.0F, 45.0F, 0.0F), Transformation.Interpolations.CATMULL), new Keyframe(0.9583F, AnimationHelper.rotation(90.0F, 0.0F, 0.0F), Transformation.Interpolations.CATMULL), new Keyframe(1.0417F, AnimationHelper.rotation(90.0F, 0.0F, 0.0F), Transformation.Interpolations.CATMULL))) + .addBoneAnimation("left_leg", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0F, AnimationHelper.translate(-2.5F, 0.0F, 1.0F), Transformation.Interpolations.CATMULL), new Keyframe(0.25F, AnimationHelper.translate(-2.0F, 0.0F, 1.0F), Transformation.Interpolations.CATMULL), new Keyframe(0.4583F, AnimationHelper.translate(1.0F, -2.0F, -1.0F), Transformation.Interpolations.CATMULL), new Keyframe(0.7917F, AnimationHelper.translate(0.58F, 0.0F, -2.83F), Transformation.Interpolations.CATMULL), new Keyframe(0.9583F, AnimationHelper.translate(-2.5F, 0.0F, 1.0F), Transformation.Interpolations.CATMULL), new Keyframe(1.0417F, AnimationHelper.translate(-2.5F, 0.0F, 1.0F), Transformation.Interpolations.CATMULL))) + .addBoneAnimation("right_leg", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0F, AnimationHelper.rotation(90.0F, 0.0F, 0.0F), Transformation.Interpolations.CATMULL), new Keyframe(0.25F, AnimationHelper.rotation(90.0F, 0.0F, 0.0F), Transformation.Interpolations.CATMULL), new Keyframe(0.4583F, AnimationHelper.rotation(67.5F, 45.0F, 0.0F), Transformation.Interpolations.CATMULL), new Keyframe(0.7917F, AnimationHelper.rotation(90.0F, -45.0F, 0.0F), Transformation.Interpolations.CATMULL), new Keyframe(0.9583F, AnimationHelper.rotation(90.0F, 0.0F, 0.0F), Transformation.Interpolations.CATMULL), new Keyframe(1.0417F, AnimationHelper.rotation(90.0F, 0.0F, 0.0F), Transformation.Interpolations.CATMULL))) + .addBoneAnimation("right_leg", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0F, AnimationHelper.translate(2.5F, 0.0F, 1.0F), Transformation.Interpolations.CATMULL), new Keyframe(0.25F, AnimationHelper.translate(2.0F, 0.0F, 1.0F), Transformation.Interpolations.CATMULL), new Keyframe(0.4583F, AnimationHelper.translate(-1.0F, -2.0F, -1.0F), Transformation.Interpolations.CATMULL), new Keyframe(0.7917F, AnimationHelper.translate(-0.58F, 0.0F, -2.83F), Transformation.Interpolations.CATMULL), new Keyframe(0.9583F, AnimationHelper.translate(2.5F, 0.0F, 1.0F), Transformation.Interpolations.CATMULL), new Keyframe(1.0417F, AnimationHelper.translate(2.5F, 0.0F, 1.0F), Transformation.Interpolations.CATMULL))) + .build(); + + public static final Animation IDLING_IN_WATER = Animation.Builder.create(3.0F).looping() + .addBoneAnimation("body", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0F, AnimationHelper.rotation(0.0F, 0.0F, 0.0F), Transformation.Interpolations.CATMULL), new Keyframe(1.625F, AnimationHelper.rotation(-10.0F, 0.0F, 0.0F), Transformation.Interpolations.CATMULL), new Keyframe(3.0F, AnimationHelper.rotation(0.0F, 0.0F, 0.0F), Transformation.Interpolations.CATMULL))) + .addBoneAnimation("left_arm", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0F, AnimationHelper.rotation(0.0F, 0.0F, -22.5F), Transformation.Interpolations.CATMULL), new Keyframe(2.2083F, AnimationHelper.rotation(0.0F, 0.0F, -45.0F), Transformation.Interpolations.CATMULL), new Keyframe(3.0F, AnimationHelper.rotation(0.0F, 0.0F, -22.5F), Transformation.Interpolations.CATMULL))) + .addBoneAnimation("left_arm", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0F, AnimationHelper.translate(-1.0F, 0.0F, 0.0F), Transformation.Interpolations.CATMULL), new Keyframe(2.2083F, AnimationHelper.translate(-1.0F, -0.5F, 0.0F), Transformation.Interpolations.CATMULL), new Keyframe(3.0F, AnimationHelper.translate(-1.0F, 0.0F, 0.0F), Transformation.Interpolations.CATMULL))) + .addBoneAnimation("right_arm", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0F, AnimationHelper.rotation(0.0F, 0.0F, 22.5F), Transformation.Interpolations.CATMULL), new Keyframe(2.2083F, AnimationHelper.rotation(0.0F, 0.0F, 45.0F), Transformation.Interpolations.CATMULL), new Keyframe(3.0F, AnimationHelper.rotation(0.0F, 0.0F, 22.5F), Transformation.Interpolations.CATMULL))) + .addBoneAnimation("right_arm", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0F, AnimationHelper.translate(1.0F, 0.0F, 0.0F), Transformation.Interpolations.CATMULL), new Keyframe(2.2083F, AnimationHelper.translate(1.0F, -0.5F, 0.0F), Transformation.Interpolations.CATMULL), new Keyframe(3.0F, AnimationHelper.translate(1.0F, 0.0F, 0.0F), Transformation.Interpolations.CATMULL))) + .addBoneAnimation("left_leg", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0F, AnimationHelper.rotation(22.5F, -22.5F, 0.0F), Transformation.Interpolations.CATMULL), new Keyframe(1.0F, AnimationHelper.rotation(22.5F, -22.5F, -45.0F), Transformation.Interpolations.CATMULL), new Keyframe(3.0F, AnimationHelper.rotation(22.5F, -22.5F, 0.0F), Transformation.Interpolations.CATMULL))) + .addBoneAnimation("left_leg", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0F, AnimationHelper.translate(0.0F, 0.0F, 1.0F), Transformation.Interpolations.CATMULL), new Keyframe(1.0F, AnimationHelper.translate(0.0F, -1.0F, 1.0F), Transformation.Interpolations.CATMULL), new Keyframe(3.0F, AnimationHelper.translate(0.0F, 0.0F, 1.0F), Transformation.Interpolations.CATMULL))) + .addBoneAnimation("right_leg", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0F, AnimationHelper.rotation(22.5F, 22.5F, 0.0F), Transformation.Interpolations.CATMULL), new Keyframe(1.0F, AnimationHelper.rotation(22.5F, 22.5F, 45.0F), Transformation.Interpolations.CATMULL), new Keyframe(3.0F, AnimationHelper.rotation(22.5F, 22.5F, 0.0F), Transformation.Interpolations.CATMULL))) + .addBoneAnimation("right_leg", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0F, AnimationHelper.translate(0.0F, 0.0F, 1.0F), Transformation.Interpolations.CATMULL), new Keyframe(1.0F, AnimationHelper.translate(0.0F, -1.0F, 1.0F), Transformation.Interpolations.CATMULL), new Keyframe(3.0F, AnimationHelper.translate(0.0F, 0.0F, 1.0F), Transformation.Interpolations.CATMULL))) + .build(); +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/client/animation/WardenAnimations.java b/common/src/main/java/com/cursedcauldron/wildbackport/client/animation/WardenAnimations.java new file mode 100644 index 0000000..b4a5281 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/client/animation/WardenAnimations.java @@ -0,0 +1,15 @@ +package com.cursedcauldron.wildbackport.client.animation; + +import com.cursedcauldron.wildbackport.client.animation.api.Animation; +import com.cursedcauldron.wildbackport.client.animation.api.AnimationHelper; +import com.cursedcauldron.wildbackport.client.animation.api.Keyframe; +import com.cursedcauldron.wildbackport.client.animation.api.Transformation; + +public class WardenAnimations { + public static final Animation EMERGING = Animation.Builder.create(6.68f).addBoneAnimation("body", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.52f, AnimationHelper.rotation(0.0f, 0.0f, -22.5f), Transformation.Interpolations.CATMULL), new Keyframe(1.2f, AnimationHelper.rotation(0.0f, 0.0f, -7.5f), Transformation.Interpolations.CATMULL), new Keyframe(1.68f, AnimationHelper.rotation(0.0f, 0.0f, 10.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.8f, AnimationHelper.rotation(0.0f, 0.0f, 10.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.28f, AnimationHelper.rotation(0.0f, 0.0f, 10.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.88f, AnimationHelper.rotation(0.0f, 0.0f, 10.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.76f, AnimationHelper.rotation(25.0f, 0.0f, -7.5f), Transformation.Interpolations.CATMULL), new Keyframe(3.92f, AnimationHelper.rotation(35.0f, 0.0f, -7.5f), Transformation.Interpolations.CATMULL), new Keyframe(4.08f, AnimationHelper.rotation(25.0f, 0.0f, -7.5f), Transformation.Interpolations.CATMULL), new Keyframe(4.44f, AnimationHelper.rotation(47.5f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.56f, AnimationHelper.rotation(47.5f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.68f, AnimationHelper.rotation(47.5f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(5.0f, AnimationHelper.rotation(70.0f, 0.0f, 2.5f), Transformation.Interpolations.CATMULL), new Keyframe(5.8f, AnimationHelper.rotation(70.0f, 0.0f, 2.5f), Transformation.Interpolations.CATMULL), new Keyframe(6.64f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("body", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0f, AnimationHelper.translate(0.0f, -63.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.52f, AnimationHelper.translate(0.0f, -56.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.2f, AnimationHelper.translate(0.0f, -32.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.68f, AnimationHelper.translate(0.0f, -32.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.8f, AnimationHelper.translate(0.0f, -32.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.28f, AnimationHelper.translate(0.0f, -32.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.88f, AnimationHelper.translate(0.0f, -32.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.16f, AnimationHelper.translate(0.0f, -27.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.76f, AnimationHelper.translate(0.0f, -14.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.92f, AnimationHelper.translate(0.0f, -11.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.08f, AnimationHelper.translate(0.0f, -14.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.44f, AnimationHelper.translate(0.0f, -6.0f, -3.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.56f, AnimationHelper.translate(0.0f, -4.0f, -3.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.68f, AnimationHelper.translate(0.0f, -6.0f, -3.0f), Transformation.Interpolations.CATMULL), new Keyframe(5.0f, AnimationHelper.translate(0.0f, -3.0f, -4.0f), Transformation.Interpolations.CATMULL), new Keyframe(5.8f, AnimationHelper.translate(0.0f, -3.0f, -4.0f), Transformation.Interpolations.CATMULL), new Keyframe(6.64f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("head", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.52f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.92f, AnimationHelper.rotation(0.74f, 0.0f, -40.38f), Transformation.Interpolations.CATMULL), new Keyframe(1.16f, AnimationHelper.rotation(-67.5f, 0.0f, -2.5f), Transformation.Interpolations.CATMULL), new Keyframe(1.24f, AnimationHelper.rotation(-67.5f, 0.0f, -2.5f), Transformation.Interpolations.CATMULL), new Keyframe(1.32f, AnimationHelper.rotation(-47.5f, 0.0f, -2.5f), Transformation.Interpolations.CATMULL), new Keyframe(1.4f, AnimationHelper.rotation(-67.5f, 0.0f, -2.5f), Transformation.Interpolations.CATMULL), new Keyframe(1.68f, AnimationHelper.rotation(-67.5f, 0.0f, 15.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.76f, AnimationHelper.rotation(-67.5f, 0.0f, -5.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.84f, AnimationHelper.rotation(-52.5f, 0.0f, -5.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.92f, AnimationHelper.rotation(-67.5f, 0.0f, -5.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.64f, AnimationHelper.rotation(-17.5f, 0.0f, -10.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.76f, AnimationHelper.rotation(70.0f, 0.0f, 12.5f), Transformation.Interpolations.CATMULL), new Keyframe(4.04f, AnimationHelper.rotation(70.0f, 0.0f, 12.5f), Transformation.Interpolations.CATMULL), new Keyframe(4.12f, AnimationHelper.rotation(80.0f, 0.0f, 12.5f), Transformation.Interpolations.CATMULL), new Keyframe(4.24f, AnimationHelper.rotation(70.0f, 0.0f, 12.5f), Transformation.Interpolations.CATMULL), new Keyframe(5.0f, AnimationHelper.rotation(77.5f, 0.0f, -2.5f), Transformation.Interpolations.CATMULL), new Keyframe(6.64f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("head", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.52f, AnimationHelper.translate(-8.0f, -11.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.92f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.24f, AnimationHelper.translate(0.0f, 0.47f, -0.95f), Transformation.Interpolations.CATMULL), new Keyframe(1.32f, AnimationHelper.translate(0.0f, 0.47f, -0.95f), Transformation.Interpolations.CATMULL), new Keyframe(1.4f, AnimationHelper.translate(0.0f, 0.47f, -0.95f), Transformation.Interpolations.CATMULL), new Keyframe(1.68f, AnimationHelper.translate(0.0f, 1.0f, -2.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.76f, AnimationHelper.translate(0.0f, 1.0f, -2.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.84f, AnimationHelper.translate(0.0f, 1.0f, -2.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.92f, AnimationHelper.translate(0.0f, 1.0f, -2.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.64f, AnimationHelper.translate(0.0f, -2.0f, -2.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.76f, AnimationHelper.translate(0.0f, -4.0f, 1.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.04f, AnimationHelper.translate(0.0f, -1.0f, 1.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.12f, AnimationHelper.translate(0.0f, -1.0f, 1.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.24f, AnimationHelper.translate(0.0f, -1.0f, 1.0f), Transformation.Interpolations.CATMULL), new Keyframe(5.0f, AnimationHelper.translate(0.0f, -1.0f, 1.0f), Transformation.Interpolations.CATMULL), new Keyframe(6.64f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("right_ear", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.52f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.28f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.88f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.36f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.56f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(5.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(5.8f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(6.64f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("right_ear", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.52f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.28f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.88f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.36f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.56f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(5.0f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(5.8f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(6.64f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("left_ear", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.52f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.28f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.88f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.36f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.56f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(5.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(5.8f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(6.64f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("left_ear", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.52f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.28f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.88f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.36f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.56f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(5.0f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(5.8f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(6.64f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("right_arm", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.52f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.2f, AnimationHelper.rotation(-152.5f, 2.5f, 7.5f), Transformation.Interpolations.CATMULL), new Keyframe(1.68f, AnimationHelper.rotation(-180.0f, 12.5f, -10.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.8f, AnimationHelper.rotation(-90.0f, 12.5f, -10.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.28f, AnimationHelper.rotation(-90.0f, 12.5f, -10.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.88f, AnimationHelper.rotation(-90.0f, 12.5f, -10.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.08f, AnimationHelper.rotation(-95.0f, 12.5f, -10.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.24f, AnimationHelper.rotation(-83.93f, 3.93f, 5.71f), Transformation.Interpolations.CATMULL), new Keyframe(3.36f, AnimationHelper.rotation(-80.0f, 7.5f, 17.5f), Transformation.Interpolations.CATMULL), new Keyframe(3.76f, AnimationHelper.rotation(-67.5f, 2.5f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.08f, AnimationHelper.rotation(-67.5f, 2.5f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.44f, AnimationHelper.rotation(-55.0f, 2.5f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.56f, AnimationHelper.rotation(-60.0f, 2.5f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.68f, AnimationHelper.rotation(-55.0f, 2.5f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(5.0f, AnimationHelper.rotation(-67.5f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(5.56f, AnimationHelper.rotation(-50.45f, 0.0f, 2.69f), Transformation.Interpolations.CATMULL), new Keyframe(6.08f, AnimationHelper.rotation(-62.72f, 0.0f, 4.3f), Transformation.Interpolations.CATMULL), new Keyframe(6.64f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("right_arm", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.52f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.2f, AnimationHelper.translate(0.0f, -21.0f, 9.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.68f, AnimationHelper.translate(2.0f, -2.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.8f, AnimationHelper.translate(2.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.28f, AnimationHelper.translate(2.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.88f, AnimationHelper.translate(2.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.08f, AnimationHelper.translate(2.0f, -2.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.24f, AnimationHelper.translate(2.0f, 2.71f, 3.86f), Transformation.Interpolations.CATMULL), new Keyframe(3.36f, AnimationHelper.translate(2.0f, 1.0f, 5.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.76f, AnimationHelper.translate(2.0f, 3.0f, 3.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.08f, AnimationHelper.translate(2.0f, 3.0f, 3.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.44f, AnimationHelper.translate(2.67f, 4.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.56f, AnimationHelper.translate(2.67f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.68f, AnimationHelper.translate(2.67f, 4.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(5.0f, AnimationHelper.translate(0.67f, 3.0f, 4.0f), Transformation.Interpolations.CATMULL), new Keyframe(6.64f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("left_arm", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.12f, AnimationHelper.rotation(-167.5f, -17.5f, -7.5f), Transformation.Interpolations.CATMULL), new Keyframe(0.6f, AnimationHelper.rotation(-167.5f, -17.5f, -7.5f), Transformation.Interpolations.CATMULL), new Keyframe(0.88f, AnimationHelper.rotation(-175.0f, -17.5f, 15.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.16f, AnimationHelper.rotation(-190.0f, -17.5f, 5.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.28f, AnimationHelper.rotation(-90.0f, -5.0f, 5.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.68f, AnimationHelper.rotation(-90.0f, -17.5f, -12.5f), Transformation.Interpolations.CATMULL), new Keyframe(1.8f, AnimationHelper.rotation(-90.0f, -17.5f, -12.5f), Transformation.Interpolations.CATMULL), new Keyframe(2.28f, AnimationHelper.rotation(-90.0f, -17.5f, -12.5f), Transformation.Interpolations.CATMULL), new Keyframe(2.88f, AnimationHelper.rotation(-90.0f, -17.5f, -12.5f), Transformation.Interpolations.CATMULL), new Keyframe(3.04f, AnimationHelper.rotation(-81.29f, -10.64f, -14.21f), Transformation.Interpolations.CATMULL), new Keyframe(3.16f, AnimationHelper.rotation(-83.5f, -5.5f, -15.5f), Transformation.Interpolations.CATMULL), new Keyframe(3.76f, AnimationHelper.rotation(-62.5f, -7.5f, 5.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.92f, AnimationHelper.rotation(-58.75f, -3.75f, 5.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.08f, AnimationHelper.rotation(-55.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.44f, AnimationHelper.rotation(-52.5f, 0.0f, 5.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.56f, AnimationHelper.rotation(-50.0f, 0.0f, 5.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.68f, AnimationHelper.rotation(-52.5f, 0.0f, 5.0f), Transformation.Interpolations.CATMULL), new Keyframe(5.0f, AnimationHelper.rotation(-72.5f, -2.5f, 5.0f), Transformation.Interpolations.CATMULL), new Keyframe(5.56f, AnimationHelper.rotation(-57.5f, -4.54f, 2.99f), Transformation.Interpolations.CATMULL), new Keyframe(6.08f, AnimationHelper.rotation(-70.99f, -5.77f, 1.78f), Transformation.Interpolations.CATMULL), new Keyframe(6.64f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("left_arm", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.12f, AnimationHelper.translate(0.0f, -8.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.6f, AnimationHelper.translate(0.0f, -8.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.88f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.2f, AnimationHelper.translate(-2.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.68f, AnimationHelper.translate(-4.0f, 3.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.8f, AnimationHelper.translate(-4.0f, 3.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.28f, AnimationHelper.translate(-4.0f, 3.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.88f, AnimationHelper.translate(-4.0f, 3.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.04f, AnimationHelper.translate(-3.23f, 5.7f, 4.97f), Transformation.Interpolations.CATMULL), new Keyframe(3.16f, AnimationHelper.translate(-1.49f, 2.22f, 5.25f), Transformation.Interpolations.CATMULL), new Keyframe(3.76f, AnimationHelper.translate(-1.14f, 1.71f, 1.86f), Transformation.Interpolations.CATMULL), new Keyframe(3.92f, AnimationHelper.translate(-1.14f, 1.21f, 3.86f), Transformation.Interpolations.CATMULL), new Keyframe(4.08f, AnimationHelper.translate(-1.14f, 2.71f, 4.86f), Transformation.Interpolations.CATMULL), new Keyframe(4.44f, AnimationHelper.translate(-1.0f, 1.0f, 3.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.56f, AnimationHelper.translate(0.0f, 1.0f, 1.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.68f, AnimationHelper.translate(0.0f, 1.0f, 3.0f), Transformation.Interpolations.CATMULL), new Keyframe(5.0f, AnimationHelper.translate(-2.0f, 0.0f, 4.0f), Transformation.Interpolations.CATMULL), new Keyframe(6.64f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("right_leg", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.52f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.28f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.88f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.36f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.32f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.48f, AnimationHelper.rotation(55.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.6f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(5.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(5.8f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(6.64f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("right_leg", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0f, AnimationHelper.translate(0.0f, -63.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.52f, AnimationHelper.translate(0.0f, -56.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.2f, AnimationHelper.translate(0.0f, -32.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.68f, AnimationHelper.translate(0.0f, -32.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.8f, AnimationHelper.translate(0.0f, -32.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.28f, AnimationHelper.translate(0.0f, -32.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.88f, AnimationHelper.translate(0.0f, -32.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.36f, AnimationHelper.translate(0.0f, -22.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.76f, AnimationHelper.translate(0.0f, -12.28f, 2.48f), Transformation.Interpolations.CATMULL), new Keyframe(3.92f, AnimationHelper.translate(0.0f, -9.28f, 2.48f), Transformation.Interpolations.CATMULL), new Keyframe(4.08f, AnimationHelper.translate(0.0f, -12.28f, 2.48f), Transformation.Interpolations.CATMULL), new Keyframe(4.32f, AnimationHelper.translate(0.0f, -4.14f, 4.14f), Transformation.Interpolations.CATMULL), new Keyframe(4.48f, AnimationHelper.translate(0.0f, -0.57f, -8.43f), Transformation.Interpolations.CATMULL), new Keyframe(4.6f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(5.0f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(5.8f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(6.64f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("left_leg", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.52f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.28f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.88f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.36f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.84f, AnimationHelper.rotation(20.0f, 0.0f, -17.5f), Transformation.Interpolations.CATMULL), new Keyframe(4.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.68f, AnimationHelper.rotation(20.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.84f, AnimationHelper.rotation(10.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(5.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(5.8f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(6.64f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("left_leg", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0f, AnimationHelper.translate(0.0f, -63.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.52f, AnimationHelper.translate(0.0f, -56.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.2f, AnimationHelper.translate(0.0f, -32.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.68f, AnimationHelper.translate(0.0f, -32.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.8f, AnimationHelper.translate(0.0f, -32.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.28f, AnimationHelper.translate(0.0f, -32.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.88f, AnimationHelper.translate(0.0f, -32.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.36f, AnimationHelper.translate(0.0f, -22.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.84f, AnimationHelper.translate(-4.0f, 2.0f, -7.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.0f, AnimationHelper.translate(-4.0f, 0.0f, -5.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.68f, AnimationHelper.translate(-4.0f, 0.0f, -9.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.84f, AnimationHelper.translate(-2.0f, 2.0f, -3.5f), Transformation.Interpolations.CATMULL), new Keyframe(5.0f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(5.8f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(6.64f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).build(); + public static final Animation DIGGING = Animation.Builder.create(5.0f).addBoneAnimation("body", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.25f, AnimationHelper.rotation(4.13441f, 0.94736f, 1.2694f), Transformation.Interpolations.CATMULL), new Keyframe(0.5f, AnimationHelper.rotation(50.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.7083f, AnimationHelper.rotation(54.45407f, -13.53935f, -18.14183f), Transformation.Interpolations.CATMULL), new Keyframe(1.0417f, AnimationHelper.rotation(59.46442f, -10.8885f, 35.7954f), Transformation.Interpolations.CATMULL), new Keyframe(1.3333f, AnimationHelper.rotation(82.28261f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.625f, AnimationHelper.rotation(53.23606f, 10.04715f, -29.72932f), Transformation.Interpolations.CATMULL), new Keyframe(2.2083f, AnimationHelper.rotation(-17.71739f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.5417f, AnimationHelper.rotation(112.28261f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.6667f, AnimationHelper.rotation(116.06889f, 5.11581f, -24.50117f), Transformation.Interpolations.CATMULL), new Keyframe(2.8333f, AnimationHelper.rotation(121.56244f, -4.17248f, 19.57737f), Transformation.Interpolations.CATMULL), new Keyframe(3.0417f, AnimationHelper.rotation(138.5689f, 5.11581f, -24.50117f), Transformation.Interpolations.CATMULL), new Keyframe(3.25f, AnimationHelper.rotation(144.06244f, -4.17248f, 19.57737f), Transformation.Interpolations.CATMULL), new Keyframe(3.375f, AnimationHelper.rotation(147.28261f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.625f, AnimationHelper.rotation(147.28261f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.875f, AnimationHelper.rotation(134.36221f, 8.81113f, -8.90172f), Transformation.Interpolations.CATMULL), new Keyframe(4.0417f, AnimationHelper.rotation(132.05966f, -8.35927f, 9.70506f), Transformation.Interpolations.CATMULL), new Keyframe(4.25f, AnimationHelper.rotation(134.36221f, 8.81113f, -8.90172f), Transformation.Interpolations.CATMULL), new Keyframe(4.5f, AnimationHelper.rotation(147.5f, 0.0f, 0.0f), Transformation.Interpolations.LINEAL))).addBoneAnimation("body", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.5f, AnimationHelper.translate(0.0f, -16.48454f, -6.5784f), Transformation.Interpolations.CATMULL), new Keyframe(0.7083f, AnimationHelper.translate(0.0f, -16.48454f, -6.5784f), Transformation.Interpolations.CATMULL), new Keyframe(1.0417f, AnimationHelper.translate(0.0f, -16.97f, -7.11f), Transformation.Interpolations.CATMULL), new Keyframe(1.625f, AnimationHelper.translate(0.0f, -13.97f, -7.11f), Transformation.Interpolations.CATMULL), new Keyframe(2.2083f, AnimationHelper.translate(0.0f, -11.48454f, -0.5784f), Transformation.Interpolations.CATMULL), new Keyframe(2.5417f, AnimationHelper.translate(0.0f, -16.48454f, -6.5784f), Transformation.Interpolations.CATMULL), new Keyframe(2.6667f, AnimationHelper.translate(0.0f, -20.27f, -5.42f), Transformation.Interpolations.CATMULL), new Keyframe(3.375f, AnimationHelper.translate(0.0f, -21.48454f, -5.5784f), Transformation.Interpolations.CATMULL), new Keyframe(4.0417f, AnimationHelper.translate(0.0f, -22.48454f, -5.5784f), Transformation.Interpolations.CATMULL), new Keyframe(4.5f, AnimationHelper.translate(0.0f, -40.0f, -8.0f), Transformation.Interpolations.LINEAL))).addBoneAnimation("head", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.6667f, AnimationHelper.rotation(12.5f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.2083f, AnimationHelper.rotation(12.5f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.75f, AnimationHelper.rotation(45.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.375f, AnimationHelper.rotation(-22.5f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.5417f, AnimationHelper.rotation(67.5f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.375f, AnimationHelper.rotation(67.5f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("head", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.375f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.LINEAL))).addBoneAnimation("right_arm", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.5f, AnimationHelper.rotation(-101.8036f, -21.29587f, 30.61478f), Transformation.Interpolations.CATMULL), new Keyframe(0.7083f, AnimationHelper.rotation(-101.8036f, -21.29587f, 30.61478f), Transformation.Interpolations.CATMULL), new Keyframe(1.0f, AnimationHelper.rotation(48.7585f, -17.61941f, 9.9865f), Transformation.Interpolations.CATMULL), new Keyframe(1.1667f, AnimationHelper.rotation(48.7585f, -17.61941f, 9.9865f), Transformation.Interpolations.CATMULL), new Keyframe(1.4583f, AnimationHelper.rotation(-101.8036f, -21.29587f, 30.61478f), Transformation.Interpolations.CATMULL), new Keyframe(1.75f, AnimationHelper.rotation(-89.04994f, -4.19657f, -1.47845f), Transformation.Interpolations.CATMULL), new Keyframe(2.2083f, AnimationHelper.rotation(-158.30728f, 3.7152f, -1.52352f), Transformation.Interpolations.CATMULL), new Keyframe(2.5417f, AnimationHelper.rotation(-89.04994f, -4.19657f, -1.47845f), Transformation.Interpolations.CATMULL), new Keyframe(4.375f, AnimationHelper.rotation(-120.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("right_arm", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.7083f, AnimationHelper.translate(2.22f, 0.0f, 0.86f), Transformation.Interpolations.CATMULL), new Keyframe(1.0f, AnimationHelper.translate(3.12f, 0.0f, 4.29f), Transformation.Interpolations.CATMULL), new Keyframe(2.2083f, AnimationHelper.translate(1.0f, 0.0f, 4.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.375f, AnimationHelper.translate(0.0f, 0.0f, 4.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("left_arm", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.2917f, AnimationHelper.rotation(-63.89288f, -0.52011f, 2.09491f), Transformation.Interpolations.CATMULL), new Keyframe(0.5f, AnimationHelper.rotation(-63.89288f, -0.52011f, 2.09491f), Transformation.Interpolations.CATMULL), new Keyframe(0.7083f, AnimationHelper.rotation(-62.87857f, 15.15061f, 9.97445f), Transformation.Interpolations.CATMULL), new Keyframe(0.9167f, AnimationHelper.rotation(-86.93642f, 17.45026f, 4.05284f), Transformation.Interpolations.CATMULL), new Keyframe(1.1667f, AnimationHelper.rotation(-86.93642f, 17.45026f, 4.05284f), Transformation.Interpolations.CATMULL), new Keyframe(1.4583f, AnimationHelper.rotation(-86.93642f, 17.45026f, 4.05284f), Transformation.Interpolations.CATMULL), new Keyframe(1.6667f, AnimationHelper.rotation(63.0984f, 8.83573f, -8.71284f), Transformation.Interpolations.CATMULL), new Keyframe(1.8333f, AnimationHelper.rotation(35.5984f, 8.83573f, -8.71284f), Transformation.Interpolations.CATMULL), new Keyframe(2.2083f, AnimationHelper.rotation(-153.27473f, -0.02953f, 3.5235f), Transformation.Interpolations.CATMULL), new Keyframe(2.5417f, AnimationHelper.rotation(-87.07754f, -0.02625f, 3.132f), Transformation.Interpolations.CATMULL), new Keyframe(4.375f, AnimationHelper.rotation(-120.0f, 0.0f, 0.0f), Transformation.Interpolations.LINEAL))).addBoneAnimation("left_arm", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.5f, AnimationHelper.translate(-0.28f, 5.0f, 10.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.7083f, AnimationHelper.translate(-1.51f, 4.35f, 4.33f), Transformation.Interpolations.CATMULL), new Keyframe(0.9167f, AnimationHelper.translate(-0.6f, 3.61f, 4.63f), Transformation.Interpolations.CATMULL), new Keyframe(1.1667f, AnimationHelper.translate(-0.6f, 3.61f, 0.63f), Transformation.Interpolations.CATMULL), new Keyframe(1.6667f, AnimationHelper.translate(-2.85f, -0.1f, 3.33f), Transformation.Interpolations.CATMULL), new Keyframe(2.2083f, AnimationHelper.translate(-1.0f, 0.0f, 4.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.375f, AnimationHelper.translate(0.0f, 0.0f, 4.0f), Transformation.Interpolations.LINEAL))).addBoneAnimation("right_leg", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.5f, AnimationHelper.rotation(113.27f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.7083f, AnimationHelper.rotation(113.27f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.3333f, AnimationHelper.rotation(113.27f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.5833f, AnimationHelper.rotation(182.5f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.8333f, AnimationHelper.rotation(120.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.0833f, AnimationHelper.rotation(182.5f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.2917f, AnimationHelper.rotation(120.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.5f, AnimationHelper.rotation(90.0f, 0.0f, 0.0f), Transformation.Interpolations.LINEAL))).addBoneAnimation("right_leg", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.5f, AnimationHelper.translate(0.0f, -13.98f, -2.37f), Transformation.Interpolations.CATMULL), new Keyframe(0.7083f, AnimationHelper.translate(0.0f, -13.98f, -2.37f), Transformation.Interpolations.CATMULL), new Keyframe(3.3333f, AnimationHelper.translate(0.0f, -13.98f, -2.37f), Transformation.Interpolations.CATMULL), new Keyframe(3.5833f, AnimationHelper.translate(0.0f, -7.0f, -3.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.8333f, AnimationHelper.translate(0.0f, -9.0f, -3.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.0833f, AnimationHelper.translate(0.0f, -16.71f, -3.69f), Transformation.Interpolations.CATMULL), new Keyframe(4.2917f, AnimationHelper.translate(0.0f, -28.0f, -5.0f), Transformation.Interpolations.LINEAL))).addBoneAnimation("left_leg", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.5f, AnimationHelper.rotation(114.98f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.7083f, AnimationHelper.rotation(114.98f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.3333f, AnimationHelper.rotation(114.98f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.5833f, AnimationHelper.rotation(90.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.8333f, AnimationHelper.rotation(172.5f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.0833f, AnimationHelper.rotation(90.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.2917f, AnimationHelper.rotation(197.5f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.5f, AnimationHelper.rotation(90.0f, 0.0f, 0.0f), Transformation.Interpolations.LINEAL))).addBoneAnimation("left_leg", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.5f, AnimationHelper.translate(0.0f, -14.01f, -2.35f), Transformation.Interpolations.CATMULL), new Keyframe(0.7083f, AnimationHelper.translate(0.0f, -14.01f, -2.35f), Transformation.Interpolations.CATMULL), new Keyframe(3.3333f, AnimationHelper.translate(0.0f, -14.01f, -2.35f), Transformation.Interpolations.CATMULL), new Keyframe(3.5833f, AnimationHelper.translate(0.0f, -5.0f, -4.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.8333f, AnimationHelper.translate(0.0f, -7.0f, -4.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.0833f, AnimationHelper.translate(0.0f, -15.5f, -3.76f), Transformation.Interpolations.CATMULL), new Keyframe(4.2917f, AnimationHelper.translate(0.0f, -28.0f, -5.0f), Transformation.Interpolations.LINEAL))).build(); + public static final Animation ROARING = Animation.Builder.create(4.2f).addBoneAnimation("body", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.24f, AnimationHelper.rotation(-25.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.6f, AnimationHelper.rotation(32.5f, 0.0f, -7.5f), Transformation.Interpolations.CATMULL), new Keyframe(1.84f, AnimationHelper.rotation(38.33f, 0.0f, 2.99f), Transformation.Interpolations.CATMULL), new Keyframe(2.08f, AnimationHelper.rotation(40.97f, 0.0f, -4.3f), Transformation.Interpolations.CATMULL), new Keyframe(2.36f, AnimationHelper.rotation(44.41f, 0.0f, 6.29f), Transformation.Interpolations.CATMULL), new Keyframe(3.0f, AnimationHelper.rotation(47.5f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.2f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("body", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.24f, AnimationHelper.translate(0.0f, -1.0f, 3.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.6f, AnimationHelper.translate(0.0f, -3.0f, -6.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.0f, AnimationHelper.translate(0.0f, -3.0f, -6.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.2f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("head", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.24f, AnimationHelper.rotation(-32.5f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.6f, AnimationHelper.rotation(-32.5f, 0.0f, -27.5f), Transformation.Interpolations.CATMULL), new Keyframe(1.8f, AnimationHelper.rotation(-32.5f, 0.0f, 26.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.04f, AnimationHelper.rotation(-32.5f, 0.0f, -27.5f), Transformation.Interpolations.CATMULL), new Keyframe(2.44f, AnimationHelper.rotation(-32.5f, 0.0f, 26.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.84f, AnimationHelper.rotation(-5.0f, 0.0f, -12.5f), Transformation.Interpolations.CATMULL), new Keyframe(4.2f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("head", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.24f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.6f, AnimationHelper.translate(0.0f, -2.0f, -6.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.2f, AnimationHelper.translate(0.0f, -2.0f, -6.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.48f, AnimationHelper.translate(0.0f, -2.0f, -6.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.2f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("right_ear", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.24f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.76f, AnimationHelper.rotation(0.0f, 0.0f, -10.85f), Transformation.Interpolations.CATMULL), new Keyframe(2.08f, AnimationHelper.rotation(0.0f, 0.0f, 12.5f), Transformation.Interpolations.CATMULL), new Keyframe(2.4f, AnimationHelper.rotation(0.0f, 0.0f, -10.85f), Transformation.Interpolations.CATMULL), new Keyframe(2.72f, AnimationHelper.rotation(0.0f, 0.0f, 12.5f), Transformation.Interpolations.CATMULL), new Keyframe(3.0f, AnimationHelper.rotation(0.0f, 0.0f, -10.85f), Transformation.Interpolations.CATMULL), new Keyframe(4.2f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("left_ear", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.24f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.76f, AnimationHelper.rotation(0.0f, 0.0f, -15.85f), Transformation.Interpolations.CATMULL), new Keyframe(2.08f, AnimationHelper.rotation(0.0f, 0.0f, 12.5f), Transformation.Interpolations.CATMULL), new Keyframe(2.4f, AnimationHelper.rotation(0.0f, 0.0f, -15.85f), Transformation.Interpolations.CATMULL), new Keyframe(2.72f, AnimationHelper.rotation(0.0f, 0.0f, 12.5f), Transformation.Interpolations.CATMULL), new Keyframe(3.0f, AnimationHelper.rotation(0.0f, 0.0f, -15.85f), Transformation.Interpolations.CATMULL), new Keyframe(4.2f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("right_arm", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.72f, AnimationHelper.rotation(-120.0f, 0.0f, -20.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.24f, AnimationHelper.rotation(-77.5f, 3.75f, 15.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.48f, AnimationHelper.rotation(67.5f, -32.5f, 20.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.48f, AnimationHelper.rotation(37.5f, -32.5f, 25.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.88f, AnimationHelper.rotation(27.6f, -17.1f, 32.5f), Transformation.Interpolations.CATMULL), new Keyframe(4.2f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("right_arm", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.72f, AnimationHelper.translate(3.0f, -2.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.48f, AnimationHelper.translate(4.0f, -2.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.48f, AnimationHelper.translate(4.0f, -2.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.2f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("left_arm", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.72f, AnimationHelper.rotation(-125.0f, 0.0f, 20.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.24f, AnimationHelper.rotation(-76.25f, -17.5f, -7.5f), Transformation.Interpolations.CATMULL), new Keyframe(1.48f, AnimationHelper.rotation(62.5f, 42.5f, -12.5f), Transformation.Interpolations.CATMULL), new Keyframe(2.48f, AnimationHelper.rotation(37.5f, 27.5f, -27.5f), Transformation.Interpolations.CATMULL), new Keyframe(2.88f, AnimationHelper.rotation(25.0f, 18.4f, -30.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.2f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("left_arm", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.72f, AnimationHelper.translate(-3.0f, -2.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.48f, AnimationHelper.translate(-4.0f, -2.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.48f, AnimationHelper.translate(-4.0f, -2.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(4.2f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).build(); + public static final Animation SNIFFING = Animation.Builder.create(4.16f).addBoneAnimation("body", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.56f, AnimationHelper.rotation(17.5f, 32.5f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.96f, AnimationHelper.rotation(0.0f, 32.5f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.2f, AnimationHelper.rotation(10.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.8f, AnimationHelper.rotation(10.0f, -30.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.32f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("head", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.68f, AnimationHelper.rotation(0.0f, 40.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.96f, AnimationHelper.rotation(-22.5f, 40.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.24f, AnimationHelper.rotation(0.0f, 20.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.52f, AnimationHelper.rotation(-35.0f, 20.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.76f, AnimationHelper.rotation(0.0f, 20.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.28f, AnimationHelper.rotation(0.0f, -20.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.88f, AnimationHelper.rotation(0.0f, -20.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.32f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("right_arm", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.96f, AnimationHelper.rotation(17.5f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.2f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.76f, AnimationHelper.rotation(-15.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.32f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("left_arm", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.96f, AnimationHelper.rotation(-15.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.2f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.76f, AnimationHelper.rotation(17.5f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.32f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).build(); + public static final Animation ATTACKING = Animation.Builder.create(0.33333f).addBoneAnimation("body", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.0417f, AnimationHelper.rotation(-22.5f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.2083f, AnimationHelper.rotation(22.5f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.3333f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("body", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.0417f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.2083f, AnimationHelper.translate(0.0f, -1.0f, -2.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.3333f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("head", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.0417f, AnimationHelper.rotation(22.5f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.25f, AnimationHelper.rotation(-30.17493f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.3333f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("head", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.0417f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.25f, AnimationHelper.translate(0.0f, -2.0f, -2.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.3333f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("right_arm", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.0417f, AnimationHelper.rotation(-120.36119f, 40.78947f, -20.94102f), Transformation.Interpolations.CATMULL), new Keyframe(0.1667f, AnimationHelper.rotation(-90.0f, -45.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.3333f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("right_arm", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.0417f, AnimationHelper.translate(4.0f, 0.0f, 5.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.1667f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.3333f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("left_arm", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.0417f, AnimationHelper.rotation(-120.36119f, -40.78947f, 20.94102f), Transformation.Interpolations.CATMULL), new Keyframe(0.1667f, AnimationHelper.rotation(-61.1632f, 42.85882f, 11.52421f), Transformation.Interpolations.CATMULL), new Keyframe(0.3333f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("left_arm", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.0417f, AnimationHelper.translate(-4.0f, 0.0f, 5.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.1667f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.3333f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).build(); + public static final Animation SONIC_BOOM = Animation.Builder.create(3.0f).addBoneAnimation("body", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.0833f, AnimationHelper.rotation(47.5f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.625f, AnimationHelper.rotation(55.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.9167f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.0f, AnimationHelper.rotation(-32.5f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.4583f, AnimationHelper.rotation(-32.5f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.7083f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.875f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("body", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.0833f, AnimationHelper.translate(0.0f, -3.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.625f, AnimationHelper.translate(0.0f, -4.0f, -1.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.9167f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.7083f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.875f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("right_ribcage", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.5417f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.7917f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.875f, AnimationHelper.rotation(0.0f, 125.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.5f, AnimationHelper.rotation(0.0f, 125.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.6667f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("left_ribcage", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.5417f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.7917f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.875f, AnimationHelper.rotation(0.0f, -125.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.5f, AnimationHelper.rotation(0.0f, -125.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.6667f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("head", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.0f, AnimationHelper.rotation(67.5f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.75f, AnimationHelper.rotation(80.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.9167f, AnimationHelper.rotation(-45.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.5f, AnimationHelper.rotation(-45.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.7083f, AnimationHelper.rotation(-45.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.875f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("head", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.9167f, AnimationHelper.translate(0.0f, 0.0f, -3.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.5f, AnimationHelper.translate(0.0f, 0.0f, -3.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.7083f, AnimationHelper.translate(0.0f, 0.0f, -3.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.875f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("right_arm", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.875f, AnimationHelper.rotation(-42.28659f, -32.69813f, -5.00825f), Transformation.Interpolations.CATMULL), new Keyframe(1.1667f, AnimationHelper.rotation(-29.83757f, -35.39626f, -45.28089f), Transformation.Interpolations.CATMULL), new Keyframe(1.3333f, AnimationHelper.rotation(-29.83757f, -35.39626f, -45.28089f), Transformation.Interpolations.CATMULL), new Keyframe(1.6667f, AnimationHelper.rotation(-72.28659f, -32.69813f, -5.00825f), Transformation.Interpolations.CATMULL), new Keyframe(1.8333f, AnimationHelper.rotation(35.26439f, -30.0f, 35.26439f), Transformation.Interpolations.CATMULL), new Keyframe(1.9167f, AnimationHelper.rotation(73.75484f, -13.0931f, 19.20518f), Transformation.Interpolations.CATMULL), new Keyframe(2.5f, AnimationHelper.rotation(73.75484f, -13.0931f, 19.20518f), Transformation.Interpolations.CATMULL), new Keyframe(2.75f, AnimationHelper.rotation(58.20713f, -21.1064f, 28.7261f), Transformation.Interpolations.CATMULL), new Keyframe(3.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("right_arm", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.8333f, AnimationHelper.translate(3.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.75f, AnimationHelper.translate(3.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.0f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("left_arm", new Transformation(Transformation.Targets.ROTATE, new Keyframe(0.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(0.875f, AnimationHelper.rotation(-33.80694f, 32.31058f, 6.87997f), Transformation.Interpolations.CATMULL), new Keyframe(1.1667f, AnimationHelper.rotation(-17.87827f, 34.62115f, 49.02433f), Transformation.Interpolations.CATMULL), new Keyframe(1.3333f, AnimationHelper.rotation(-17.87827f, 34.62115f, 49.02433f), Transformation.Interpolations.CATMULL), new Keyframe(1.6667f, AnimationHelper.rotation(-51.30694f, 32.31058f, 6.87997f), Transformation.Interpolations.CATMULL), new Keyframe(1.8333f, AnimationHelper.rotation(35.26439f, 30.0f, -35.26439f), Transformation.Interpolations.CATMULL), new Keyframe(1.9167f, AnimationHelper.rotation(73.75484f, 13.0931f, -19.20518f), Transformation.Interpolations.CATMULL), new Keyframe(2.5f, AnimationHelper.rotation(73.75484f, 13.0931f, -19.20518f), Transformation.Interpolations.CATMULL), new Keyframe(2.75f, AnimationHelper.rotation(58.20713f, 21.1064f, -28.7261f), Transformation.Interpolations.CATMULL), new Keyframe(3.0f, AnimationHelper.rotation(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).addBoneAnimation("left_arm", new Transformation(Transformation.Targets.TRANSLATE, new Keyframe(0.0f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(1.8333f, AnimationHelper.translate(-3.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(2.75f, AnimationHelper.translate(-3.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL), new Keyframe(3.0f, AnimationHelper.translate(0.0f, 0.0f, 0.0f), Transformation.Interpolations.CATMULL))).build(); +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/client/animation/api/Animated.java b/common/src/main/java/com/cursedcauldron/wildbackport/client/animation/api/Animated.java new file mode 100644 index 0000000..72bb6ca --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/client/animation/api/Animated.java @@ -0,0 +1,53 @@ +package com.cursedcauldron.wildbackport.client.animation.api; + +import com.mojang.math.Vector3f; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.model.geom.PartPose; + +//<> + +public interface Animated { + static void translate(ModelPart part, Vector3f vec) { + part.x += vec.x(); + part.y += vec.y(); + part.z += vec.z(); + } + + static void rotate(ModelPart part, Vector3f vec) { + part.xRot += vec.x(); + part.yRot += vec.y(); + part.zRot += vec.z(); + } + + static void scale(ModelPart part, Vector3f vec) { + ((Animated)(Object)part).increaseXScale(vec.x()); + ((Animated)(Object)part).increaseYScale(vec.y()); + ((Animated)(Object)part).increaseZScale(vec.z()); + } + + PartPose getDefaultPose(); + + void setDefaultPose(PartPose pose); + + static void resetPose(ModelPart part) { + part.loadPose(((Animated)(Object)part).getDefaultPose()); + } + + float xScale(); + + void setXScale(float x); + + void increaseXScale(float x); + + float yScale(); + + void setYScale(float y); + + void increaseYScale(float y); + + float zScale(); + + void setZScale(float z); + + void increaseZScale(float z); +} diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/client/animation/api/AnimatedModel.java b/common/src/main/java/com/cursedcauldron/wildbackport/client/animation/api/AnimatedModel.java new file mode 100644 index 0000000..89c6ab3 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/client/animation/api/AnimatedModel.java @@ -0,0 +1,42 @@ +package com.cursedcauldron.wildbackport.client.animation.api; + +import com.cursedcauldron.wildbackport.core.mixin.access.ModelPartAccessor; +import com.mojang.math.Vector3f; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.model.HierarchicalModel; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.Entity; + +import java.util.Optional; +import java.util.function.Function; + +//<> + +@Environment(EnvType.CLIENT) +public abstract class AnimatedModel extends HierarchicalModel { + private static final Vector3f CACHE = new Vector3f(); + + public AnimatedModel() { + this(RenderType::entityCutoutNoCull); + } + + public AnimatedModel(Function function) { + super(function); + } + + public Optional getChild(String name) { + return this.root().getAllParts().filter(part -> ((ModelPartAccessor)(Object)part).getChildren().containsKey(name)).findFirst().map(part -> part.getChild(name)); + } + + protected void animate(AnimationState state, Animation animation, float animationProgress) { + this.animate(state, animation, animationProgress, 1.0F); + } + + protected void animate(AnimationState animationState, Animation animation, float animationProgress, float speedMultiplier) { + animationState.run(animationProgress, speedMultiplier); + animationState.run(state -> AnimationHelper.animate(this, animation, state.runningTime(), 1.0F, CACHE)); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/client/animation/api/Animation.java b/common/src/main/java/com/cursedcauldron/wildbackport/client/animation/api/Animation.java new file mode 100644 index 0000000..042aa53 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/client/animation/api/Animation.java @@ -0,0 +1,40 @@ +package com.cursedcauldron.wildbackport.client.animation.api; + +import com.google.common.collect.Maps; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import org.apache.commons.compress.utils.Lists; + +import java.util.List; +import java.util.Map; + +@Environment(EnvType.CLIENT) +public record Animation(float lengthInSeconds, boolean looping, Map> boneAnimations) { + public static class Builder { + private final float lengthInSeconds; + private final Map> transformations = Maps.newHashMap(); + private boolean looping; + + public static Builder create(float lengthInSeconds) { + return new Builder(lengthInSeconds); + } + + private Builder(float lengthInSeconds) { + this.lengthInSeconds = lengthInSeconds; + } + + public Builder looping() { + this.looping = true; + return this; + } + + public Builder addBoneAnimation(String name2, Transformation transformation) { + this.transformations.computeIfAbsent(name2, name -> Lists.newArrayList()).add(transformation); + return this; + } + + public Animation build() { + return new Animation(this.lengthInSeconds, this.looping, this.transformations); + } + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/client/animation/api/AnimationHelper.java b/common/src/main/java/com/cursedcauldron/wildbackport/client/animation/api/AnimationHelper.java new file mode 100644 index 0000000..50c5446 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/client/animation/api/AnimationHelper.java @@ -0,0 +1,53 @@ +package com.cursedcauldron.wildbackport.client.animation.api; + +import com.mojang.math.Vector3f; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.util.Mth; + +import java.util.List; +import java.util.Map; +import java.util.Optional; + +//<> + +@Environment(EnvType.CLIENT) +public class AnimationHelper { + public static void animate(AnimatedModel model, Animation animation, long runningTime, float speed, Vector3f cache) { + float runningSeconds = getRunningSeconds(animation, runningTime); + + for (Map.Entry> animations : animation.boneAnimations().entrySet()) { + Optional modelPart = model.getChild(animations.getKey()); + List transformations = animations.getValue(); + modelPart.ifPresent(part -> transformations.forEach(transformation -> { + Keyframe[] keyframes = transformation.keyframes(); + int start = Math.max(0, Mth.binarySearch(0, keyframes.length, i -> runningSeconds <= keyframes[i].timestamp()) - 1); + int end = Math.min(keyframes.length - 1, start + 1); + Keyframe frameStart = keyframes[start]; + Keyframe frameEnd = keyframes[end]; + float current = runningSeconds - frameStart.timestamp(); + float delta = Mth.clamp(current / (frameEnd.timestamp() - frameStart.timestamp()), 0.0f, 1.0f); + frameEnd.interpolation().apply(cache, delta, keyframes, start, end, speed); + transformation.target().apply(part, cache); + })); + } + } + + private static float getRunningSeconds(Animation animation, long runningTime) { + float time = (float)runningTime / 1000.0f; + return animation.looping() ? time % animation.lengthInSeconds() : time; + } + + public static Vector3f translate(float x, float y, float z) { + return new Vector3f(x, -y, z); + } + + public static Vector3f rotation(float x, float y, float z) { + return new Vector3f(x * ((float)Math.PI / 180), y * ((float)Math.PI / 180), z * ((float)Math.PI / 180)); + } + + public static Vector3f scale(double x, double y, double z) { + return new Vector3f((float)(x - 1.0), (float)(y - 1.0), (float)(z - 1.0)); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/client/animation/api/AnimationState.java b/common/src/main/java/com/cursedcauldron/wildbackport/client/animation/api/AnimationState.java new file mode 100644 index 0000000..e5a669e --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/client/animation/api/AnimationState.java @@ -0,0 +1,45 @@ +package com.cursedcauldron.wildbackport.client.animation.api; + +import net.minecraft.util.Mth; + +import java.util.function.Consumer; + +//<> + +public class AnimationState { + private long startedAt = Long.MAX_VALUE; + private long runningTime; + + public void start(int ticks) { + this.startedAt = (long)ticks * 1000L / 20L; + this.runningTime = 0L; + } + + public void startIfNotRunning(int ticks) { + if (!this.isRunning()) this.start(ticks); + } + + public void stop() { + this.startedAt = Long.MAX_VALUE; + } + + public void run(Consumer consumer) { + if (this.isRunning()) consumer.accept(this); + } + + public void run(float animationProgress, float speedMultiplier) { + if (this.isRunning()) { + long runningAt = Mth.lfloor(animationProgress * 1000.0F / 20.0F); + this.runningTime += (long)((float)(runningAt - this.startedAt) * speedMultiplier); + this.startedAt = runningAt; + } + } + + public long runningTime() { + return this.runningTime; + } + + public boolean isRunning() { + return this.startedAt != Long.MAX_VALUE; + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/client/animation/api/Keyframe.java b/common/src/main/java/com/cursedcauldron/wildbackport/client/animation/api/Keyframe.java new file mode 100644 index 0000000..765cea3 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/client/animation/api/Keyframe.java @@ -0,0 +1,8 @@ +package com.cursedcauldron.wildbackport.client.animation.api; + +import com.mojang.math.Vector3f; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +@Environment(EnvType.CLIENT) +public record Keyframe(float timestamp, Vector3f target, Transformation.Interpolation interpolation) {} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/client/animation/api/Transformation.java b/common/src/main/java/com/cursedcauldron/wildbackport/client/animation/api/Transformation.java new file mode 100644 index 0000000..49e44ae --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/client/animation/api/Transformation.java @@ -0,0 +1,42 @@ +package com.cursedcauldron.wildbackport.client.animation.api; + +import com.cursedcauldron.wildbackport.common.utils.MathUtils; +import com.mojang.math.Vector3f; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.util.Mth; + +@Environment(EnvType.CLIENT) +public record Transformation(Target target, Keyframe... keyframes) { + public interface Target { + void apply(ModelPart part, Vector3f vector); + } + + public static class Interpolations { + public static final Interpolation LINEAL = (cache, delta, keyframes, start, end, speed) -> { + Vector3f frameStart = keyframes[start].target(); + Vector3f frameEnd = keyframes[end].target(); + cache.set(Mth.lerp(delta, frameStart.x(), frameEnd.x()) * speed, Mth.lerp(delta, frameStart.y(), frameEnd.y()) * speed, Mth.lerp(delta, frameStart.z(), frameEnd.z()) * speed); + return cache; + }; + public static final Interpolation CATMULL = (cache, delta, keyframes, start, end, speed) -> { + Vector3f frameStartPoint = keyframes[Math.max(0, start - 1)].target(); + Vector3f frameStart = keyframes[start].target(); + Vector3f frameEnd = keyframes[end].target(); + Vector3f frameEndPoint = keyframes[Math.min(keyframes.length - 1, end + 1)].target(); + cache.set(MathUtils.catmullrom(delta, frameStartPoint.x(), frameStart.x(), frameEnd.x(), frameEndPoint.x()) * speed, MathUtils.catmullrom(delta, frameStartPoint.y(), frameStart.y(), frameEnd.y(), frameEndPoint.y()) * speed, MathUtils.catmullrom(delta, frameStartPoint.z(), frameStart.z(), frameEnd.z(), frameEndPoint.z()) * speed); + return cache; + }; + } + + public static class Targets { + public static final Target TRANSLATE = Animated::translate; + public static final Target ROTATE = Animated::rotate; + public static final Target SCALE = Animated::scale; + } + + public interface Interpolation { + Vector3f apply(Vector3f cache, float delta, Keyframe[] keyframes, int start, int end, float speed); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/client/particle/SculkChargeParticle.java b/common/src/main/java/com/cursedcauldron/wildbackport/client/particle/SculkChargeParticle.java new file mode 100644 index 0000000..2f69920 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/client/particle/SculkChargeParticle.java @@ -0,0 +1,52 @@ +package com.cursedcauldron.wildbackport.client.particle; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.particle.Particle; +import net.minecraft.client.particle.ParticleProvider; +import net.minecraft.client.particle.ParticleRenderType; +import net.minecraft.client.particle.SpriteSet; +import net.minecraft.client.particle.TextureSheetParticle; + +@Environment(EnvType.CLIENT) +public class SculkChargeParticle extends TextureSheetParticle { + private final SpriteSet sprites; + + public SculkChargeParticle(ClientLevel level, double x, double y, double z, double xMotion, double yMotion, double zMotion, SpriteSet sprites) { + super(level, x, y, z, xMotion, yMotion, zMotion); + this.sprites = sprites; + this.friction = 0.96F; + this.scale(1.5F); + this.hasPhysics = false; + this.setSpriteFromAge(sprites); + } + + @Override + protected int getLightColor(float delta) { + return 240; + } + + @Override + public ParticleRenderType getRenderType() { + return ParticleRenderType.PARTICLE_SHEET_TRANSLUCENT; + } + + @Override + public void tick() { + super.tick(); + this.setSpriteFromAge(this.sprites); + } + + public record Provider(SpriteSet sprites) implements ParticleProvider { + @Override + public Particle createParticle(SculkChargeParticleOptions options, ClientLevel level, double x, double y, double z, double xMotion, double yMotion, double zMotion) { + SculkChargeParticle particle = new SculkChargeParticle(level, x, y, z, xMotion, yMotion, zMotion, this.sprites); + particle.setAlpha(1.0F); + particle.setParticleSpeed(xMotion, yMotion, zMotion); + particle.oRoll = particle.roll = options.roll(); + particle.setLifetime(level.getRandom().nextInt(12) + 8); + return particle; + } + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/client/particle/SculkChargeParticleOptions.java b/common/src/main/java/com/cursedcauldron/wildbackport/client/particle/SculkChargeParticleOptions.java new file mode 100644 index 0000000..1453765 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/client/particle/SculkChargeParticleOptions.java @@ -0,0 +1,48 @@ +package com.cursedcauldron.wildbackport.client.particle; + +import com.cursedcauldron.wildbackport.client.registry.WBParticleTypes; +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.core.Registry; +import net.minecraft.core.particles.ParticleOptions; +import net.minecraft.core.particles.ParticleType; +import net.minecraft.network.FriendlyByteBuf; + +import java.util.Locale; + +public record SculkChargeParticleOptions(float roll) implements ParticleOptions { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> { + return instance.group(Codec.FLOAT.fieldOf("roll").forGetter(options -> { + return options.roll; + })).apply(instance, SculkChargeParticleOptions::new); + }); + + public static final Deserializer DESERIALIZER = new Deserializer<>() { + @Override + public SculkChargeParticleOptions fromCommand(ParticleType type, StringReader reader) throws CommandSyntaxException { + return new SculkChargeParticleOptions(reader.readFloat()); + } + + @Override + public SculkChargeParticleOptions fromNetwork(ParticleType type, FriendlyByteBuf buf) { + return new SculkChargeParticleOptions(buf.readFloat()); + } + }; + + @Override + public ParticleType getType() { + return WBParticleTypes.SCULK_CHARGE.get(); + } + + @Override + public void writeToNetwork(FriendlyByteBuf buf) { + buf.writeFloat(this.roll); + } + + @Override + public String writeToString() { + return String.format(Locale.ROOT, "%s %.2f", Registry.PARTICLE_TYPE.getId(this.getType()), this.roll); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/client/particle/SculkChargePopParticle.java b/common/src/main/java/com/cursedcauldron/wildbackport/client/particle/SculkChargePopParticle.java new file mode 100644 index 0000000..0c669d4 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/client/particle/SculkChargePopParticle.java @@ -0,0 +1,54 @@ +package com.cursedcauldron.wildbackport.client.particle; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.particle.Particle; +import net.minecraft.client.particle.ParticleProvider; +import net.minecraft.client.particle.ParticleRenderType; +import net.minecraft.client.particle.SpriteSet; +import net.minecraft.client.particle.TextureSheetParticle; +import net.minecraft.core.particles.SimpleParticleType; + +//<> + +@Environment(EnvType.CLIENT) +public class SculkChargePopParticle extends TextureSheetParticle { + private final SpriteSet sprites; + + public SculkChargePopParticle(ClientLevel level, double x, double y, double z, double xMotion, double yMotion, double zMotion, SpriteSet sprites) { + super(level, x, y, z, xMotion, yMotion, zMotion); + this.sprites = sprites; + this.friction = 0.96F; + this.scale(1.0F); + this.hasPhysics = false; + this.setSpriteFromAge(sprites); + } + + @Override + protected int getLightColor(float delta) { + return 240; + } + + @Override + public ParticleRenderType getRenderType() { + return ParticleRenderType.PARTICLE_SHEET_TRANSLUCENT; + } + + @Override + public void tick() { + super.tick(); + this.setSpriteFromAge(this.sprites); + } + + public record Provider(SpriteSet sprites) implements ParticleProvider { + @Override + public Particle createParticle(SimpleParticleType type, ClientLevel level, double x, double y, double z, double xMotion, double yMotion, double zMotion) { + SculkChargePopParticle particle = new SculkChargePopParticle(level, x, y, z, xMotion, yMotion, zMotion, this.sprites); + particle.setAlpha(1.0F); + particle.setParticleSpeed(xMotion, yMotion, zMotion); + particle.setLifetime(level.getRandom().nextInt(4) + 6); + return particle; + } + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/client/particle/SculkSoulParticle.java b/common/src/main/java/com/cursedcauldron/wildbackport/client/particle/SculkSoulParticle.java new file mode 100644 index 0000000..7c500a1 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/client/particle/SculkSoulParticle.java @@ -0,0 +1,51 @@ +package com.cursedcauldron.wildbackport.client.particle; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.particle.Particle; +import net.minecraft.client.particle.ParticleProvider; +import net.minecraft.client.particle.ParticleRenderType; +import net.minecraft.client.particle.RisingParticle; +import net.minecraft.client.particle.SpriteSet; +import net.minecraft.core.particles.SimpleParticleType; + +//<> + +@Environment(EnvType.CLIENT) +public class SculkSoulParticle extends RisingParticle { + private final SpriteSet sprites; + + public SculkSoulParticle(ClientLevel level, double x, double y, double z, double xMotion, double yMotion, double zMotion, SpriteSet sprites) { + super(level, x, y, z, xMotion, yMotion, zMotion); + this.sprites = sprites; + this.getQuadSize(1.5F); + this.setSpriteFromAge(sprites); + } + + @Override + protected int getLightColor(float delta) { + return 240; + } + + @Override + public ParticleRenderType getRenderType() { + return ParticleRenderType.PARTICLE_SHEET_TRANSLUCENT; + } + + @Override + public void tick() { + super.tick(); + this.setSpriteFromAge(this.sprites); + } + + @Environment(EnvType.CLIENT) + public record Provider(SpriteSet sprites) implements ParticleProvider { + @Override + public Particle createParticle(SimpleParticleType type, ClientLevel level, double x, double y, double z, double xMotion, double yMotion, double zMotion) { + SculkSoulParticle particle = new SculkSoulParticle(level, x, y, z, xMotion, yMotion, zMotion, this.sprites); + particle.setAlpha(1.0F); + return particle; + } + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/client/particle/ShriekParticle.java b/common/src/main/java/com/cursedcauldron/wildbackport/client/particle/ShriekParticle.java new file mode 100644 index 0000000..88d71c8 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/client/particle/ShriekParticle.java @@ -0,0 +1,112 @@ +package com.cursedcauldron.wildbackport.client.particle; + +import com.mojang.blaze3d.vertex.VertexConsumer; +import com.mojang.math.Quaternion; +import com.mojang.math.Vector3f; +import net.minecraft.Util; +import net.minecraft.client.Camera; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.particle.Particle; +import net.minecraft.client.particle.ParticleProvider; +import net.minecraft.client.particle.ParticleRenderType; +import net.minecraft.client.particle.SpriteSet; +import net.minecraft.client.particle.TextureSheetParticle; +import net.minecraft.util.Mth; +import net.minecraft.world.phys.Vec3; + +import java.util.function.Consumer; + +public class ShriekParticle extends TextureSheetParticle { + private static final Vector3f AXIS = Util.make(new Vector3f(0.5F, 0.5F, 0.5F), Vector3f::normalize); + private static final Vector3f OFFSET = new Vector3f(-1.0F, -1.0F, 0.0F); + private int delay; + + protected ShriekParticle(ClientLevel level, double x, double y, double z, int delay) { + super(level, x, y, z); + this.quadSize = 0.85F; + this.delay = delay; + this.lifetime = 30; + this.gravity = 0.0F; + this.xd = 0.0D; + this.yd = 0.1D; + this.zd = 0.0D; + } + + @Override + public float getQuadSize(float tickDelta) { + return this.quadSize * Mth.clamp(((float)this.age + tickDelta) / (float)this.lifetime * 0.75F, 0.0F, 1.0F); + } + + @Override + public void render(VertexConsumer vertex, Camera camera, float tickDelta) { + if (this.delay > 0) return; + this.alpha = 1.0F - Mth.clamp(((float)this.age + tickDelta) / (float)this.lifetime * 0.75F, 0.0F, 1.0F); + this.render(vertex, camera, tickDelta, quaternion -> { + quaternion.mul(Vector3f.YP.rotation(0.0F)); + quaternion.mul(Vector3f.XP.rotation(-1.0472F)); + }); + this.render(vertex, camera, tickDelta, quaternion -> { + quaternion.mul(Vector3f.YP.rotation((float)(-Math.PI))); + quaternion.mul(Vector3f.XP.rotation(1.0472F)); + }); + } + + private void render(VertexConsumer vertex, Camera camera, float tickDelta, Consumer consumer) { + Vec3 pos = camera.getPosition(); + float x = (float)(Mth.lerp(tickDelta, this.xo, this.x) - pos.x()); + float y = (float)(Mth.lerp(tickDelta, this.yo, this.y) - pos.y()); + float z = (float)(Mth.lerp(tickDelta, this.zo, this.z) - pos.z()); + Quaternion quaternion = new Quaternion(AXIS, 0.0F, true); + consumer.accept(quaternion); + OFFSET.transform(quaternion); + Vector3f[] vectors = new Vector3f[] {new Vector3f(-1.0F, -1.0F, 0.0F), new Vector3f(-1.0F, 1.0F, 0.0F), new Vector3f(1.0F, 1.0F, 0.0F), new Vector3f(1.0F, -1.0F, 0.0F)}; + float quadSize = this.getQuadSize(tickDelta); + + for (int i = 0; i < 4; i++) { + Vector3f vector = vectors[i]; + vector.transform(quaternion); + vector.mul(quadSize); + vector.add(x, y, z); + } + + int light = this.getLightColor(tickDelta); + this.addVertex(vertex, vectors[0], this.getU1(), this.getV1(), light); + this.addVertex(vertex, vectors[1], this.getU1(), this.getV0(), light); + this.addVertex(vertex, vectors[2], this.getU0(), this.getV0(), light); + this.addVertex(vertex, vectors[3], this.getU0(), this.getV1(), light); + + } + + private void addVertex(VertexConsumer vertex, Vector3f vector, float u, float v, int light) { + vertex.vertex(vector.x(), vector.y(), vector.z()).uv(u, v).color(this.rCol, this.gCol, this.bCol, this.alpha).uv2(light).endVertex(); + } + + @Override + protected int getLightColor(float tint) { + return 240; + } + + @Override + public ParticleRenderType getRenderType() { + return ParticleRenderType.PARTICLE_SHEET_TRANSLUCENT; + } + + @Override + public void tick() { + if (this.delay > 0) { + --this.delay; + return; + } + super.tick(); + } + + public record Provider(SpriteSet spriteSet) implements ParticleProvider { + @Override + public Particle createParticle(ShriekParticleOptions options, ClientLevel level, double x, double y, double z, double xMotion, double yMotion, double zMotion) { + ShriekParticle particle = new ShriekParticle(level, x, y, z, options.delay()); + particle.pickSprite(this.spriteSet); + particle.setAlpha(1.0F); + return particle; + } + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/client/particle/ShriekParticleOptions.java b/common/src/main/java/com/cursedcauldron/wildbackport/client/particle/ShriekParticleOptions.java new file mode 100644 index 0000000..e1f84a6 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/client/particle/ShriekParticleOptions.java @@ -0,0 +1,53 @@ +package com.cursedcauldron.wildbackport.client.particle; + +import com.cursedcauldron.wildbackport.client.registry.WBParticleTypes; +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.core.Registry; +import net.minecraft.core.particles.ParticleOptions; +import net.minecraft.core.particles.ParticleType; +import net.minecraft.network.FriendlyByteBuf; + +import java.util.Locale; + +public record ShriekParticleOptions(int delay) implements ParticleOptions { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> { + return instance.group(Codec.INT.fieldOf("delay").forGetter(options -> { + return options.delay; + })).apply(instance, ShriekParticleOptions::new); + }); + + public static final ParticleOptions.Deserializer DESERIALIZER = new ParticleOptions.Deserializer<>() { + @Override + public ShriekParticleOptions fromCommand(ParticleType type, StringReader reader) throws CommandSyntaxException { + reader.expect(' '); + return new ShriekParticleOptions(reader.readInt()); + } + + @Override + public ShriekParticleOptions fromNetwork(ParticleType type, FriendlyByteBuf buf) { + return new ShriekParticleOptions(buf.readVarInt()); + } + }; + + @Override + public void writeToNetwork(FriendlyByteBuf buf) { + buf.writeVarInt(this.delay); + } + + @Override + public String writeToString() { + return String.format(Locale.ROOT, "%s %d", Registry.PARTICLE_TYPE.getId(this.getType()), this.delay); + } + + @Override + public ParticleType getType() { + return WBParticleTypes.SHRIEK.get(); + } + + public int getDelay() { + return this.delay; + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/client/particle/SonicBoomParticle.java b/common/src/main/java/com/cursedcauldron/wildbackport/client/particle/SonicBoomParticle.java new file mode 100644 index 0000000..520a149 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/client/particle/SonicBoomParticle.java @@ -0,0 +1,24 @@ +package com.cursedcauldron.wildbackport.client.particle; + +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.particle.HugeExplosionParticle; +import net.minecraft.client.particle.Particle; +import net.minecraft.client.particle.ParticleProvider; +import net.minecraft.client.particle.SpriteSet; +import net.minecraft.core.particles.SimpleParticleType; + +public class SonicBoomParticle extends HugeExplosionParticle { + public SonicBoomParticle(ClientLevel level, double x, double y, double z, double speed, SpriteSet sprites) { + super(level, x, y, z, speed, sprites); + this.lifetime = 16; + this.quadSize = 1.5F; + this.setSpriteFromAge(sprites); + } + + public record Provider(SpriteSet sprites) implements ParticleProvider { + @Override + public Particle createParticle(SimpleParticleType particle, ClientLevel level, double x, double y, double z, double xMotion, double yMotion, double zMotion) { + return new SonicBoomParticle(level, x, y, z, xMotion, this.sprites); + } + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/client/registry/WBCriteriaTriggers.java b/common/src/main/java/com/cursedcauldron/wildbackport/client/registry/WBCriteriaTriggers.java new file mode 100644 index 0000000..bd038ad --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/client/registry/WBCriteriaTriggers.java @@ -0,0 +1,20 @@ +package com.cursedcauldron.wildbackport.client.registry; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.core.mixin.access.CriteriaTriggersAccessor; +import net.minecraft.advancements.CriterionTrigger; +import net.minecraft.advancements.critereon.KilledTrigger; +import net.minecraft.advancements.critereon.LocationTrigger; +import net.minecraft.resources.ResourceLocation; + +//<> + +public class WBCriteriaTriggers { + public static final KilledTrigger KILL_MOB_NEAR_SCULK_CATALYST = create(new KilledTrigger(new ResourceLocation(WildBackport.MOD_ID, "kill_mob_near_sculk_catalyst"))); +// public static final ItemUsedOnBlockTrigger ALLAY_DROP_ITEM_ON_BLOCK = create(new ItemUsedOnBlockTrigger(new ResourceLocation(WildBackport.MOD_ID, "kill_mob_near_sculk_catalyst"))); + public static final LocationTrigger AVOID_VIBRATION = create(new LocationTrigger(new ResourceLocation(WildBackport.MOD_ID, "avoid_vibration"))); + + public static > T create(T type) { + return CriteriaTriggersAccessor.callRegister(type); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/client/registry/WBParticleTypes.java b/common/src/main/java/com/cursedcauldron/wildbackport/client/registry/WBParticleTypes.java new file mode 100644 index 0000000..34cf720 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/client/registry/WBParticleTypes.java @@ -0,0 +1,39 @@ +package com.cursedcauldron.wildbackport.client.registry; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.client.particle.SculkChargeParticleOptions; +import com.cursedcauldron.wildbackport.client.particle.ShriekParticleOptions; +import com.cursedcauldron.wildbackport.core.api.CoreRegistry; +import com.cursedcauldron.wildbackport.core.mixin.access.SimpleParticleTypeAccessor; +import com.mojang.serialization.Codec; +import net.minecraft.core.Registry; +import net.minecraft.core.particles.ParticleOptions; +import net.minecraft.core.particles.ParticleType; +import net.minecraft.core.particles.SimpleParticleType; + +import java.util.function.Function; +import java.util.function.Supplier; + +//<> + +public class WBParticleTypes { + public static final CoreRegistry> PARTICLES = CoreRegistry.create(Registry.PARTICLE_TYPE, WildBackport.MOD_ID); + + public static final Supplier SCULK_SOUL = create("sculk_soul", false); + public static final Supplier> SCULK_CHARGE = create("sculk_charge", SculkChargeParticleOptions.DESERIALIZER, type -> SculkChargeParticleOptions.CODEC, true); + public static final Supplier SCULK_CHARGE_POP = create("sculk_charge_pop", true); + public static final Supplier> SHRIEK = create("shriek", ShriekParticleOptions.DESERIALIZER, type -> ShriekParticleOptions.CODEC, true); + public static final Supplier SONIC_BOOM = create("sonic_boom", true); + + private static Supplier create(String key, boolean alwaysShow) { + return PARTICLES.register(key, () -> SimpleParticleTypeAccessor.createSimpleParticleType(alwaysShow)); + } + + private static Supplier> create(String key, ParticleOptions.Deserializer deserializer, Function, Codec> function, boolean alwaysShow) { + return PARTICLES.register(key, () -> new ParticleType<>(alwaysShow, deserializer) { + @Override public Codec codec() { + return function.apply(this); + } + }); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/client/registry/WBSoundEvents.java b/common/src/main/java/com/cursedcauldron/wildbackport/client/registry/WBSoundEvents.java new file mode 100644 index 0000000..5466784 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/client/registry/WBSoundEvents.java @@ -0,0 +1,137 @@ +package com.cursedcauldron.wildbackport.client.registry; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.core.api.CoreRegistry; +import com.google.common.collect.ImmutableList; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.sounds.SoundEvent; + +import java.util.stream.IntStream; + +//<> + +public class WBSoundEvents { + public static final CoreRegistry SOUNDS = CoreRegistry.create(Registry.SOUND_EVENT, WildBackport.MOD_ID); + + // Blocks + public static final SoundEvent BLOCK_SCULK_VEIN_BREAK = create("block.sculk_vein.break"); + public static final SoundEvent BLOCK_SCULK_VEIN_FALL = create("block.sculk_vein.fall"); + public static final SoundEvent BLOCK_SCULK_VEIN_HIT = create("block.sculk_vein.hit"); + public static final SoundEvent BLOCK_SCULK_VEIN_PLACE = create("block.sculk_vein.place"); + public static final SoundEvent BLOCK_SCULK_VEIN_STEP = create("block.sculk_vein.step"); + public static final SoundEvent BLOCK_SCULK_CATALYST_BLOOM = create("block.sculk_catalyst.bloom"); + public static final SoundEvent BLOCK_SCULK_CATALYST_BREAK = create("block.sculk_catalyst.break"); + public static final SoundEvent BLOCK_SCULK_CATALYST_FALL = create("block.sculk_catalyst.fall"); + public static final SoundEvent BLOCK_SCULK_CATALYST_HIT = create("block.sculk_catalyst.hit"); + public static final SoundEvent BLOCK_SCULK_CATALYST_PLACE = create("block.sculk_catalyst.place"); + public static final SoundEvent BLOCK_SCULK_CATALYST_STEP = create("block.sculk_catalyst.step"); + public static final SoundEvent BLOCK_SCULK_SPREAD = create("block.sculk.spread"); + public static final SoundEvent BLOCK_SCULK_CHARGE = create("block.sculk.charge"); + public static final SoundEvent BLOCK_SCULK_BREAK = create("block.sculk.break"); + public static final SoundEvent BLOCK_SCULK_FALL = create("block.sculk.fall"); + public static final SoundEvent BLOCK_SCULK_HIT = create("block.sculk.hit"); + public static final SoundEvent BLOCK_SCULK_PLACE = create("block.sculk.place"); + public static final SoundEvent BLOCK_SCULK_STEP = create("block.sculk.step"); + public static final SoundEvent BLOCK_SCULK_SHRIEKER_BREAK = create("block.sculk_shrieker.break"); + public static final SoundEvent BLOCK_SCULK_SHRIEKER_FALL = create("block.sculk_shrieker.fall"); + public static final SoundEvent BLOCK_SCULK_SHRIEKER_HIT = create("block.sculk_shrieker.hit"); + public static final SoundEvent BLOCK_SCULK_SHRIEKER_PLACE = create("block.sculk_shrieker.place"); + public static final SoundEvent BLOCK_SCULK_SHRIEKER_STEP = create("block.sculk_shrieker.step"); + public static final SoundEvent BLOCK_SCULK_SHRIEKER_SHRIEK = create("block.sculk_shrieker.shriek"); + public static final SoundEvent BLOCK_FROGLIGHT_BREAK = create("block.froglight.break"); + public static final SoundEvent BLOCK_FROGLIGHT_FALL = create("block.froglight.fall"); + public static final SoundEvent BLOCK_FROGLIGHT_HIT = create("block.froglight.hit"); + public static final SoundEvent BLOCK_FROGLIGHT_PLACE = create("block.froglight.place"); + public static final SoundEvent BLOCK_FROGLIGHT_STEP = create("block.froglight.step"); + public static final SoundEvent BLOCK_FROGSPAWN_BREAK = create("block.frogspawn.break"); + public static final SoundEvent BLOCK_FROGSPAWN_FALL = create("block.frogspawn.fall"); + public static final SoundEvent BLOCK_FROGSPAWN_HATCH = create("block.frogspawn.hatch"); + public static final SoundEvent BLOCK_FROGSPAWN_HIT = create("block.frogspawn.hit"); + public static final SoundEvent BLOCK_FROGSPAWN_PLACE = create("block.frogspawn.place"); + public static final SoundEvent BLOCK_FROGSPAWN_STEP = create("block.frogspawn.step"); + public static final SoundEvent BLOCK_MANGROVE_ROOTS_BREAK = create("block.mangrove_roots.break"); + public static final SoundEvent BLOCK_MANGROVE_ROOTS_FALL = create("block.mangrove_roots.fall"); + public static final SoundEvent BLOCK_MANGROVE_ROOTS_HIT = create("block.mangrove_roots.hit"); + public static final SoundEvent BLOCK_MANGROVE_ROOTS_PLACE = create("block.mangrove_roots.place"); + public static final SoundEvent BLOCK_MANGROVE_ROOTS_STEP = create("block.mangrove_roots.step"); + public static final SoundEvent BLOCK_MUD_BREAK = create("block.mud.break"); + public static final SoundEvent BLOCK_MUD_FALL = create("block.mud.fall"); + public static final SoundEvent BLOCK_MUD_HIT = create("block.mud.hit"); + public static final SoundEvent BLOCK_MUD_PLACE = create("block.mud.place"); + public static final SoundEvent BLOCK_MUD_STEP = create("block.mud.step"); + public static final SoundEvent BLOCK_MUD_BRICKS_BREAK = create("block.mud_bricks.break"); + public static final SoundEvent BLOCK_MUD_BRICKS_FALL = create("block.mud_bricks.fall"); + public static final SoundEvent BLOCK_MUD_BRICKS_HIT = create("block.mud_bricks.hit"); + public static final SoundEvent BLOCK_MUD_BRICKS_PLACE = create("block.mud_bricks.place"); + public static final SoundEvent BLOCK_MUD_BRICKS_STEP = create("block.mud_bricks.step"); + public static final SoundEvent BLOCK_MUDDY_MANGROVE_ROOTS_BREAK = create("block.muddy_mangrove_roots.break"); + public static final SoundEvent BLOCK_MUDDY_MANGROVE_ROOTS_FALL = create("block.muddy_mangrove_roots.fall"); + public static final SoundEvent BLOCK_MUDDY_MANGROVE_ROOTS_HIT = create("block.muddy_mangrove_roots.hit"); + public static final SoundEvent BLOCK_MUDDY_MANGROVE_ROOTS_PLACE = create("block.muddy_mangrove_roots.place"); + public static final SoundEvent BLOCK_MUDDY_MANGROVE_ROOTS_STEP = create("block.muddy_mangrove_roots.step"); + public static final SoundEvent BLOCK_PACKED_MUD_BREAK = create("block.packed_mud.break"); + public static final SoundEvent BLOCK_PACKED_MUD_FALL = create("block.packed_mud.fall"); + public static final SoundEvent BLOCK_PACKED_MUD_HIT = create("block.packed_mud.hit"); + public static final SoundEvent BLOCK_PACKED_MUD_PLACE = create("block.packed_mud.place"); + public static final SoundEvent BLOCK_PACKED_MUD_STEP = create("block.packed_mud.step"); + + // Items + public static final SoundEvent BUCKED_EMPTY_TADPOLE = create("item.bucket.empty_tadpole"); + public static final SoundEvent BUCKED_FILL_TADPOLE = create("item.bucket.fill_tadpole"); + public static final ImmutableList GOAT_HORN_SOUND_VARIANTS = IntStream.range(0, 8).mapToObj(value -> { + return create("item.goat_horn.sound." + value); + }).collect(ImmutableList.toImmutableList()); + + // Entities + public static final SoundEvent ALLAY_AMBIENT_WITH_ITEM = create("entity.allay.ambient_with_item"); + public static final SoundEvent ALLAY_AMBIENT_WITHOUT_ITEM = create("entity.allay.ambient_without_item"); + public static final SoundEvent ALLAY_DEATH = create("entity.allay.death"); + public static final SoundEvent ALLAY_HURT = create("entity.allay.hurt"); + public static final SoundEvent ALLAY_ITEM_GIVEN = create("entity.allay.item_given"); + public static final SoundEvent ALLAY_ITEM_TAKEN = create("entity.allay.item_taken"); + public static final SoundEvent ALLAY_ITEM_THROW = create("entity.allay.item_thrown"); + public static final SoundEvent FROG_AMBIENT = create("entity.frog.ambient"); + public static final SoundEvent FROG_DEATH = create("entity.frog.death"); + public static final SoundEvent FROG_EAT = create("entity.frog.eat"); + public static final SoundEvent FROG_HURT = create("entity.frog.hurt"); + public static final SoundEvent FROG_LAY_SPAWN = create("entity.frog.lay_spawn"); + public static final SoundEvent FROG_LONG_JUMP = create("entity.frog.long_jump"); + public static final SoundEvent FROG_STEP = create("entity.frog.step"); + public static final SoundEvent FROG_TONGUE = create("entity.frog.tongue"); +// public static final SoundEvent PARROT_IMITATE_WARDEN = create("entity.parrot.imitate_warden"); + public static final SoundEvent TADPOLE_DEATH = create("entity.tadpole.death"); + public static final SoundEvent TADPOLE_FLOP = create("entity.tadpole.flop"); + public static final SoundEvent TADPOLE_GROW_UP = create("entity.tadpole.grow_up"); + public static final SoundEvent TADPOLE_HURT = create("entity.tadpole.hurt"); + public static final SoundEvent WARDEN_AMBIENT = create("entity.warden.ambient"); + public static final SoundEvent WARDEN_LISTENING = create("entity.warden.listening"); + public static final SoundEvent WARDEN_LISTENING_ANGRY = create("entity.warden.listening_angry"); + public static final SoundEvent WARDEN_ANGRY = create("entity.warden.angry"); + public static final SoundEvent WARDEN_HURT = create("entity.warden.hurt"); + public static final SoundEvent WARDEN_DEATH = create("entity.warden.death"); + public static final SoundEvent WARDEN_STEP = create("entity.warden.step"); + public static final SoundEvent WARDEN_TENDRIL_CLICKS = create("entity.warden.tendril_clicks"); + public static final SoundEvent WARDEN_HEARTBEAT = create("entity.warden.heartbeat"); + public static final SoundEvent WARDEN_AGITATED = create("entity.warden.agitated"); + public static final SoundEvent WARDEN_ATTACK_IMPACT = create("entity.warden.attack_impact"); + public static final SoundEvent WARDEN_ROAR = create("entity.warden.roar"); + public static final SoundEvent WARDEN_SNIFF = create("entity.warden.sniff"); + public static final SoundEvent WARDEN_EMERGE = create("entity.warden.emerge"); + public static final SoundEvent WARDEN_DIG = create("entity.warden.dig"); + public static final SoundEvent WARDEN_NEARBY_CLOSEST = create("entity.warden.nearby_closest"); + public static final SoundEvent WARDEN_NEARBY_CLOSER = create("entity.warden.nearby_closer"); + public static final SoundEvent WARDEN_NEARBY_CLOSE = create("entity.warden.nearby_close"); + public static final SoundEvent WARDEN_SONIC_BOOM = create("entity.warden.sonic_boom"); + public static final SoundEvent WARDEN_SONIC_CHARGE = create("entity.warden.sonic_charge"); + + // Music + public static final SoundEvent MUSIC_DISC_5 = create("music_disc.5"); +// public static final SoundEvent MUSIC_BIOME_DEEP_DARK = create("music.overworld.deep_dark"); + + public static SoundEvent create(String key) { + SoundEvent sound = new SoundEvent(new ResourceLocation(WildBackport.MOD_ID, key)); + SOUNDS.register(key, () -> sound); + return sound; + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/client/registry/WBSoundTypes.java b/common/src/main/java/com/cursedcauldron/wildbackport/client/registry/WBSoundTypes.java new file mode 100644 index 0000000..1e11432 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/client/registry/WBSoundTypes.java @@ -0,0 +1,25 @@ +package com.cursedcauldron.wildbackport.client.registry; + +import com.cursedcauldron.wildbackport.client.sound.CoreSoundType; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.world.level.block.SoundType; + +//<> + +public class WBSoundTypes { + public static final SoundType SCULK = create(WBSoundEvents.BLOCK_SCULK_BREAK, WBSoundEvents.BLOCK_SCULK_STEP, WBSoundEvents.BLOCK_SCULK_PLACE, WBSoundEvents.BLOCK_SCULK_HIT, WBSoundEvents.BLOCK_SCULK_FALL); + public static final SoundType SCULK_CATALYST = create(WBSoundEvents.BLOCK_SCULK_CATALYST_BREAK, WBSoundEvents.BLOCK_SCULK_CATALYST_STEP, WBSoundEvents.BLOCK_SCULK_CATALYST_PLACE, WBSoundEvents.BLOCK_SCULK_CATALYST_HIT, WBSoundEvents.BLOCK_SCULK_CATALYST_FALL); + public static final SoundType SCULK_VEIN = create(WBSoundEvents.BLOCK_SCULK_VEIN_BREAK, WBSoundEvents.BLOCK_SCULK_VEIN_STEP, WBSoundEvents.BLOCK_SCULK_VEIN_PLACE, WBSoundEvents.BLOCK_SCULK_VEIN_HIT, WBSoundEvents.BLOCK_SCULK_VEIN_FALL); + public static final SoundType SCULK_SHRIEKER = create(WBSoundEvents.BLOCK_SCULK_SHRIEKER_BREAK, WBSoundEvents.BLOCK_SCULK_SHRIEKER_STEP, WBSoundEvents.BLOCK_SCULK_SHRIEKER_PLACE, WBSoundEvents.BLOCK_SCULK_SHRIEKER_HIT, WBSoundEvents.BLOCK_SCULK_SHRIEKER_FALL); + public static final SoundType FROGLIGHT = create(WBSoundEvents.BLOCK_FROGLIGHT_BREAK, WBSoundEvents.BLOCK_FROGLIGHT_STEP, WBSoundEvents.BLOCK_FROGLIGHT_PLACE, WBSoundEvents.BLOCK_FROGLIGHT_HIT, WBSoundEvents.BLOCK_FROGLIGHT_FALL); + public static final SoundType FROGSPAWN = create(WBSoundEvents.BLOCK_FROGSPAWN_BREAK, WBSoundEvents.BLOCK_FROGSPAWN_STEP, WBSoundEvents.BLOCK_FROGSPAWN_PLACE, WBSoundEvents.BLOCK_FROGSPAWN_HIT, WBSoundEvents.BLOCK_FROGSPAWN_FALL); + public static final SoundType MANGROVE_ROOTS = create(WBSoundEvents.BLOCK_MANGROVE_ROOTS_BREAK, WBSoundEvents.BLOCK_MANGROVE_ROOTS_STEP, WBSoundEvents.BLOCK_MANGROVE_ROOTS_PLACE, WBSoundEvents.BLOCK_MANGROVE_ROOTS_HIT, WBSoundEvents.BLOCK_MANGROVE_ROOTS_FALL); + public static final SoundType MUD = create(WBSoundEvents.BLOCK_MUD_BREAK, WBSoundEvents.BLOCK_MUD_STEP, WBSoundEvents.BLOCK_MUD_PLACE, WBSoundEvents.BLOCK_MUD_HIT, WBSoundEvents.BLOCK_MUD_FALL); + public static final SoundType MUD_BRICKS = create(WBSoundEvents.BLOCK_MUD_BRICKS_BREAK, WBSoundEvents.BLOCK_MUD_BRICKS_STEP, WBSoundEvents.BLOCK_MUD_BRICKS_PLACE, WBSoundEvents.BLOCK_MUD_BRICKS_HIT, WBSoundEvents.BLOCK_MUD_BRICKS_FALL); + public static final SoundType MUDDY_MANGROVE_ROOTS = create(WBSoundEvents.BLOCK_MUDDY_MANGROVE_ROOTS_BREAK, WBSoundEvents.BLOCK_MUDDY_MANGROVE_ROOTS_STEP, WBSoundEvents.BLOCK_MUDDY_MANGROVE_ROOTS_PLACE, WBSoundEvents.BLOCK_MUDDY_MANGROVE_ROOTS_HIT, WBSoundEvents.BLOCK_MUDDY_MANGROVE_ROOTS_FALL); + public static final SoundType PACKED_MUD = create(WBSoundEvents.BLOCK_PACKED_MUD_BREAK, WBSoundEvents.BLOCK_PACKED_MUD_STEP, WBSoundEvents.BLOCK_PACKED_MUD_PLACE, WBSoundEvents.BLOCK_PACKED_MUD_HIT, WBSoundEvents.BLOCK_PACKED_MUD_FALL); + + public static SoundType create(SoundEvent breakSnd, SoundEvent stepSnd, SoundEvent placeSnd, SoundEvent hitSnd, SoundEvent fallSnd) { + return new CoreSoundType(() -> breakSnd, () -> stepSnd, () -> placeSnd, () -> hitSnd, () -> fallSnd); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/client/render/AllayRenderer.java b/common/src/main/java/com/cursedcauldron/wildbackport/client/render/AllayRenderer.java new file mode 100644 index 0000000..3d05a1c --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/client/render/AllayRenderer.java @@ -0,0 +1,31 @@ +package com.cursedcauldron.wildbackport.client.render; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.client.render.model.AllayModel; +import com.cursedcauldron.wildbackport.common.entities.Allay; +import net.minecraft.client.model.geom.ModelLayerLocation; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.client.renderer.entity.MobRenderer; +import net.minecraft.client.renderer.entity.layers.ItemInHandLayer; +import net.minecraft.core.BlockPos; +import net.minecraft.resources.ResourceLocation; + +public class AllayRenderer extends MobRenderer { + public static final ModelLayerLocation MODEL_LAYER = new ModelLayerLocation(new ResourceLocation(WildBackport.MOD_ID, "allay"), "main"); + private static final ResourceLocation TEXTURE = new ResourceLocation(WildBackport.MOD_ID, "textures/entity/allay/allay.png"); + + public AllayRenderer(EntityRendererProvider.Context context) { + super(context, new AllayModel(context.bakeLayer(MODEL_LAYER)), 0.4F); + this.addLayer(new ItemInHandLayer<>(this)); + } + + @Override + public ResourceLocation getTextureLocation(Allay entity) { + return TEXTURE; + } + + @Override + protected int getBlockLightLevel(Allay entity, BlockPos pos) { + return 15; + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/client/render/ChestBoatRenderer.java b/common/src/main/java/com/cursedcauldron/wildbackport/client/render/ChestBoatRenderer.java new file mode 100644 index 0000000..70ce291 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/client/render/ChestBoatRenderer.java @@ -0,0 +1,86 @@ +package com.cursedcauldron.wildbackport.client.render; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.client.render.model.ChestBoatModel; +import com.cursedcauldron.wildbackport.common.entities.MangroveBoat; +import com.cursedcauldron.wildbackport.common.entities.access.api.BoatTypes; +import com.google.common.collect.ImmutableMap; +import com.ibm.icu.impl.Pair; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import com.mojang.math.Quaternion; +import com.mojang.math.Vector3f; +import net.minecraft.client.model.geom.ModelLayerLocation; +import net.minecraft.client.model.geom.ModelLayers; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.entity.EntityRenderer; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.vehicle.Boat; + +import java.util.Map; +import java.util.stream.Stream; + +//<> + +public class ChestBoatRenderer extends EntityRenderer { + private final Map> boatResources; + + public ChestBoatRenderer(EntityRendererProvider.Context context, boolean chest) { + super(context); + this.shadowRadius = 0.8F; + this.boatResources = Stream.of(Boat.Type.values()).collect(ImmutableMap.toImmutableMap(type -> type, type -> Pair.of(getTexture(type, chest), this.createModel(context, type, chest)))); + } + + private ChestBoatModel createModel(EntityRendererProvider.Context context, Boat.Type type, boolean chest) { + ModelLayerLocation layer = chest ? ChestBoatModel.createChestBoat(type) : ModelLayers.createBoatModelName(type); + return new ChestBoatModel(context.bakeLayer(layer), chest); + } + + private static ResourceLocation getTexture(Boat.Type type, boolean chested) { + if (chested) { + return new ResourceLocation(WildBackport.MOD_ID, "textures/entity/chest_boat/" + type.getName() + ".png"); + } else { + return new ResourceLocation(type == BoatTypes.MANGROVE.get() ? WildBackport.MOD_ID: "minecraft", "textures/entity/boat/" + type.getName() + ".png"); + } + } + + @Override + public void render(MangroveBoat boat, float yaw, float angle, PoseStack stack, MultiBufferSource buffer, int light) { + stack.pushPose(); + stack.translate(0.0D, 0.375D, 0.0D); + stack.mulPose(Vector3f.YP.rotationDegrees(180.0F - yaw)); + float hurtTilt = (float)boat.getHurtTime() - angle; + float damageTilt = boat.getDamage() - angle; + if (damageTilt < 0.0F) damageTilt = 0.0F; + + if (hurtTilt > 0.0F) stack.mulPose(Vector3f.XP.rotationDegrees(Mth.sin(hurtTilt) * hurtTilt * damageTilt / 10.0F * (float)boat.getHurtDir())); + + float bubbleTilt = boat.getBubbleAngle(angle); + if (!Mth.equal(bubbleTilt, 0.0F)) stack.mulPose(new Quaternion(new Vector3f(1.0F, 0.0F, 1.0F), boat.getBubbleAngle(angle), true)); + + Pair resource = this.boatResources.get(boat.getBoatType()); + ResourceLocation location = resource.first; + ChestBoatModel model = resource.second; + stack.scale(-1.0F, -1.0F, 1.0F); + stack.mulPose(Vector3f.YP.rotationDegrees(90.0F)); + model.setupAnim(boat, angle, 0.0F, -0.1F, 0.0F, 0.0F); + VertexConsumer render = buffer.getBuffer(model.renderType(location)); + model.renderToBuffer(stack, render, light, OverlayTexture.NO_OVERLAY, 1.0F, 1.0F, 1.0F, 1.0F); + if (!boat.isUnderWater()) { + VertexConsumer waterRender = buffer.getBuffer(RenderType.waterMask()); + model.waterPatch().render(stack, waterRender, light, OverlayTexture.NO_OVERLAY); + } + + stack.popPose(); + super.render(boat, yaw, angle, stack, buffer, light); + } + + @Override + public ResourceLocation getTextureLocation(MangroveBoat boat) { + return this.boatResources.get(boat.getBoatType()).first; + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/client/render/FrogRenderer.java b/common/src/main/java/com/cursedcauldron/wildbackport/client/render/FrogRenderer.java new file mode 100644 index 0000000..4be9edb --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/client/render/FrogRenderer.java @@ -0,0 +1,32 @@ +package com.cursedcauldron.wildbackport.client.render; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.client.render.model.FrogModel; +import com.cursedcauldron.wildbackport.common.entities.Frog; +import com.google.common.collect.Maps; +import net.minecraft.Util; +import net.minecraft.client.model.geom.ModelLayerLocation; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.client.renderer.entity.MobRenderer; +import net.minecraft.resources.ResourceLocation; + +import java.util.Map; + +public class FrogRenderer extends MobRenderer> { + public static final ModelLayerLocation MODEL_LAYER = new ModelLayerLocation(new ResourceLocation(WildBackport.MOD_ID, "frog"), "main"); + + private static final Map TEXTURES = Util.make(Maps.newHashMap(), hashMap -> { + for (Frog.Variant variant : Frog.Variant.values()) { + hashMap.put(variant, new ResourceLocation(WildBackport.MOD_ID, String.format("textures/entity/frog/%s_frog.png", variant.getName()))); + } + }); + + public FrogRenderer(EntityRendererProvider.Context context) { + super(context, new FrogModel<>(context.bakeLayer(MODEL_LAYER)), 0.3f); + } + + @Override + public ResourceLocation getTextureLocation(Frog frog) { + return TEXTURES.get(frog.getVariant()); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/client/render/TadpoleRenderer.java b/common/src/main/java/com/cursedcauldron/wildbackport/client/render/TadpoleRenderer.java new file mode 100644 index 0000000..90dcd9f --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/client/render/TadpoleRenderer.java @@ -0,0 +1,24 @@ +package com.cursedcauldron.wildbackport.client.render; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.client.render.model.TadpoleModel; +import com.cursedcauldron.wildbackport.common.entities.Tadpole; +import net.minecraft.client.model.geom.ModelLayerLocation; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.client.renderer.entity.MobRenderer; +import net.minecraft.resources.ResourceLocation; + +public class TadpoleRenderer extends MobRenderer> { + public static final ModelLayerLocation MODEL_LAYER = new ModelLayerLocation(new ResourceLocation(WildBackport.MOD_ID, "tadpole"), "main"); + + private static final ResourceLocation TEXTURE = new ResourceLocation(WildBackport.MOD_ID, "textures/entity/tadpole/tadpole.png"); + + public TadpoleRenderer(EntityRendererProvider.Context context) { + super(context, new TadpoleModel<>(context.bakeLayer(MODEL_LAYER)), 0.14F); + } + + @Override + public ResourceLocation getTextureLocation(Tadpole entity) { + return TEXTURE; + } +} diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/client/render/WardenLayerRenderer.java b/common/src/main/java/com/cursedcauldron/wildbackport/client/render/WardenLayerRenderer.java new file mode 100644 index 0000000..23389cc --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/client/render/WardenLayerRenderer.java @@ -0,0 +1,63 @@ +package com.cursedcauldron.wildbackport.client.render; + +import com.cursedcauldron.wildbackport.client.render.model.Drawable; +import com.cursedcauldron.wildbackport.client.render.model.WardenModel; +import com.cursedcauldron.wildbackport.common.entities.Warden; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.model.EntityModel; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.entity.LivingEntityRenderer; +import net.minecraft.client.renderer.entity.RenderLayerParent; +import net.minecraft.client.renderer.entity.layers.RenderLayer; +import net.minecraft.resources.ResourceLocation; + +import java.util.List; + +//<> + +@Environment(EnvType.CLIENT) +public class WardenLayerRenderer> extends RenderLayer { + private final ResourceLocation texture; + private final AnimationAngleAdjuster animationAngleAdjuster; + private final ModelPartVisibility modelPartVisibility; + + public WardenLayerRenderer(RenderLayerParent ctx, ResourceLocation texture, AnimationAngleAdjuster animationAngleAdjuster, ModelPartVisibility modelPartVisibility) { + super(ctx); + this.texture = texture; + this.animationAngleAdjuster = animationAngleAdjuster; + this.modelPartVisibility = modelPartVisibility; + } + + @Override + public void render(PoseStack stack, MultiBufferSource source, int light, T entity, float angle, float distance, float tickDelta, float animationProgress, float yaw, float pitch) { + if (!entity.isInvisible()) { + this.updateModelPartVisibility(); + VertexConsumer consumer = source.getBuffer(RenderType.entityCutoutNoCull(this.texture)); + this.getParentModel().renderToBuffer(stack, consumer, light, LivingEntityRenderer.getOverlayCoords(entity, 0.0F), 1.0F, 1.0F, 1.0F, this.animationAngleAdjuster.apply(entity, tickDelta, animationProgress)); + this.unhideAllModelParts(); + } + } + + private void updateModelPartVisibility() { + List parts = this.modelPartVisibility.getPartsToDraw(this.getParentModel()); + this.getParentModel().root().getAllParts().forEach(part -> ((Drawable)(Object)part).setSkipDraw(true)); + parts.forEach(part -> ((Drawable)(Object)part).setSkipDraw(false)); + } + + private void unhideAllModelParts() { + this.getParentModel().root().getAllParts().forEach(part -> ((Drawable)(Object)part).setSkipDraw(false)); + } + + public interface AnimationAngleAdjuster { + float apply(T entity, float tickDelta, float animationProgress); + } + + public interface ModelPartVisibility> { + List getPartsToDraw(M parts); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/client/render/WardenRenderer.java b/common/src/main/java/com/cursedcauldron/wildbackport/client/render/WardenRenderer.java new file mode 100644 index 0000000..c17f50c --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/client/render/WardenRenderer.java @@ -0,0 +1,39 @@ +package com.cursedcauldron.wildbackport.client.render; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.client.render.model.WardenModel; +import com.cursedcauldron.wildbackport.common.entities.Warden; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.model.geom.ModelLayerLocation; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.client.renderer.entity.MobRenderer; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Mth; + +//<> + +@Environment(EnvType.CLIENT) +public class WardenRenderer extends MobRenderer> { + public static final ModelLayerLocation MODEL_LAYER = new ModelLayerLocation(new ResourceLocation(WildBackport.MOD_ID, "warden"), "main"); + + private static final ResourceLocation TEXTURE = new ResourceLocation(WildBackport.MOD_ID, "textures/entity/warden/warden.png"); + private static final ResourceLocation BIOLUMINESCENT_LAYER_TEXTURE = new ResourceLocation(WildBackport.MOD_ID, "textures/entity/warden/warden_bioluminescent_layer.png"); + private static final ResourceLocation HEART_TEXTURE = new ResourceLocation(WildBackport.MOD_ID, "textures/entity/warden/warden_heart.png"); + private static final ResourceLocation PULSATING_SPOTS_1_TEXTURE = new ResourceLocation(WildBackport.MOD_ID, "textures/entity/warden/warden_pulsating_spots_1.png"); + private static final ResourceLocation PULSATING_SPOTS_2_TEXTURE = new ResourceLocation(WildBackport.MOD_ID, "textures/entity/warden/warden_pulsating_spots_2.png"); + + public WardenRenderer(EntityRendererProvider.Context ctx) { + super(ctx, new WardenModel<>(ctx.bakeLayer(MODEL_LAYER)), 0.9F); + this.addLayer(new WardenLayerRenderer<>(this, BIOLUMINESCENT_LAYER_TEXTURE, (entity, tickDelta, animationProgress) -> 1.0F, WardenModel::getHeadAndLimbs)); + this.addLayer(new WardenLayerRenderer<>(this, PULSATING_SPOTS_1_TEXTURE, (entity, tickDelta, animationProgress) -> Math.max(0.0F, Mth.cos(animationProgress * 0.045F) * 0.25F), WardenModel::getBodyHeadAndLimbs)); + this.addLayer(new WardenLayerRenderer<>(this, PULSATING_SPOTS_2_TEXTURE, (entity, tickDelta, animationProgress) -> Math.max(0.0F, Mth.cos(animationProgress * 0.045F + (float)Math.PI) * 0.25F), WardenModel::getBodyHeadAndLimbs)); + this.addLayer(new WardenLayerRenderer<>(this, TEXTURE, (entity, tickDelta, animationProgress) -> entity.getTendrilPitch(tickDelta), WardenModel::getTendrils)); + this.addLayer(new WardenLayerRenderer<>(this, HEART_TEXTURE, (entity, tickDelta, animationProgress) -> entity.getHeartPitch(tickDelta), WardenModel::getBody)); + } + + @Override + public ResourceLocation getTextureLocation(Warden warden) { + return TEXTURE; + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/client/render/model/AllayModel.java b/common/src/main/java/com/cursedcauldron/wildbackport/client/render/model/AllayModel.java new file mode 100644 index 0000000..b44bd57 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/client/render/model/AllayModel.java @@ -0,0 +1,102 @@ +package com.cursedcauldron.wildbackport.client.render.model; + +import com.cursedcauldron.wildbackport.client.animation.api.Animated; +import com.cursedcauldron.wildbackport.common.entities.Allay; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import com.mojang.math.Vector3f; +import net.minecraft.client.model.ArmedModel; +import net.minecraft.client.model.HierarchicalModel; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.model.geom.PartPose; +import net.minecraft.client.model.geom.builders.CubeDeformation; +import net.minecraft.client.model.geom.builders.CubeListBuilder; +import net.minecraft.client.model.geom.builders.LayerDefinition; +import net.minecraft.client.model.geom.builders.MeshDefinition; +import net.minecraft.client.model.geom.builders.PartDefinition; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.HumanoidArm; + +//<> + +public class AllayModel extends HierarchicalModel implements ArmedModel { + private final ModelPart root; + private final ModelPart head; + private final ModelPart body; + private final ModelPart right_arm; + private final ModelPart left_arm; + private final ModelPart right_wing; + private final ModelPart left_wing; + + public AllayModel(ModelPart part) { + this.root = part.getChild("root"); + this.head = this.root.getChild("head"); + this.body = this.root.getChild("body"); + this.right_arm = this.body.getChild("right_arm"); + this.left_arm = this.body.getChild("left_arm"); + this.right_wing = this.body.getChild("right_wing"); + this.left_wing = this.body.getChild("left_wing"); + } + + public static LayerDefinition createBodyLayer() { + MeshDefinition mesh = new MeshDefinition(); + PartDefinition root = mesh.getRoot().addOrReplaceChild("root", CubeListBuilder.create(), PartPose.offset(0.0F, 23.5F, 0.0F)); + root.addOrReplaceChild("head", CubeListBuilder.create().texOffs(0, 0).addBox(-2.5F, -5.0F, -2.5F, 5.0F, 5.0F, 5.0F, new CubeDeformation(0.0F)), PartPose.offset(0.0F, -3.99F, 0.0F)); + PartDefinition body = root.addOrReplaceChild("body", CubeListBuilder.create().texOffs(0, 10).addBox(-1.5F, 0.0F, -1.0F, 3.0F, 4.0F, 2.0F, new CubeDeformation(0.0F)).texOffs(0, 16).addBox(-1.5F, 0.0F, -1.0F, 3.0F, 5.0F, 2.0F, new CubeDeformation(-0.2F)), PartPose.offset(0.0F, -4.0F, 0.0F)); + body.addOrReplaceChild("right_arm", CubeListBuilder.create().texOffs(23, 0).addBox(-0.75F, -0.5F, -1.0F, 1.0F, 4.0F, 2.0F, new CubeDeformation(-0.01F)), PartPose.offset(-1.75F, 0.5F, 0.0F)); + body.addOrReplaceChild("left_arm", CubeListBuilder.create().texOffs(23, 6).addBox(-0.25F, -0.5F, -1.0F, 1.0F, 4.0F, 2.0F, new CubeDeformation(-0.01F)), PartPose.offset(1.75F, 0.5F, 0.0F)); + body.addOrReplaceChild("right_wing", CubeListBuilder.create().texOffs(16, 14).addBox(0.0F, 1.0F, 0.0F, 0.0F, 5.0F, 8.0F, new CubeDeformation(0.0F)), PartPose.offset(-0.5F, 0.0F, 0.65F)); + body.addOrReplaceChild("left_wing", CubeListBuilder.create().texOffs(16, 14).addBox(0.0F, 1.0F, 0.0F, 0.0F, 5.0F, 8.0F, new CubeDeformation(0.0F)), PartPose.offset(0.5F, 0.0F, 0.65F)); + return LayerDefinition.create(mesh, 32, 32); + } + + @Override + public void setupAnim(Allay entity, float angle, float distance, float animationProgress, float yaw, float pitch) { + this.root().getAllParts().forEach(Animated::resetPose); + this.head.xRot = pitch * ((float)Math.PI / 180F); + this.head.yRot = yaw * ((float)Math.PI / 180F); + float f = animationProgress * 20.0F * ((float)Math.PI / 180F) + distance; + float f1 = Mth.cos(f) * (float)Math.PI * 0.15F; + float f2 = animationProgress - (float)entity.tickCount; + float f3 = animationProgress * 9.0F * ((float)Math.PI / 180F); + float f4 = Math.min(distance / 0.3F, 1.0F); + float f5 = 1.0F - f4; + float holdingItemAnimation = entity.getHoldingItemAnimationProgress(f2); + this.right_wing.xRot = 0.43633232F; + this.right_wing.yRot = -0.61086524F + f1; + this.left_wing.xRot = 0.43633232F; + this.left_wing.yRot = 0.61086524F - f1; + float f7 = f4 * 0.6981317F; + this.body.xRot = f7; + float f8 = Mth.lerp(holdingItemAnimation, f7, Mth.lerp(f4, (-(float)Math.PI / 3F), (-(float)Math.PI / 4F))); + this.root.y += (float)Math.cos(f3) * 0.25F * f5; + this.right_arm.xRot = f8; + this.left_arm.xRot = f8; + float f9 = f5 * (1.0F - holdingItemAnimation); + float f10 = 0.43633232F - Mth.cos(f3 + ((float)Math.PI * 1.5F)) * (float)Math.PI * 0.075F * f9; + this.left_arm.zRot = -f10; + this.right_arm.zRot = f10; + this.right_arm.yRot = 0.27925268F * holdingItemAnimation; + this.left_arm.yRot = -0.27925268F * holdingItemAnimation; + } + + @Override + public void renderToBuffer(PoseStack stack, VertexConsumer consumer, int i, int j, float f, float g, float h, float k) { + this.root.render(stack, consumer, i, j); + } + + @Override + public void translateToHand(HumanoidArm arm, PoseStack stack) { + this.root.translateAndRotate(stack); + this.body.translateAndRotate(stack); + stack.translate(0.0D, -0.09375D, 0.09375D); + stack.mulPose(Vector3f.XP.rotation(this.right_arm.xRot + 0.43633232F)); + stack.scale(0.7F, 0.7F, 0.7F); + stack.translate(0.0625D, 0.0D, 0.0D); + } + + @Override + public ModelPart root() { + return this.root; + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/client/render/model/ChestBoatModel.java b/common/src/main/java/com/cursedcauldron/wildbackport/client/render/model/ChestBoatModel.java new file mode 100644 index 0000000..e60c03f --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/client/render/model/ChestBoatModel.java @@ -0,0 +1,85 @@ +package com.cursedcauldron.wildbackport.client.render.model; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.common.entities.MangroveBoat; +import com.google.common.collect.ImmutableList; +import net.minecraft.client.model.ListModel; +import net.minecraft.client.model.geom.ModelLayerLocation; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.model.geom.PartPose; +import net.minecraft.client.model.geom.builders.CubeListBuilder; +import net.minecraft.client.model.geom.builders.LayerDefinition; +import net.minecraft.client.model.geom.builders.MeshDefinition; +import net.minecraft.client.model.geom.builders.PartDefinition; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.vehicle.Boat; + +//<> + +public class ChestBoatModel extends ListModel { + private final ModelPart leftPaddle; + private final ModelPart rightPaddle; + private final ModelPart waterPatch; + private final ImmutableList parts; + + public ChestBoatModel(ModelPart root, boolean chest) { + this.leftPaddle = root.getChild("left_paddle"); + this.rightPaddle = root.getChild("right_paddle"); + this.waterPatch = root.getChild("water_patch"); + ImmutableList.Builder builder = new ImmutableList.Builder<>(); + builder.add(root.getChild("bottom"), root.getChild("back"), root.getChild("front"), root.getChild("right"), root.getChild("left"), this.leftPaddle, this.rightPaddle); + if (chest) { + builder.add(root.getChild("chest_bottom")); + builder.add(root.getChild("chest_lid")); + builder.add(root.getChild("chest_lock")); + } + + this.parts = builder.build(); + } + + public static LayerDefinition createBodyModel(boolean chested) { + MeshDefinition mesh = new MeshDefinition(); + PartDefinition part = mesh.getRoot(); + part.addOrReplaceChild("bottom", CubeListBuilder.create().texOffs(0, 0).addBox(-14.0F, -9.0F, -3.0F, 28.0F, 16.0F, 3.0F), PartPose.offsetAndRotation(0.0F, 3.0F, 1.0F, 1.5707964F, 0.0F, 0.0F)); + part.addOrReplaceChild("back", CubeListBuilder.create().texOffs(0, 19).addBox(-13.0F, -7.0F, -1.0F, 18.0F, 6.0F, 2.0F), PartPose.offsetAndRotation(-15.0F, 4.0F, 4.0F, 0.0F, 4.712389F, 0.0F)); + part.addOrReplaceChild("front", CubeListBuilder.create().texOffs(0, 27).addBox(-8.0F, -7.0F, -1.0F, 16.0F, 6.0F, 2.0F), PartPose.offsetAndRotation(15.0F, 4.0F, 0.0F, 0.0F, 1.5707964F, 0.0F)); + part.addOrReplaceChild("right", CubeListBuilder.create().texOffs(0, 35).addBox(-14.0F, -7.0F, -1.0F, 28.0F, 6.0F, 2.0F), PartPose.offsetAndRotation(0.0F, 4.0F, -9.0F, 0.0F, 3.1415927F, 0.0F)); + part.addOrReplaceChild("left", CubeListBuilder.create().texOffs(0, 43).addBox(-14.0F, -7.0F, -1.0F, 28.0F, 6.0F, 2.0F), PartPose.offset(0.0F, 4.0F, 9.0F)); + if (chested) { + part.addOrReplaceChild("chest_bottom", CubeListBuilder.create().texOffs(0, 76).addBox(0.0f, 0.0f, 0.0f, 12.0f, 8.0f, 12.0f), PartPose.offsetAndRotation(-2.0f, -5.0f, -6.0f, 0.0f, -1.5707964f, 0.0f)); + part.addOrReplaceChild("chest_lid", CubeListBuilder.create().texOffs(0, 59).addBox(0.0f, 0.0f, 0.0f, 12.0f, 4.0f, 12.0f), PartPose.offsetAndRotation(-2.0f, -9.0f, -6.0f, 0.0f, -1.5707964f, 0.0f)); + part.addOrReplaceChild("chest_lock", CubeListBuilder.create().texOffs(0, 59).addBox(0.0f, 0.0f, 0.0f, 2.0f, 4.0f, 1.0f), PartPose.offsetAndRotation(-1.0f, -6.0f, -1.0f, 0.0f, -1.5707964f, 0.0f)); + } + + part.addOrReplaceChild("left_paddle", CubeListBuilder.create().texOffs(62, 0).addBox(-1.0F, 0.0F, -5.0F, 2.0F, 2.0F, 18.0F).addBox(-1.001F, -3.0F, 8.0F, 1.0F, 6.0F, 7.0F), PartPose.offsetAndRotation(3.0F, -5.0F, 9.0F, 0.0F, 0.0F, 0.19634955F)); + part.addOrReplaceChild("right_paddle", CubeListBuilder.create().texOffs(62, 20).addBox(-1.0F, 0.0F, -5.0F, 2.0F, 2.0F, 18.0F).addBox(0.001F, -3.0F, 8.0F, 1.0F, 6.0F, 7.0F), PartPose.offsetAndRotation(3.0F, -5.0F, -9.0F, 0.0F, 3.1415927F, 0.19634955F)); + part.addOrReplaceChild("water_patch", CubeListBuilder.create().texOffs(0, 0).addBox(-14.0F, -9.0F, -3.0F, 28.0F, 16.0F, 3.0F), PartPose.offsetAndRotation(0.0F, -3.0F, 1.0F, 1.5707964F, 0.0F, 0.0F)); + return LayerDefinition.create(mesh, 128, chested ? 128 : 64); + } + + @Override + public void setupAnim(MangroveBoat boat, float angle, float distance, float animationProgress, float yaw, float pitch) { + animatePaddle(boat, 0, this.leftPaddle, angle); + animatePaddle(boat, 1, this.rightPaddle, angle); + } + + public ImmutableList parts() { + return this.parts; + } + + public ModelPart waterPatch() { + return this.waterPatch; + } + + private static void animatePaddle(MangroveBoat boat, int sigma, ModelPart part, float angle) { + float time = boat.getRowingTime(sigma, angle); + part.xRot = Mth.clampedLerp(-1.0471976F, -0.2617994F, (Mth.sin(-time) + 1.0F) / 2.0F); + part.yRot = Mth.clampedLerp(-0.7853982F, 0.7853982F, (Mth.sin(-time + 1.0F) + 1.0F) / 2.0F); + if (sigma == 1) part.yRot = (float)Math.PI - part.yRot; + } + + public static ModelLayerLocation createChestBoat(Boat.Type type) { + return new ModelLayerLocation(new ResourceLocation(WildBackport.MOD_ID, "chest_boat/" + type.getName()), "main"); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/client/render/model/Drawable.java b/common/src/main/java/com/cursedcauldron/wildbackport/client/render/model/Drawable.java new file mode 100644 index 0000000..e3fc933 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/client/render/model/Drawable.java @@ -0,0 +1,7 @@ +package com.cursedcauldron.wildbackport.client.render.model; + +public interface Drawable { + boolean skipDraw(); + + void setSkipDraw(boolean set); +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/client/render/model/FrogModel.java b/common/src/main/java/com/cursedcauldron/wildbackport/client/render/model/FrogModel.java new file mode 100644 index 0000000..9ead528 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/client/render/model/FrogModel.java @@ -0,0 +1,79 @@ +package com.cursedcauldron.wildbackport.client.render.model; + +import com.cursedcauldron.wildbackport.client.animation.FrogAnimations; +import com.cursedcauldron.wildbackport.client.animation.api.Animated; +import com.cursedcauldron.wildbackport.client.animation.api.AnimatedModel; +import com.cursedcauldron.wildbackport.common.entities.Frog; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.model.geom.PartPose; +import net.minecraft.client.model.geom.builders.CubeDeformation; +import net.minecraft.client.model.geom.builders.CubeListBuilder; +import net.minecraft.client.model.geom.builders.LayerDefinition; +import net.minecraft.client.model.geom.builders.MeshDefinition; +import net.minecraft.client.model.geom.builders.PartDefinition; + +public class FrogModel extends AnimatedModel { + private final ModelPart root; + private final ModelPart body; + private final ModelPart head; + private final ModelPart eyes; + private final ModelPart tongue; + private final ModelPart leftArm; + private final ModelPart rightArm; + private final ModelPart leftLeg; + private final ModelPart rightLeg; + private final ModelPart croakingBody; + + public FrogModel(ModelPart root) { + this.root = root.getChild("root"); + this.body = this.root.getChild("body"); + this.head = this.body.getChild("head"); + this.eyes = this.head.getChild("eyes"); + this.tongue = this.body.getChild("tongue"); + this.leftArm = this.body.getChild("left_arm"); + this.rightArm = this.body.getChild("right_arm"); + this.leftLeg = this.root.getChild("left_leg"); + this.rightLeg = this.root.getChild("right_leg"); + this.croakingBody = this.body.getChild("croaking_body"); + } + + public static LayerDefinition createBodyLayer() { + MeshDefinition mesh = new MeshDefinition(); + PartDefinition root = mesh.getRoot(); + PartDefinition bone = root.addOrReplaceChild("root", CubeListBuilder.create(), PartPose.offset(0.0f, 24.0f, 0.0f)); + PartDefinition body = bone.addOrReplaceChild("body", CubeListBuilder.create().texOffs(3, 1).addBox(-3.5f, -2.0f, -8.0f, 7.0f, 3.0f, 9.0f).texOffs(23, 22).addBox(-3.5f, -1.0f, -8.0f, 7.0f, 0.0f, 9.0f), PartPose.offset(0.0f, -2.0f, 4.0f)); + PartDefinition head = body.addOrReplaceChild("head", CubeListBuilder.create().texOffs(23, 13).addBox(-3.5f, -1.0f, -7.0f, 7.0f, 0.0f, 9.0f).texOffs(0, 13).addBox(-3.5f, -2.0f, -7.0f, 7.0f, 3.0f, 9.0f), PartPose.offset(0.0f, -2.0f, -1.0f)); + PartDefinition eyes = head.addOrReplaceChild("eyes", CubeListBuilder.create(), PartPose.offset(-0.5f, 0.0f, 2.0f)); + eyes.addOrReplaceChild("right_eye", CubeListBuilder.create().texOffs(0, 0).addBox(-1.5f, -1.0f, -1.5f, 3.0f, 2.0f, 3.0f), PartPose.offset(-1.5f, -3.0f, -6.5f)); + eyes.addOrReplaceChild("left_eye", CubeListBuilder.create().texOffs(0, 5).addBox(-1.5f, -1.0f, -1.5f, 3.0f, 2.0f, 3.0f), PartPose.offset(2.5f, -3.0f, -6.5f)); + body.addOrReplaceChild("croaking_body", CubeListBuilder.create().texOffs(26, 5).addBox(-3.5f, -0.1f, -2.9f, 7.0f, 2.0f, 3.0f, new CubeDeformation(-0.1f)), PartPose.offset(0.0f, -1.0f, -5.0f)); + body.addOrReplaceChild("tongue", CubeListBuilder.create().texOffs(17, 13).addBox(-2.0f, 0.0f, -7.1f, 4.0f, 0.0f, 7.0f), PartPose.offset(0.0f, -1.01f, 1.0f)); + PartDefinition left_arm = body.addOrReplaceChild("left_arm", CubeListBuilder.create().texOffs(0, 32).addBox(-1.0f, 0.0f, -1.0f, 2.0f, 3.0f, 3.0f), PartPose.offset(4.0f, -1.0f, -6.5f)); + left_arm.addOrReplaceChild("left_hand", CubeListBuilder.create().texOffs(18, 40).addBox(-4.0f, 0.01f, -4.0f, 8.0f, 0.0f, 8.0f), PartPose.offset(0.0f, 3.0f, -1.0f)); + PartDefinition right_arm = body.addOrReplaceChild("right_arm", CubeListBuilder.create().texOffs(0, 38).addBox(-1.0f, 0.0f, -1.0f, 2.0f, 3.0f, 3.0f), PartPose.offset(-4.0f, -1.0f, -6.5f)); + right_arm.addOrReplaceChild("right_hand", CubeListBuilder.create().texOffs(2, 40).addBox(-4.0f, 0.01f, -5.0f, 8.0f, 0.0f, 8.0f), PartPose.offset(0.0f, 3.0f, 0.0f)); + PartDefinition left_leg = bone.addOrReplaceChild("left_leg", CubeListBuilder.create().texOffs(14, 25).addBox(-1.0f, 0.0f, -2.0f, 3.0f, 3.0f, 4.0f), PartPose.offset(3.5f, -3.0f, 4.0f)); + left_leg.addOrReplaceChild("left_foot", CubeListBuilder.create().texOffs(2, 32).addBox(-4.0f, 0.01f, -4.0f, 8.0f, 0.0f, 8.0f), PartPose.offset(2.0f, 3.0f, 0.0f)); + PartDefinition right_leg = bone.addOrReplaceChild("right_leg", CubeListBuilder.create().texOffs(0, 25).addBox(-2.0f, 0.0f, -2.0f, 3.0f, 3.0f, 4.0f), PartPose.offset(-3.5f, -3.0f, 4.0f)); + right_leg.addOrReplaceChild("right_foot", CubeListBuilder.create().texOffs(18, 32).addBox(-4.0f, 0.01f, -4.0f, 8.0f, 0.0f, 8.0f), PartPose.offset(-2.0f, 3.0f, 0.0f)); + return LayerDefinition.create(mesh, 48, 48); + } + + @Override + public void setupAnim(T entity, float angle, float distance, float animationProgress, float yaw, float pitch) { + this.root.getAllParts().forEach(Animated::resetPose); + float speedMultiplier = Math.min((float)entity.getDeltaMovement().lengthSqr() * 200.0F, 8.0F); + this.animate(entity.longJumpingAnimationState, FrogAnimations.LONG_JUMPING, animationProgress); + this.animate(entity.croakingAnimationState, FrogAnimations.CROAKING, animationProgress); + this.animate(entity.usingTongueAnimationState, FrogAnimations.USING_TONGUE, animationProgress); + this.animate(entity.walkingAnimationState, FrogAnimations.WALKING, animationProgress, speedMultiplier); + this.animate(entity.swimmingAnimationState, FrogAnimations.SWIMMING, animationProgress); + this.animate(entity.idlingInWaterAnimationState, FrogAnimations.IDLING_IN_WATER, animationProgress); + this.croakingBody.visible = entity.croakingAnimationState.isRunning(); + } + + @Override + public ModelPart root() { + return this.root; + } +} diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/client/render/model/TadpoleModel.java b/common/src/main/java/com/cursedcauldron/wildbackport/client/render/model/TadpoleModel.java new file mode 100644 index 0000000..ab162d8 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/client/render/model/TadpoleModel.java @@ -0,0 +1,48 @@ +package com.cursedcauldron.wildbackport.client.render.model; + +import com.cursedcauldron.wildbackport.common.entities.Tadpole; +import com.google.common.collect.ImmutableList; +import net.minecraft.client.model.AgeableListModel; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.model.geom.PartPose; +import net.minecraft.client.model.geom.builders.CubeListBuilder; +import net.minecraft.client.model.geom.builders.LayerDefinition; +import net.minecraft.client.model.geom.builders.MeshDefinition; +import net.minecraft.client.model.geom.builders.PartDefinition; +import net.minecraft.util.Mth; + +public class TadpoleModel extends AgeableListModel { + private final ModelPart root; + private final ModelPart tail; + + public TadpoleModel(ModelPart root) { + super(true, 8.0F, 3.35F); + this.root = root; + this.tail = root.getChild("tail"); + } + + public static LayerDefinition createBodyLayer() { + MeshDefinition mesh = new MeshDefinition(); + PartDefinition root = mesh.getRoot(); + root.addOrReplaceChild("body", CubeListBuilder.create().texOffs(0, 0).addBox(-1.5F, -1.0F, 0.0F, 3.0F, 2.0F, 3.0F), PartPose.offset(0.0F, 22.0F, -3.0F)); + root.addOrReplaceChild("tail", CubeListBuilder.create().texOffs(0, 0).addBox(0.0F, -1.0F, 0.0F, 0.0F, 2.0F, 7.0F), PartPose.offset(0.0F, 22.0F, 0.0F)); + return LayerDefinition.create(mesh, 16, 16); + } + + @Override + protected Iterable headParts() { + return ImmutableList.of(this.root); + } + + @Override + protected Iterable bodyParts() { + return ImmutableList.of(this.tail); + } + + @Override + public void setupAnim(T entity, float angle, float distance, float animationProgress, float yaw, float pitch) { + float angles = entity.isInWater() ? 1.0F : 1.5F; + this.tail.yRot = -angles * 0.25F * Mth.sin(0.3F * animationProgress); + } + +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/client/render/model/WardenModel.java b/common/src/main/java/com/cursedcauldron/wildbackport/client/render/model/WardenModel.java new file mode 100644 index 0000000..e025730 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/client/render/model/WardenModel.java @@ -0,0 +1,163 @@ +package com.cursedcauldron.wildbackport.client.render.model; + +import com.cursedcauldron.wildbackport.client.animation.WardenAnimations; +import com.cursedcauldron.wildbackport.client.animation.api.Animated; +import com.cursedcauldron.wildbackport.client.animation.api.AnimatedModel; +import com.cursedcauldron.wildbackport.common.entities.Warden; +import com.google.common.collect.ImmutableList; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.model.geom.PartPose; +import net.minecraft.client.model.geom.builders.CubeListBuilder; +import net.minecraft.client.model.geom.builders.LayerDefinition; +import net.minecraft.client.model.geom.builders.MeshDefinition; +import net.minecraft.client.model.geom.builders.PartDefinition; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.util.Mth; + +import java.util.List; + +//<> + +public class WardenModel extends AnimatedModel { + private final ModelPart root; + protected final ModelPart bone; + protected final ModelPart body; + protected final ModelPart head; + protected final ModelPart rightTendril; + protected final ModelPart leftTendril; + protected final ModelPart leftLeg; + protected final ModelPart leftArm; + protected final ModelPart leftRibcage; + protected final ModelPart rightArm; + protected final ModelPart rightLeg; + protected final ModelPart rightRibcage; + private final List tendrils; + private final List justBody; + private final List headAndLimbs; + private final List bodyHeadAndLimbs; + + public WardenModel(ModelPart root) { + super(RenderType::entityCutoutNoCull); + this.root = root; + this.bone = root.getChild("bone"); + this.body = this.bone.getChild("body"); + this.head = this.body.getChild("head"); + this.rightLeg = this.bone.getChild("right_leg"); + this.leftLeg = this.bone.getChild("left_leg"); + this.rightArm = this.body.getChild("right_arm"); + this.leftArm = this.body.getChild("left_arm"); + this.rightTendril = this.head.getChild("right_tendril"); + this.leftTendril = this.head.getChild("left_tendril"); + this.rightRibcage = this.body.getChild("right_ribcage"); + this.leftRibcage = this.body.getChild("left_ribcage"); + this.tendrils = ImmutableList.of(this.leftTendril, this.rightTendril); + this.justBody = ImmutableList.of(this.body); + this.headAndLimbs = ImmutableList.of(this.head, this.leftArm, this.rightArm, this.leftLeg, this.rightLeg); + this.bodyHeadAndLimbs = ImmutableList.of(this.body, this.head, this.leftArm, this.rightArm, this.leftLeg, this.rightLeg); + } + + public static LayerDefinition createBodyLayer() { + MeshDefinition mesh = new MeshDefinition(); + PartDefinition root = mesh.getRoot(); + PartDefinition bone = root.addOrReplaceChild("bone", CubeListBuilder.create(), PartPose.offset(0.0f, 24.0f, 0.0f)); + PartDefinition body = bone.addOrReplaceChild("body", CubeListBuilder.create().texOffs(0, 0).addBox(-9.0f, -13.0f, -4.0f, 18.0f, 21.0f, 11.0f), PartPose.offset(0.0f, -21.0f, 0.0f)); + body.addOrReplaceChild("right_ribcage", CubeListBuilder.create().texOffs(90, 11).addBox(-2.0f, -11.0f, -0.1f, 9.0f, 21.0f, 0.0f), PartPose.offset(-7.0f, -2.0f, -4.0f)); + body.addOrReplaceChild("left_ribcage", CubeListBuilder.create().texOffs(90, 11).mirror().addBox(-7.0f, -11.0f, -0.1f, 9.0f, 21.0f, 0.0f).mirror(false), PartPose.offset(7.0f, -2.0f, -4.0f)); + PartDefinition head = body.addOrReplaceChild("head", CubeListBuilder.create().texOffs(0, 32).addBox(-8.0f, -16.0f, -5.0f, 16.0f, 16.0f, 10.0f), PartPose.offset(0.0f, -13.0f, 0.0f)); + head.addOrReplaceChild("right_tendril", CubeListBuilder.create().texOffs(52, 32).addBox(-16.0f, -13.0f, 0.0f, 16.0f, 16.0f, 0.0f), PartPose.offset(-8.0f, -12.0f, 0.0f)); + head.addOrReplaceChild("left_tendril", CubeListBuilder.create().texOffs(58, 0).addBox(0.0f, -13.0f, 0.0f, 16.0f, 16.0f, 0.0f), PartPose.offset(8.0f, -12.0f, 0.0f)); + body.addOrReplaceChild("right_arm", CubeListBuilder.create().texOffs(44, 50).addBox(-4.0f, 0.0f, -4.0f, 8.0f, 28.0f, 8.0f), PartPose.offset(-13.0f, -13.0f, 1.0f)); + body.addOrReplaceChild("left_arm", CubeListBuilder.create().texOffs(0, 58).addBox(-4.0f, 0.0f, -4.0f, 8.0f, 28.0f, 8.0f), PartPose.offset(13.0f, -13.0f, 1.0f)); + bone.addOrReplaceChild("right_leg", CubeListBuilder.create().texOffs(76, 48).addBox(-3.1f, 0.0f, -3.0f, 6.0f, 13.0f, 6.0f), PartPose.offset(-5.9f, -13.0f, 0.0f)); + bone.addOrReplaceChild("left_leg", CubeListBuilder.create().texOffs(76, 76).addBox(-2.9f, 0.0f, -3.0f, 6.0f, 13.0f, 6.0f), PartPose.offset(5.9f, -13.0f, 0.0f)); + return LayerDefinition.create(mesh, 128, 128); + } + + @Override + public void setupAnim(T entity, float angle, float distance, float animationProgress, float yaw, float pitch) { + this.root.getAllParts().forEach(Animated::resetPose); + float tickDelta = animationProgress - (float)entity.tickCount; + this.setHeadAngle(yaw, pitch); + this.setLimbAngles(angle, distance); + this.setHeadAndBodyAngles(animationProgress); + this.setTendrilPitches(entity, animationProgress, tickDelta); + this.animate(entity.attackingAnimationState, WardenAnimations.ATTACKING, animationProgress); + this.animate(entity.sonicBoomAnimationState, WardenAnimations.SONIC_BOOM, animationProgress); + this.animate(entity.diggingAnimationState, WardenAnimations.DIGGING, animationProgress); + this.animate(entity.emergingAnimationState, WardenAnimations.EMERGING, animationProgress); + this.animate(entity.roaringAnimationState, WardenAnimations.ROARING, animationProgress); + this.animate(entity.sniffingAnimationState, WardenAnimations.SNIFFING, animationProgress); + } + + private void setHeadAngle(float yaw, float pitch) { + this.head.xRot = pitch * ((float)Math.PI / 180); + this.head.yRot = yaw * ((float)Math.PI / 180); + } + + private void setHeadAndBodyAngles(float animationProgress) { + float angle = animationProgress * 0.1F; + float cos = Mth.cos(angle); + float sin = Mth.sin(angle); + this.head.zRot += 0.06F * cos; + this.head.xRot += 0.06F * sin; + this.body.zRot += 0.025F * sin; + this.body.xRot += 0.025F * cos; + } + + private void setLimbAngles(float angle, float distance) { + float roll = Math.min(0.5F, 3.0F * distance); + float mod = angle * 0.8662F; + float cos = Mth.cos(mod); + float sin = Mth.sin(mod); + float pitch = Math.min(0.35F, roll); + this.head.zRot += 0.3F * sin * roll; + this.head.xRot += 1.2F * Mth.cos(mod + 1.5707964F) * pitch; + this.body.zRot = 0.1F * sin * roll; + this.body.xRot = 1.0F * cos * pitch; + this.leftLeg.xRot = 1.0F * cos * roll; + this.rightLeg.xRot = 1.0F * Mth.cos(mod + (float)Math.PI) * roll; + this.leftArm.xRot = -(0.8F * cos * roll); + this.leftArm.zRot = 0.0F; + this.rightArm.xRot = -(0.8F * sin * roll); + this.rightArm.zRot = 0.0F; + this.setArmPivots(); + } + + private void setArmPivots() { + this.leftArm.yRot = 0.0F; + this.leftArm.z = 1.0F; + this.leftArm.x = 13.0F; + this.leftArm.y = -13.0F; + this.rightArm.yRot = 0.0F; + this.rightArm.z = 1.0F; + this.rightArm.x = -13.0F; + this.rightArm.y = -13.0F; + } + + private void setTendrilPitches(T warden, float animationProgress, float tickDelta) { + float pitch = warden.getTendrilPitch(tickDelta) * (float)(Math.cos((double)animationProgress * 2.25D) * Math.PI * (double)0.1F); + this.leftTendril.xRot = pitch; + this.rightTendril.xRot = -pitch; + } + + @Override + public ModelPart root() { + return this.root; + } + + public List getTendrils() { + return this.tendrils; + } + + public List getBody() { + return this.justBody; + } + + public List getHeadAndLimbs() { + return this.headAndLimbs; + } + + public List getBodyHeadAndLimbs() { + return this.bodyHeadAndLimbs; + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/client/sound/CoreSoundType.java b/common/src/main/java/com/cursedcauldron/wildbackport/client/sound/CoreSoundType.java new file mode 100644 index 0000000..785cc31 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/client/sound/CoreSoundType.java @@ -0,0 +1,49 @@ +package com.cursedcauldron.wildbackport.client.sound; + +import net.minecraft.sounds.SoundEvent; +import net.minecraft.world.level.block.SoundType; + +import java.util.function.Supplier; + +public class CoreSoundType extends SoundType { + private final Supplier breakSound; + private final Supplier stepSound; + private final Supplier placeSound; + private final Supplier hitSound; + private final Supplier fallSound; + + @SuppressWarnings("all") + public CoreSoundType(Supplier breakSound, Supplier stepSound, Supplier placeSound, Supplier hitSound, Supplier fallSound) { + super(1.0F, 1.0F, null, null, null, null, null); + this.breakSound = breakSound; + this.stepSound = stepSound; + this.placeSound = placeSound; + this.hitSound = hitSound; + this.fallSound = fallSound; + } + + @Override + public SoundEvent getBreakSound() { + return this.breakSound.get(); + } + + @Override + public SoundEvent getStepSound() { + return this.stepSound.get(); + } + + @Override + public SoundEvent getPlaceSound() { + return this.placeSound.get(); + } + + @Override + public SoundEvent getHitSound() { + return this.hitSound.get(); + } + + @Override + public SoundEvent getFallSound() { + return this.fallSound.get(); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/CommonSetup.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/CommonSetup.java new file mode 100644 index 0000000..262aa81 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/CommonSetup.java @@ -0,0 +1,30 @@ +package com.cursedcauldron.wildbackport.common; + +import com.cursedcauldron.wildbackport.common.entities.Allay; +import com.cursedcauldron.wildbackport.common.entities.Frog; +import com.cursedcauldron.wildbackport.common.entities.Tadpole; +import com.cursedcauldron.wildbackport.common.entities.Warden; +import com.cursedcauldron.wildbackport.common.events.StructureEvent; +import com.cursedcauldron.wildbackport.common.registry.entity.WBEntities; +import com.cursedcauldron.wildbackport.core.api.MobRegistry; + +public class CommonSetup { + /** + * Runs features at initializing + */ + public static void onCommon() { + // Entity Attributes + MobRegistry.registerAttributes(WBEntities.ALLAY, Allay::createAttributes); + MobRegistry.registerAttributes(WBEntities.FROG, Frog::createAttributes); + MobRegistry.registerAttributes(WBEntities.TADPOLE, Tadpole::createAttributes); + MobRegistry.registerAttributes(WBEntities.WARDEN, Warden::createAttributes); + StructureEvent.bootstrap(); + } + + /** + * Runs features post bootstrap + */ + public static void onPostClient() { + StructureEvent.bootstrap(); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/BlockProperties.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/BlockProperties.java new file mode 100644 index 0000000..529f76b --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/BlockProperties.java @@ -0,0 +1,37 @@ +package com.cursedcauldron.wildbackport.common.blocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.block.state.properties.IntegerProperty; + +public class BlockProperties { + // Block Properties + public static final BooleanProperty SHRIEKING = BooleanProperty.create("shrieking"); + public static final BooleanProperty CAN_SUMMON = BooleanProperty.create("can_summon"); + public static final BooleanProperty BLOOM = BooleanProperty.create("bloom"); + public static final IntegerProperty AGE_4 = IntegerProperty.create("age", 0, 4); + + // Block values + public static boolean always(BlockState state, BlockGetter getter, BlockPos pos, EntityType type) { + return true; + } + + public static boolean never(BlockState state, BlockGetter getter, BlockPos pos, EntityType type) { + return false; + } + + public static boolean ocelotOrParrot(BlockState state, BlockGetter getter, BlockPos pos, EntityType entity) { + return entity == EntityType.OCELOT || entity == EntityType.PARROT; + } + + public static boolean always(BlockState state, BlockGetter getter, BlockPos pos) { + return true; + } + + public static boolean never(BlockState state, BlockGetter getter, BlockPos pos) { + return true; + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/FrogspawnBlock.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/FrogspawnBlock.java new file mode 100644 index 0000000..48428cc --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/FrogspawnBlock.java @@ -0,0 +1,114 @@ +package com.cursedcauldron.wildbackport.common.blocks; + +import com.cursedcauldron.wildbackport.client.registry.WBSoundEvents; +import com.cursedcauldron.wildbackport.common.entities.Tadpole; +import com.cursedcauldron.wildbackport.common.registry.entity.WBEntities; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.sounds.SoundSource; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +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.state.BlockState; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; + +import java.util.Random; + +//<> + +public class FrogspawnBlock extends Block { + protected static final VoxelShape SHAPE = Block.box(0.0D, 0.0D, 0.0D, 16.0D, 1.5D, 16.0D); + private static final int MIN_HATCH_TIME = 3600; + private static final int MAX_HATCH_TIME = 12000; + + public FrogspawnBlock(Properties properties) { + super(properties); + } + + @Override + public VoxelShape getShape(BlockState state, BlockGetter getter, BlockPos pos, CollisionContext context) { + return SHAPE; + } + + @Override + public boolean canSurvive(BlockState state, LevelReader reader, BlockPos pos) { + return mayPlaceOn(reader, pos.below()); + } + + @Override + public void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean notify) { + level.scheduleTick(pos, this, hatchTime(level.getRandom())); + } + + private static int hatchTime(Random random) { + return random.nextInt(MIN_HATCH_TIME, MAX_HATCH_TIME); + } + + @Override + public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor access, BlockPos pos, BlockPos neighborPos) { + return !this.canSurvive(state, access, pos) ? Blocks.AIR.defaultBlockState() : super.updateShape(state, direction, neighborState, access, pos, neighborPos); + } + + @Override + public void tick(BlockState state, ServerLevel level, BlockPos pos, Random random) { + if (!this.canSurvive(state, level, pos)) { + this.hatch(level, pos); + } else { + this.onHatch(level, pos, random); + } + } + + @Override + public void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { + if (entity.getType().equals(EntityType.FALLING_BLOCK)) { + this.hatch(level, pos); + } + } + + private static boolean mayPlaceOn(LevelReader reader, BlockPos pos) { + FluidState fluidState = reader.getFluidState(pos); + FluidState topFluidState = reader.getFluidState(pos.above()); + return fluidState.getType() == Fluids.WATER && topFluidState.getType() == Fluids.EMPTY; + } + + private void onHatch(ServerLevel level, BlockPos pos, Random random) { + this.hatch(level, pos); + level.playSound(null, pos, WBSoundEvents.BLOCK_FROGSPAWN_HATCH, SoundSource.BLOCKS, 1.0F, 1.0F); + this.createTadpole(level, pos, random); + } + + private void hatch(Level level, BlockPos blockPos) { + level.destroyBlock(blockPos, false); + } + + private void createTadpole(ServerLevel level, BlockPos pos, Random random) { + int i = random.nextInt(2, 6); + + for (int index = 1; index <= i; ++index) { + Tadpole tadpole = WBEntities.TADPOLE.get().create(level); + if (tadpole != null) { + double x = (double)pos.getX() + this.getSpawnOffset(random); + double z = (double)pos.getZ() + this.getSpawnOffset(random); + int yaw = random.nextInt(1, 361); + tadpole.moveTo(x, (double)pos.getY() - 0.5, z, yaw, 0.0F); + tadpole.setPersistenceRequired(); + level.addFreshEntity(tadpole); + } + } + } + + private double getSpawnOffset(Random random) { + double d = Tadpole.WIDTH / 2.0F; + return Mth.clamp(random.nextDouble(), d, 1.0 - d); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/MangroveLeavesBlock.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/MangroveLeavesBlock.java new file mode 100644 index 0000000..12a606a --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/MangroveLeavesBlock.java @@ -0,0 +1,34 @@ +package com.cursedcauldron.wildbackport.common.blocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.BonemealableBlock; +import net.minecraft.world.level.block.LeavesBlock; +import net.minecraft.world.level.block.state.BlockState; + +import java.util.Random; + +//<> + +public class MangroveLeavesBlock extends LeavesBlock implements BonemealableBlock { + public MangroveLeavesBlock(Properties properties) { + super(properties); + } + + @Override + public boolean isValidBonemealTarget(BlockGetter getter, BlockPos pos, BlockState state, boolean bl) { + return getter.getBlockState(pos.below()).isAir(); + } + + @Override + public boolean isBonemealSuccess(Level level, Random random, BlockPos pos, BlockState state) { + return true; + } + + @Override + public void performBonemeal(ServerLevel level, Random random, BlockPos pos, BlockState state) { + level.setBlock(pos.below(), MangrovePropaguleBlock.createPropagule(), 2); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/MangrovePropaguleBlock.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/MangrovePropaguleBlock.java new file mode 100644 index 0000000..9d966c6 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/MangrovePropaguleBlock.java @@ -0,0 +1,130 @@ +package com.cursedcauldron.wildbackport.common.blocks; + +import com.cursedcauldron.wildbackport.common.registry.WBBlocks; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +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.SaplingBlock; +import net.minecraft.world.level.block.SimpleWaterloggedBlock; +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.IntegerProperty; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; +import net.minecraft.world.phys.Vec3; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; +import org.jetbrains.annotations.Nullable; + +import java.util.Random; + +//<> + +public class MangrovePropaguleBlock extends SaplingBlock implements SimpleWaterloggedBlock { + private static final VoxelShape[] SHAPES = new VoxelShape[]{Block.box(7.0D, 13.0D, 7.0D, 9.0D, 16.0D, 9.0D), Block.box(7.0D, 10.0D, 7.0D, 9.0D, 16.0D, 9.0D), Block.box(7.0D, 7.0D, 7.0D, 9.0D, 16.0D, 9.0D), Block.box(7.0D, 3.0D, 7.0D, 9.0D, 16.0D, 9.0D), Block.box(7.0D, 0.0D, 7.0D, 9.0D, 16.0D, 9.0D)}; + public static final IntegerProperty AGE = BlockProperties.AGE_4; + public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; + public static final BooleanProperty HANGING = BlockStateProperties.HANGING; + + public MangrovePropaguleBlock(Properties properties) { + super(new MangroveTreeGrower(0.85F), properties); + this.registerDefaultState(this.stateDefinition.any().setValue(STAGE, 0).setValue(AGE, 0).setValue(WATERLOGGED, false).setValue(HANGING, false)); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + builder.add(STAGE, AGE, WATERLOGGED, HANGING); + } + + @Override + protected boolean mayPlaceOn(BlockState state, BlockGetter getter, BlockPos pos) { + return super.mayPlaceOn(state, getter, pos) || state.is(Blocks.CLAY); + } + + @Override @Nullable + public BlockState getStateForPlacement(BlockPlaceContext context) { + FluidState fluidState = context.getLevel().getFluidState(context.getClickedPos()); + return super.getStateForPlacement(context).setValue(WATERLOGGED, fluidState.getType() == Fluids.WATER).setValue(AGE, 4); + } + + @Override + public VoxelShape getShape(BlockState state, BlockGetter getter, BlockPos pos, CollisionContext context) { + Vec3 offset = state.getOffset(getter, pos); + VoxelShape shape = !state.getValue(HANGING) ? SHAPES[4] : SHAPES[state.getValue(AGE)]; + return shape.move(offset.x, offset.y, offset.z); + } + + @Override + public boolean canSurvive(BlockState state, LevelReader reader, BlockPos pos) { + return isHanging(state) ? reader.getBlockState(pos.above()).is(WBBlocks.MANGROVE_LEAVES.get()) : super.canSurvive(state, reader, pos); + } + + @Override + public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor accessor, BlockPos pos, BlockPos neighborPos) { + if (state.getValue(WATERLOGGED)) accessor.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(accessor)); + return direction == Direction.UP && !state.canSurvive(accessor, pos) ? Blocks.AIR.defaultBlockState() : super.updateShape(state, direction, neighborState, accessor, pos, neighborPos); + } + + @Override + public OffsetType getOffsetType() { + return OffsetType.XZ; + } + + @Override + public FluidState getFluidState(BlockState state) { + return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state); + } + + @Override + public void randomTick(BlockState state, ServerLevel level, BlockPos pos, Random random) { + if (!isHanging(state)) { + if (random.nextInt(7) == 0) this.advanceTree(level, pos, state, random); + } else { + if (!ageAtMax(state)) level.setBlock(pos, state.cycle(AGE), 2); + } + } + + @Override + public boolean isValidBonemealTarget(BlockGetter getter, BlockPos pos, BlockState state, boolean flag) { + return !isHanging(state) || !ageAtMax(state); + } + + @Override + public boolean isBonemealSuccess(Level level, Random random, BlockPos pos, BlockState state) { + return isHanging(state) ? !ageAtMax(state) : super.isBonemealSuccess(level, random, pos, state); + } + + @Override + public void performBonemeal(ServerLevel level, Random random, BlockPos pos, BlockState state) { + if (isHanging(state) && !ageAtMax(state)) { + level.setBlock(pos, state.cycle(AGE), 2); + } else { + super.performBonemeal(level, random, pos, state); + } + } + + private static boolean isHanging(BlockState state) { + return state.getValue(HANGING); + } + + private static boolean ageAtMax(BlockState state) { + return state.getValue(AGE) == 4; + } + + public static BlockState createPropagule() { + return createPropagule(0); + } + + public static BlockState createPropagule(int age) { + return WBBlocks.MANGROVE_PROPAGULE.get().defaultBlockState().setValue(HANGING, true).setValue(AGE, age); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/MangroveRootsBlock.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/MangroveRootsBlock.java new file mode 100644 index 0000000..48d5014 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/MangroveRootsBlock.java @@ -0,0 +1,53 @@ +package com.cursedcauldron.wildbackport.common.blocks; + +import com.cursedcauldron.wildbackport.common.registry.WBBlocks; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.SimpleWaterloggedBlock; +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.material.FluidState; +import net.minecraft.world.level.material.Fluids; +import org.jetbrains.annotations.Nullable; + +public class MangroveRootsBlock extends Block implements SimpleWaterloggedBlock { + public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; + + public MangroveRootsBlock(BlockBehaviour.Properties properties) { + super(properties); + this.registerDefaultState(this.stateDefinition.any().setValue(WATERLOGGED, false)); + } + + @Override + public boolean skipRendering(BlockState state, BlockState stateFrom, Direction direction) { + return stateFrom.is(WBBlocks.MANGROVE_ROOTS.get()) && direction.getAxis() == Direction.Axis.Y; + } + + @Override @Nullable + public BlockState getStateForPlacement(BlockPlaceContext ctx) { + FluidState state = ctx.getLevel().getFluidState(ctx.getClickedPos()); + return super.getStateForPlacement(ctx).setValue(WATERLOGGED, state.getType() == Fluids.WATER); + } + + @Override + public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor accessor, BlockPos pos, BlockPos neighborPos) { + if (state.getValue(WATERLOGGED)) accessor.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(accessor)); + return super.updateShape(state, direction, neighborState, accessor, pos, neighborPos); + } + + @Override + public FluidState getFluidState(BlockState state) { + return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + builder.add(WATERLOGGED); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/MangroveTreeGrower.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/MangroveTreeGrower.java new file mode 100644 index 0000000..e95c803 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/MangroveTreeGrower.java @@ -0,0 +1,21 @@ +package com.cursedcauldron.wildbackport.common.blocks; + +import net.minecraft.core.Holder; +import net.minecraft.world.level.block.grower.AbstractTreeGrower; +import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; +import org.jetbrains.annotations.Nullable; + +import java.util.Random; + +public class MangroveTreeGrower extends AbstractTreeGrower { + private final float tallMangroveChance; + + public MangroveTreeGrower(float tallMangroveChance) { + this.tallMangroveChance = tallMangroveChance; + } + + @Override @Nullable + protected Holder> getConfiguredFeature(Random random, boolean bl) { + return null; + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/MudBlock.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/MudBlock.java new file mode 100644 index 0000000..db091d8 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/MudBlock.java @@ -0,0 +1,43 @@ +package com.cursedcauldron.wildbackport.common.blocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.pathfinder.PathComputationType; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; + +public class MudBlock extends Block { + private static final VoxelShape SHAPE = Block.box(0.0D, 0.0D, 0.0D, 16.0D, 14.0D, 16.0D); + + public MudBlock(Properties properties) { + super(properties); + } + + @Override + public VoxelShape getBlockSupportShape(BlockState state, BlockGetter getter, BlockPos pos) { + return Shapes.block(); + } + + @Override + public VoxelShape getVisualShape(BlockState state, BlockGetter getter, BlockPos pos, CollisionContext context) { + return Shapes.block(); + } + + @Override + public VoxelShape getCollisionShape(BlockState state, BlockGetter getter, BlockPos pos, CollisionContext context) { + return SHAPE; + } + + @Override + public boolean isPathfindable(BlockState state, BlockGetter getter, BlockPos pos, PathComputationType pathComputation) { + return false; + } + + @Override + public float getShadeBrightness(BlockState state, BlockGetter getter, BlockPos pos) { + return 0.2F; + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/SculkBlock.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/SculkBlock.java new file mode 100644 index 0000000..2dfb13f --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/SculkBlock.java @@ -0,0 +1,93 @@ +package com.cursedcauldron.wildbackport.common.blocks; + +import com.cursedcauldron.wildbackport.common.registry.WBBlocks; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.sounds.SoundSource; +import net.minecraft.util.Mth; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.enchantment.EnchantmentHelper; +import net.minecraft.world.item.enchantment.Enchantments; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.OreBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.material.Fluids; + +import java.util.Random; + +public class SculkBlock extends OreBlock implements SculkSpreadable { + public SculkBlock(Properties properties) { + super(properties); + } + + @Override + public int spread(SculkSpreadManager.Cursor cursor, LevelAccessor level, BlockPos pos, Random random, SculkSpreadManager manager, boolean shouldConvert) { + int charge = cursor.getCharge(); + if (charge != 0 && random.nextInt(manager.getSpreadChance()) == 0) { + BlockPos blockPos = cursor.getPos(); + boolean inRange = blockPos.closerThan(pos, manager.getMaxDistance()); + if (!inRange && shouldNotDecay(level, blockPos)) { + int chance = manager.getExtraBlockChance(); + if (random.nextInt(chance) < charge) { + BlockPos growthPos = blockPos.above(); + BlockState state = this.getExtraBlockState(level, growthPos, random, manager.isWorldGen()); + level.setBlock(growthPos, state, 3); + level.playSound(null, blockPos, state.getSoundType().getPlaceSound(), SoundSource.BLOCKS, 1.0F, 1.0F); + } + + return Math.max(0, charge - chance); + } else { + return random.nextInt(manager.getDecayChance()) != 0 ? charge : charge - (inRange ? 1 : getDecay(manager, blockPos, pos, charge)); + } + } else { + return charge; + } + } + + private static int getDecay(SculkSpreadManager manager, BlockPos source, BlockPos target, int charge) { + int maxDistance = manager.getMaxDistance(); + float range = Mth.square((float)Math.sqrt(source.distSqr(target)) - (float)maxDistance); + int distance = Mth.square(24 - maxDistance); + float spread = Math.min(1.0F, range / (float)distance); + return Math.max(1, (int)((float)charge * spread * 0.5F)); + } + + private BlockState getExtraBlockState(LevelAccessor level, BlockPos pos, Random random, boolean isWorldGen) { + BlockState state = random.nextInt(11) == 0 ? WBBlocks.SCULK_SHRIEKER.get().defaultBlockState().setValue(SculkShriekerBlock.CAN_SUMMON, isWorldGen) : Blocks.SCULK_SENSOR.defaultBlockState(); + return state.hasProperty(BlockStateProperties.WATERLOGGED) && !level.getFluidState(pos).isEmpty() ? state.setValue(BlockStateProperties.WATERLOGGED, true) : state; + } + + private static boolean shouldNotDecay(LevelAccessor level, BlockPos pos) { + BlockState state = level.getBlockState(pos.above()); + if (state.isAir() || state.is(Blocks.WATER) && state.getFluidState().is(Fluids.WATER)) { + int chance = 0; + + for (BlockPos position : BlockPos.betweenClosed(pos.offset(-4, 0, -4), pos.offset(4, 2, 4))) { + BlockState growth = level.getBlockState(position); + if (growth.is(Blocks.SCULK_SENSOR) || growth.is(WBBlocks.SCULK_SHRIEKER.get())) { + ++chance; + } + + if (chance > 2) { + return false; + } + } + + return true; + } else { + return false; + } + } + + @Override + public void spawnAfterBreak(BlockState state, ServerLevel level, BlockPos pos, ItemStack stack) { + if (EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, stack) == 0) this.popExperience(level, pos, 1); + } + + @Override + public boolean shouldConvertToSpreadable() { + return true; + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/SculkCatalystBlock.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/SculkCatalystBlock.java new file mode 100644 index 0000000..449fb22 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/SculkCatalystBlock.java @@ -0,0 +1,82 @@ +package com.cursedcauldron.wildbackport.common.blocks; + +import com.cursedcauldron.wildbackport.client.registry.WBParticleTypes; +import com.cursedcauldron.wildbackport.client.registry.WBSoundEvents; +import com.cursedcauldron.wildbackport.common.blocks.entity.SculkCatalystBlockEntity; +import com.cursedcauldron.wildbackport.common.registry.WBBlockEntities; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.enchantment.EnchantmentHelper; +import net.minecraft.world.item.enchantment.Enchantments; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.BaseEntityBlock; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.RenderShape; +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.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.gameevent.GameEventListener; +import org.jetbrains.annotations.Nullable; + +import java.util.Random; + +//<> + +public class SculkCatalystBlock extends BaseEntityBlock { + public static final BooleanProperty BLOOM = BlockProperties.BLOOM; + + public SculkCatalystBlock(Properties properties) { + super(properties); + this.registerDefaultState(this.stateDefinition.any().setValue(BLOOM, false)); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + builder.add(BLOOM); + } + + @Override + public void tick(BlockState state, ServerLevel level, BlockPos pos, Random random) { + if (state.getValue(BLOOM)) level.setBlock(pos, state.setValue(BLOOM, false), 3); + } + + public static void bloom(ServerLevel level, BlockPos pos, BlockState state, Random random) { + level.setBlock(pos, state.setValue(BLOOM, true), 3); + level.scheduleTick(pos, state.getBlock(), 8); + level.sendParticles(WBParticleTypes.SCULK_SOUL.get(), (double)pos.getX() + 0.5D, (double)pos.getY() + 1.15D, (double)pos.getZ() + 0.5D, 2, 0.2D, 0.0D, 0.2D, 0.0D); + level.playSound(null, pos, WBSoundEvents.BLOCK_SCULK_CATALYST_BLOOM, SoundSource.BLOCKS, 2.0F, 0.6F + random.nextFloat() * 0.4F); + } + + @Nullable @Override + public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { + return new SculkCatalystBlockEntity(pos, state); + } + + @Nullable @Override + public GameEventListener getListener(Level level, T type) { + return type instanceof SculkCatalystBlockEntity catalyst ? catalyst : null; + } + + @Nullable @Override + public BlockEntityTicker getTicker(Level level, BlockState state, BlockEntityType type) { + return level.isClientSide ? null : createTickerHelper(type, WBBlockEntities.SCULK_CATALYST.get(), SculkCatalystBlockEntity::tick); + } + + @Override + public RenderShape getRenderShape(BlockState state) { + return RenderShape.MODEL; + } + + @Override + public void spawnAfterBreak(BlockState state, ServerLevel level, BlockPos pos, ItemStack stack) { + super.spawnAfterBreak(state, level, pos, stack); + if (EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, stack) == 0) { + this.popExperience(level, pos, 20); + } + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/SculkShriekerBlock.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/SculkShriekerBlock.java new file mode 100644 index 0000000..9f9e222 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/SculkShriekerBlock.java @@ -0,0 +1,144 @@ +package com.cursedcauldron.wildbackport.common.blocks; + +import com.cursedcauldron.wildbackport.common.blocks.entity.SculkShriekerBlockEntity; +import com.cursedcauldron.wildbackport.common.registry.WBBlockEntities; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.item.enchantment.EnchantmentHelper; +import net.minecraft.world.item.enchantment.Enchantments; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.BaseEntityBlock; +import net.minecraft.world.level.block.Block; +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.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.gameevent.GameEventListener; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; +import org.jetbrains.annotations.Nullable; + +import java.util.Random; + +//<> + +public class SculkShriekerBlock extends BaseEntityBlock implements SimpleWaterloggedBlock { + public static final BooleanProperty SHRIEKING = BlockProperties.SHRIEKING; + public static final BooleanProperty CAN_SUMMON = BlockProperties.CAN_SUMMON; + public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; + private static final VoxelShape SHAPE = Block.box(0.0D, 0.0D, 0.0D, 16.0D, 8.0D, 16.0D); + public static final double TOP_Y = SHAPE.max(Direction.Axis.Y); + + public SculkShriekerBlock(Properties properties) { + super(properties); + this.registerDefaultState(this.stateDefinition.any().setValue(SHRIEKING, false).setValue(WATERLOGGED, false).setValue(CAN_SUMMON, false)); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + builder.add(SHRIEKING); + builder.add(WATERLOGGED); + builder.add(CAN_SUMMON); + } + + @Override + public void stepOn(Level level, BlockPos pos, BlockState state, Entity entity) { + if (level instanceof ServerLevel server) { + ServerPlayer player = SculkShriekerBlockEntity.tryGetPlayer(entity); + if (player != null) { + server.getBlockEntity(pos, WBBlockEntities.SCULK_SHRIEKER.get()).ifPresent(shrieker -> shrieker.tryShriek(server, player)); + } + } + + super.stepOn(level, pos, state, entity); + } + + @Override + public void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean moving) { + if (level instanceof ServerLevel server) { + if (state.getValue(SHRIEKING) && !state.is(newState.getBlock())) { + server.getBlockEntity(pos, WBBlockEntities.SCULK_SHRIEKER.get()).ifPresent(shrieker -> shrieker.tryRespond(server)); + } + } + + super.onRemove(state, level, pos, newState, moving); + } + + @Override + public void tick(BlockState state, ServerLevel level, BlockPos pos, Random random) { + if (state.getValue(SHRIEKING)) { + level.setBlock(pos, state.setValue(SHRIEKING, false), 3); + level.getBlockEntity(pos, WBBlockEntities.SCULK_SHRIEKER.get()).ifPresent(shrieker -> shrieker.tryRespond(level)); + } + } + + @Override + public RenderShape getRenderShape(BlockState state) { + return RenderShape.MODEL; + } + + @Override + public VoxelShape getCollisionShape(BlockState state, BlockGetter getter, BlockPos pos, CollisionContext context) { + return SHAPE; + } + + @Override + public VoxelShape getOcclusionShape(BlockState state, BlockGetter getter, BlockPos pos) { + return SHAPE; + } + + @Override + public boolean useShapeForLightOcclusion(BlockState state) { + return true; + } + + @Nullable @Override + public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { + return new SculkShriekerBlockEntity(pos, state); + } + + @Override + public BlockState updateShape(BlockState state, Direction direction, BlockState newState, LevelAccessor level, BlockPos pos, BlockPos newPos) { + if (state.getValue(WATERLOGGED)) level.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(level)); + return super.updateShape(state, direction, newState, level, pos, newPos); + } + + @Nullable @Override + public BlockState getStateForPlacement(BlockPlaceContext context) { + return this.defaultBlockState().setValue(WATERLOGGED, context.getLevel().getFluidState(context.getClickedPos()).getType() == Fluids.WATER); + } + + @Override + public FluidState getFluidState(BlockState state) { + return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state); + } + + @Override + public void spawnAfterBreak(BlockState state, ServerLevel level, BlockPos pos, ItemStack stack) { + if (EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, stack) == 0) this.popExperience(level, pos, 5); + } + + @Nullable @Override + public GameEventListener getListener(Level level, T type) { + return type instanceof SculkShriekerBlockEntity shrieker ? shrieker.getListener() : null; + } + + @Nullable @Override + public BlockEntityTicker getTicker(Level level, BlockState state, BlockEntityType type) { + return !level.isClientSide ? createTickerHelper(type, WBBlockEntities.SCULK_SHRIEKER.get(), (levelIn, posIn, stateIn, shrieker) -> shrieker.getListener().tick(levelIn)) : null; + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/SculkSpreadManager.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/SculkSpreadManager.java new file mode 100644 index 0000000..7e58905 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/SculkSpreadManager.java @@ -0,0 +1,388 @@ +package com.cursedcauldron.wildbackport.common.blocks; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.client.particle.SculkChargeParticleOptions; +import com.cursedcauldron.wildbackport.client.registry.WBParticleTypes; +import com.cursedcauldron.wildbackport.client.registry.WBSoundEvents; +import com.cursedcauldron.wildbackport.common.tag.WBBlockTags; +import com.cursedcauldron.wildbackport.common.utils.DirectionUtils; +import com.cursedcauldron.wildbackport.common.utils.ModUtils; +import com.cursedcauldron.wildbackport.common.utils.ParticleUtils; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import com.mojang.serialization.Codec; +import com.mojang.serialization.Dynamic; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import net.minecraft.Util; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Vec3i; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtOps; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.sounds.SoundSource; +import net.minecraft.tags.TagKey; +import net.minecraft.util.Mth; +import net.minecraft.util.valueproviders.UniformInt; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.Vec3; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Random; +import java.util.Set; +import java.util.function.Supplier; + +public class SculkSpreadManager { + final boolean isWorldGen; + private final TagKey replaceableBlocks; + private final int extraBlockChance; + private final int maxDistance; + private final int spreadChance; + private final int decayChance; + private List cursors = new ArrayList<>(); + + public SculkSpreadManager(boolean isWorldGen, TagKey replaceableBlocks, int extraBlockChance, int maxDistance, int spreadChance, int decayChance) { + this.isWorldGen = isWorldGen; + this.replaceableBlocks = replaceableBlocks; + this.extraBlockChance = extraBlockChance; + this.maxDistance = maxDistance; + this.spreadChance = spreadChance; + this.decayChance = decayChance; + } + + public static SculkSpreadManager create() { + return new SculkSpreadManager(false, WBBlockTags.SCULK_REPLACEABLE, 10, 4, 10, 5); + } + + public static SculkSpreadManager createWorldGen() { + return new SculkSpreadManager(true, WBBlockTags.SCULK_REPLACEABLE_WORLD_GEN, 50, 1, 5, 10); + } + + public TagKey getReplaceableBlocks() { + return this.replaceableBlocks; + } + + public int getExtraBlockChance() { + return this.extraBlockChance; + } + + public int getMaxDistance() { + return this.maxDistance; + } + + public int getSpreadChance() { + return this.spreadChance; + } + + public int getDecayChance() { + return this.decayChance; + } + + public boolean isWorldGen() { + return this.isWorldGen; + } + + public void clearCursors() { + this.cursors.clear(); + } + + public void readTag(CompoundTag tag) { + if (tag.contains("cursors", 9)) { + this.cursors.clear(); + List cursors = Cursor.CODEC.listOf().parse(new Dynamic<>(NbtOps.INSTANCE, tag.getList("cursors", 10))).resultOrPartial(WildBackport.LOGGER::error).orElseGet(ArrayList::new); + int size = Math.min(cursors.size(), 32); + + for (int i = 0; i < size; i++) { + this.addCursor(cursors.get(i)); + } + } + } + + public void writeTag(CompoundTag tag) { + Cursor.CODEC.listOf().encodeStart(NbtOps.INSTANCE, this.cursors).resultOrPartial(WildBackport.LOGGER::error).ifPresent(value -> { + tag.put("cursors", value); + }); + } + + public void spread(BlockPos pos, int charge) { + while (charge > 0) { + int spread = Math.min(charge, 1000); + this.addCursor(new Cursor(pos, spread)); + charge -= spread; + } + } + + private void addCursor(Cursor cursor) { + if (this.cursors.size() < 32) { + this.cursors.add(cursor); + } + } + + public void tick(LevelAccessor level, BlockPos pos, Random random, boolean shouldConvert) { + Level instance = level instanceof Level side ? side : null; + if (!this.cursors.isEmpty()) { + List cursors = new ArrayList<>(); + Map cursorPositions = new HashMap<>(); + Object2IntMap positions = new Object2IntOpenHashMap<>(); + + for (Cursor cursor : this.cursors) { + cursor.spread(level, pos, random, this, shouldConvert); + if (cursor.charge <= 0) { + applySculkCharge(instance, cursor.getPos(), 0); + } else { + BlockPos position = cursor.getPos(); + positions.computeInt(position, (blockPos, charge) -> (charge == null ? 0 : charge) + cursor.charge); + Cursor target = cursorPositions.get(position); + if (target == null) { + cursorPositions.put(position, cursor); + cursors.add(cursor); + } else if (!this.isWorldGen() && cursor.charge + target.charge <= 1000) { + target.merge(cursor); + } else { + cursors.add(cursor); + if (cursor.charge < target.charge) { + cursorPositions.put(position, cursor); + } + } + } + } + + for (Object2IntMap.Entry entry : positions.object2IntEntrySet()) { + BlockPos position = entry.getKey(); + int exp = entry.getIntValue(); + Cursor cursor = cursorPositions.get(position); + Set directions = cursor == null ? null : cursor.getFacings(); + if (exp > 0 && directions != null) { + int charge = (int)(Math.log1p(exp) / (double)2.3F) + 1; + int data = (charge << 6) + SculkVeinBlock.directionsToFlag(directions); + applySculkCharge(instance, cursor.getPos(), data); + } + } + + this.cursors = cursors; + } + } + + public static class Cursor { + private static final ObjectArrayList OFFSETS = Util.make(new ObjectArrayList<>(18), positions -> { + BlockPos.betweenClosedStream(new BlockPos(-1, -1, -1), new BlockPos(1, 1, 1)).filter(pos -> { + return (pos.getX() == 0 || pos.getY() == 0 || pos.getZ() == 0) && pos != BlockPos.ZERO; + }).map(BlockPos::immutable).forEach(positions::add); + }); + private BlockPos pos; + private int charge; + private int updateDelay; + private int decayDelay; + @Nullable + private Set facings; + private static final Codec> DIRECTION_SET = Direction.CODEC.listOf().xmap(directions -> Sets.newEnumSet(directions, Direction.class), Lists::newArrayList); + public static final Codec CODEC = RecordCodecBuilder.create(instance -> { + return instance.group(BlockPos.CODEC.fieldOf("pos").forGetter(Cursor::getPos), Codec.intRange(0, 1000).fieldOf("charge").orElse(0).forGetter(Cursor::getCharge), Codec.intRange(0, 1).fieldOf("decay_delay").orElse(1).forGetter(Cursor::getDecayDelay), Codec.intRange(0, Integer.MAX_VALUE).fieldOf("update_delay").orElse(0).forGetter(cursor -> { + return cursor.updateDelay; + }), DIRECTION_SET.optionalFieldOf("facings").forGetter(cursor -> { + return Optional.ofNullable(cursor.getFacings()); + })).apply(instance, Cursor::new); + }); + + private Cursor(BlockPos pos, int charge, int decayDelay, int updateDelay, Optional> facings) { + this.pos = pos; + this.charge = charge; + this.decayDelay = decayDelay; + this.updateDelay = updateDelay; + this.facings = facings.orElse(null); + } + + public Cursor(BlockPos pos, int charge) { + this(pos, charge, 1, 0, Optional.empty()); + } + + public BlockPos getPos() { + return this.pos; + } + + public int getCharge() { + return this.charge; + } + + public int getDecayDelay() { + return this.decayDelay; + } + + @Nullable + public Set getFacings() { + return this.facings; + } + + private boolean canSpread(LevelAccessor level, BlockPos pos, boolean isWorldGen) { + if (this.charge <= 0) { + return false; + } else if (isWorldGen) { + return true; + } else if (level instanceof ServerLevel server) { + return server.shouldTickBlocksAt(ChunkPos.asLong(pos)); + } else { + return false; + } + } + + public void spread(LevelAccessor level, BlockPos pos, Random random, SculkSpreadManager spreadManager, boolean shouldConvert) { + if (this.canSpread(level, pos, spreadManager.isWorldGen)) { + if (this.updateDelay > 0) { + --this.updateDelay; + } else { + BlockState state = level.getBlockState(this.pos); + SculkSpreadable spreadable = getSpreadable(state); + if (shouldConvert && spreadable.spread(level, this.pos, state, this.facings, spreadManager.isWorldGen())) { + if (spreadable.shouldConvertToSpreadable()) { + state = level.getBlockState(this.pos); + spreadable = getSpreadable(state); + } + + level.playSound(null, this.pos, WBSoundEvents.BLOCK_SCULK_BREAK, SoundSource.BLOCKS, 1.0F, 1.0F); + } + + this.charge = spreadable.spread(this, level, pos, random, spreadManager, shouldConvert); + if (this.charge <= 0) { + spreadable.spreadAtSamePosition(level, state, this.pos, random); + } else { + BlockPos target = getSpreadPos(level, this.pos, random); + if (target != null) { + spreadable.spreadAtSamePosition(level, state, this.pos, random); + this.pos = target.immutable(); + if (spreadManager.isWorldGen() && !this.pos.closerThan(new Vec3i(pos.getX(), this.pos.getY(), pos.getZ()), 15.0D)) { + this.charge = 0; + return; + } + + state = level.getBlockState(target); + } + + if (state.getBlock() instanceof SculkSpreadable) { + this.facings = SculkVeinBlock.collectDirections(state); + } + + this.decayDelay = spreadable.getDecay(this.decayDelay); + this.updateDelay = spreadable.getUpdate(); + } + } + } + } + + void merge(Cursor cursor) { + this.charge += cursor.charge; + cursor.charge = 0; + this.updateDelay = Math.min(this.updateDelay, cursor.updateDelay); + } + + private static SculkSpreadable getSpreadable(BlockState state) { + return state.getBlock() instanceof SculkSpreadable spreadable ? spreadable : SculkSpreadable.DEFAULT; + } + + private static List shuffleOffsets(Random random) { + return ModUtils.copyShuffled(OFFSETS, random); + } + + @Nullable + private static BlockPos getSpreadPos(LevelAccessor level, BlockPos pos, Random random) { + BlockPos.MutableBlockPos target = pos.mutable(); + BlockPos.MutableBlockPos source = pos.mutable(); + + for (Vec3i offset : shuffleOffsets(random)) { + source.setWithOffset(pos, offset); + BlockState state = level.getBlockState(source); + if (state.getBlock() instanceof SculkSpreadable && canSpread(level, pos, source)) { + target.set(source); + if (SculkVeinBlock.veinCoversSculkReplaceable(level, state, source)) { + break; + } + } + } + + return target.equals(pos) ? null : target; + } + + private static boolean canSpread(LevelAccessor level, BlockPos source, BlockPos target) { + if (source.distManhattan(target) == 1) { + return true; + } else { + BlockPos pos = target.subtract(target); + Direction xAxis = Direction.fromAxisAndDirection(Direction.Axis.X, pos.getX() < 0 ? Direction.AxisDirection.NEGATIVE : Direction.AxisDirection.POSITIVE); + Direction yAxis = Direction.fromAxisAndDirection(Direction.Axis.Y, pos.getY() < 0 ? Direction.AxisDirection.NEGATIVE : Direction.AxisDirection.POSITIVE); + Direction zAxis = Direction.fromAxisAndDirection(Direction.Axis.Z, pos.getZ() < 0 ? Direction.AxisDirection.NEGATIVE : Direction.AxisDirection.POSITIVE); + if (pos.getX() == 0) { + return canSpread(level, source, yAxis) || canSpread(level, source, zAxis); + } else if (pos.getY() == 0) { + return canSpread(level, source, xAxis) || canSpread(level, source, zAxis); + } else { + return canSpread(level, source, xAxis) || canSpread(level, source, yAxis); + } + } + } + + private static boolean canSpread(LevelAccessor level, BlockPos pos, Direction direction) { + BlockPos facing = pos.relative(direction); + return !level.getBlockState(facing).isFaceSturdy(level, facing, direction.getOpposite()); + } + } + + public static void applySculkCharge(Level level, BlockPos pos, int data) { + if (level == null) return; + + Random random = level.getRandom(); + ClientLevel client = level instanceof ClientLevel side ? side : null; + ServerLevel server = level instanceof ServerLevel side ? side : null; + + int charge = data >> 6; + if (charge > 0) { + if (random.nextFloat() < (float)charge * 0.2F) { + float volume = 0.15F + 0.05F * (float)charge * (float)charge * random.nextFloat(); + float pitch = 0.4F * (float)charge - 0.2F * random.nextFloat(); + if (client != null) client.playLocalSound(pos, WBSoundEvents.BLOCK_SCULK_CHARGE, SoundSource.BLOCKS, volume, pitch, false); + } + + int facings = (byte)(data & 63); + UniformInt spread = UniformInt.of(0, charge); + Supplier velocities = () -> { + return new Vec3(Mth.nextDouble(random, -0.005D, 0.005D), Mth.nextDouble(random, -0.005D, 0.005D), Mth.nextDouble(random, -0.005D, 0.005D)); + }; + + if (facings == 0) { + for (Direction direction : Direction.values()) { + float roll = direction == Direction.DOWN ? (float)Math.PI : 0.0F; + double offset = direction == Direction.UP || direction == Direction.DOWN ? 0.32D : 0.57D; + ParticleUtils.spawnParticles(level, pos, new SculkChargeParticleOptions(roll), spread, direction, velocities, offset); + } + } else { + for (Direction direction : DirectionUtils.unpack((byte)data)) { + float roll = direction == Direction.UP ? (float)Math.PI : 0.0F; + ParticleUtils.spawnParticles(level, pos, new SculkChargeParticleOptions(roll), spread, direction, velocities, 0.35D); + } + } + } else { + if (client != null) client.playLocalSound(pos, WBSoundEvents.BLOCK_SCULK_CHARGE, SoundSource.BLOCKS, 1.0F, 1.0F, false); + boolean fullBlock = level.getBlockState(pos).isCollisionShapeFullBlock(level, pos); + int tries = fullBlock ? 40 : 20; + float spread = fullBlock ? 0.45F : 0.25F; + + for (int i = 0; i < tries; i++) { + float x = 2.0F * random.nextFloat() - 1.0F; + float y = 2.0F * random.nextFloat() - 1.0F; + float z = 2.0F * random.nextFloat() - 1.0F; + if (server != null) server.sendParticles(WBParticleTypes.SCULK_CHARGE_POP.get(), (double)pos.getX() + 0.5D + (double)(x * spread), (double)pos.getY() + 0.5D + (double)(y * spread), (double)pos.getZ() + 0.5D + (double)(z * spread), 1, x * 0.07F, y * 0.07F, z * 0.07F, 0.0D); + } + } + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/SculkSpreadable.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/SculkSpreadable.java new file mode 100644 index 0000000..3544c91 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/SculkSpreadable.java @@ -0,0 +1,57 @@ +package com.cursedcauldron.wildbackport.common.blocks; + +import com.cursedcauldron.wildbackport.common.registry.WBBlocks; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.Fluids; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; +import java.util.Random; + +public interface SculkSpreadable { + SculkSpreadable DEFAULT = new SculkSpreadable() { + @Override + public boolean spread(LevelAccessor level, BlockPos pos, BlockState state, @Nullable Collection directions, boolean postProcess) { + if (directions == null) { + return ((SculkVeinBlock)WBBlocks.SCULK_VEIN.get()).getSamePositionOnlyGrower().grow(level.getBlockState(pos), level, pos, postProcess) > 0L; + } else if(!directions.isEmpty()) { + return (state.isAir() || state.getFluidState().is(Fluids.WATER)) && SculkVeinBlock.place(level, pos, state, directions); + } else { + return SculkSpreadable.super.spread(level, pos, state, directions, postProcess); + } + } + + @Override + public int spread(SculkSpreadManager.Cursor cursor, LevelAccessor level, BlockPos pos, Random random, SculkSpreadManager spreadManager, boolean shouldConvert) { + return cursor.getDecayDelay() > 0 ? cursor.getCharge() : 0; + } + + @Override + public int getDecay(int oldDecay) { + return Math.max(oldDecay - 1, 0); + } + }; + + default byte getUpdate() { + return 1; + } + + default void spreadAtSamePosition(LevelAccessor level, BlockState state, BlockPos pos, Random random) {} + + default boolean spread(LevelAccessor level, BlockPos pos, BlockState state, @Nullable Collection directions, boolean postProcess) { + return ((SculkVeinBlock)WBBlocks.SCULK_VEIN.get()).getAllGrowTypeGrower().grow(state, level, pos, postProcess) > 0L; + } + + default boolean shouldConvertToSpreadable() { + return true; + } + + default int getDecay(int oldDecay) { + return 1; + } + + int spread(SculkSpreadManager.Cursor cursor, LevelAccessor level, BlockPos pos, Random random, SculkSpreadManager manager, boolean shouldConvert); +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/SculkVeinBlock.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/SculkVeinBlock.java new file mode 100644 index 0000000..55ab0be --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/SculkVeinBlock.java @@ -0,0 +1,263 @@ +package com.cursedcauldron.wildbackport.common.blocks; + +import com.cursedcauldron.wildbackport.client.registry.WBSoundEvents; +import com.cursedcauldron.wildbackport.common.worldgen.VeinGrower; +import com.cursedcauldron.wildbackport.common.registry.WBBlocks; +import com.cursedcauldron.wildbackport.common.tag.WBBlockTags; +import com.cursedcauldron.wildbackport.common.utils.DirectionUtils; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.sounds.SoundSource; +import net.minecraft.tags.TagKey; +import net.minecraft.util.Mth; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.MultifaceBlock; +import net.minecraft.world.level.block.SimpleWaterloggedBlock; +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.material.FluidState; +import net.minecraft.world.level.material.Fluids; +import net.minecraft.world.level.material.PushReaction; + +import java.util.Collection; +import java.util.EnumSet; +import java.util.Random; +import java.util.Set; + +//<> + +public class SculkVeinBlock extends MultifaceBlock implements SculkSpreadable, SimpleWaterloggedBlock { + private static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; + public final VeinGrower allGrowTypeGrower = new VeinGrower(new SculkVeinGrowChecker(VeinGrower.GROW_TYPES)); + private final VeinGrower samePositionOnlyGrower = new VeinGrower(new SculkVeinGrowChecker(VeinGrower.GrowType.SAME_POSITION)); + + public SculkVeinBlock(Properties properties) { + super(properties); + this.registerDefaultState(this.defaultBlockState().setValue(WATERLOGGED, false)); + } + + public VeinGrower getAllGrowTypeGrower() { + return this.allGrowTypeGrower; + } + + + public VeinGrower getSamePositionOnlyGrower() { + return this.samePositionOnlyGrower; + } + + public static boolean place(LevelAccessor level, BlockPos pos, BlockState state, Collection directions) { + boolean canPlace = false; + BlockState veinState = WBBlocks.SCULK_VEIN.get().defaultBlockState(); + + for (Direction direction : directions) { + BlockPos blockPos = pos.relative(direction); + if (canGrowOn(level, direction, blockPos, level.getBlockState(blockPos))) { + veinState = veinState.setValue(getFaceProperty(direction), true); + canPlace = true; + } + } + + if (!canPlace) { + return false; + } else { + if (!state.getFluidState().isEmpty()) { + veinState = veinState.setValue(WATERLOGGED, true); + } + + level.setBlock(pos, veinState, 3); + return true; + } + } + + @Override + public void spreadAtSamePosition(LevelAccessor level, BlockState state, BlockPos pos, Random random) { + if (state.is(this)) { + for (Direction direction : DIRECTIONS) { + BooleanProperty property = getFaceProperty(direction); + if (state.getValue(property) && level.getBlockState(pos.relative(direction)).is(WBBlocks.SCULK.get())) { + state = state.setValue(property, false); + } + } + + if (!hasAnyFace(state)) { + FluidState fluid = level.getFluidState(pos); + state = (fluid.isEmpty() ? Blocks.AIR : Blocks.WATER).defaultBlockState(); + } + + level.setBlock(pos, state, 3); + SculkSpreadable.super.spreadAtSamePosition(level, state, pos, random); + } + } + + @Override + public int spread(SculkSpreadManager.Cursor cursor, LevelAccessor level, BlockPos pos, Random random, SculkSpreadManager spreadManager, boolean shouldConvert) { + if (shouldConvert && this.convertToBlock(spreadManager, level, cursor.getPos(), random)) { + return cursor.getCharge() - 1; + } else { + return random.nextInt(spreadManager.getSpreadChance()) == 0 ? Mth.floor((float)cursor.getCharge() * 0.5F) : cursor.getCharge(); + } + } + + private boolean convertToBlock(SculkSpreadManager spreadManager, LevelAccessor level, BlockPos pos, Random random) { + BlockState state = level.getBlockState(pos); + TagKey replaceable = spreadManager.getReplaceableBlocks(); + + for (Direction direction : DirectionUtils.shuffle(random)) { + if (hasFace(state, direction)) { + BlockPos blockPos = pos.relative(direction); + BlockState blockState = level.getBlockState(blockPos); + if (blockState.is(replaceable)) { + BlockState sculk = WBBlocks.SCULK.get().defaultBlockState(); + level.setBlock(blockPos, sculk, 3); + Block.pushEntitiesUp(blockState, sculk, (ServerLevel)level, pos); + level.playSound(null, blockPos, WBSoundEvents.BLOCK_SCULK_SPREAD, SoundSource.BLOCKS, 1.0F, 1.0F); + this.allGrowTypeGrower.grow(sculk, level, blockPos, spreadManager.isWorldGen()); + Direction opposite = direction.getOpposite(); + + for (Direction towards : DIRECTIONS) { + if (towards != opposite) { + BlockPos targetPos = blockPos.relative(towards); + BlockState targetState = level.getBlockState(targetPos); + if (targetState.is(this)) { + this.spreadAtSamePosition(level, targetState, targetPos, random); + } + } + } + + return true; + } + } + } + + return false; + } + + public static boolean veinCoversSculkReplaceable(LevelAccessor level, BlockState state, BlockPos pos) { + if (state.is(WBBlocks.SCULK_VEIN.get())) { + for (Direction direction : DIRECTIONS) { + if (hasFace(state, direction) && level.getBlockState(pos.relative(direction)).is(WBBlockTags.SCULK_REPLACEABLE)) { + return true; + } + } + } + + return false; + } + + public boolean canGrowWithDirection(BlockGetter getter, BlockState state, BlockPos pos, Direction direction) { + if (this.isFaceSupported(direction) && (!state.is(this) || !hasFace(state, direction))) { + BlockPos blockPos = pos.relative(direction); + return canGrowOn(getter, direction, blockPos, getter.getBlockState(blockPos)); + } else { + return false; + } + } + + @Override + public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) { + if (state.getValue(WATERLOGGED)) { + world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world)); + } + return super.updateShape(state, direction, neighborState, world, pos, neighborPos); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + super.createBlockStateDefinition(builder); + builder.add(WATERLOGGED); + } + + @Override + public boolean canBeReplaced(BlockState state, BlockPlaceContext context) { + return !context.getItemInHand().is(WBBlocks.SCULK_VEIN.get().asItem()) || super.canBeReplaced(state, context); + } + + @Override + public FluidState getFluidState(BlockState state) { + return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state); + } + + @Override + public PushReaction getPistonPushReaction(BlockState p_60584_) { + return PushReaction.DESTROY; + } + + public static byte directionsToFlag(Collection directions) { + byte flag = 0; + + for (Direction direction : directions) { + flag = (byte)(flag | 1 << direction.ordinal()); + } + + return flag; + } + + public static Set collectDirections(BlockState state) { + if (!(state.getBlock() instanceof MultifaceBlock)) { + return Set.of(); + } else { + Set directions = EnumSet.noneOf(Direction.class); + + for (Direction direction : DIRECTIONS) { + if (hasFace(state, direction)) { + directions.add(direction); + } + } + + return directions; + } + } + + public static boolean canGrowOn(BlockGetter getter, Direction direction, BlockPos pos, BlockState state) { + return Block.isFaceFull(state.getBlockSupportShape(getter, pos), direction.getOpposite()) || Block.isFaceFull(state.getCollisionShape(getter, pos), direction.getOpposite()); + } + + public static boolean hasFace(BlockState state, Direction direction) { + BooleanProperty booleanProperty = MultifaceBlock.getFaceProperty(direction); + return state.hasProperty(booleanProperty) && state.getValue(booleanProperty); + } + + class SculkVeinGrowChecker extends VeinGrower.VeinGrowChecker { + private final VeinGrower.GrowType[] growTypes; + + public SculkVeinGrowChecker(VeinGrower.GrowType... growTypes) { + super(SculkVeinBlock.this); + this.growTypes = growTypes; + } + + @Override + public boolean canGrow(BlockGetter getter, BlockPos pos, BlockPos growPos, Direction direction, BlockState state) { + BlockPos blockPos; + BlockState blockState = getter.getBlockState(growPos.relative(direction)); + boolean flag = blockState.is(WBBlocks.SCULK.get()) || blockState.is(WBBlocks.SCULK_CATALYST.get()) || blockState.is(Blocks.MOVING_PISTON); + if (flag) { + return false; + } + if (pos.distManhattan(growPos) == 2 && getter.getBlockState(blockPos = pos.relative(direction.getOpposite())).isFaceSturdy(getter, blockPos, direction)) { + return false; + } + FluidState fluidState = state.getFluidState(); + if (!fluidState.isEmpty() && !fluidState.is(Fluids.WATER)) { + return false; + } + return state.getMaterial().isReplaceable() || super.canGrow(getter, pos, growPos, direction, state); + } + + @Override + public VeinGrower.GrowType[] getGrowTypes() { + return this.growTypes; + } + + @Override + public boolean canGrow(BlockState state) { + return !state.is(WBBlocks.SCULK_VEIN.get()); + } + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/entity/MangroveSignBlockEntity.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/entity/MangroveSignBlockEntity.java new file mode 100644 index 0000000..6eb2325 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/entity/MangroveSignBlockEntity.java @@ -0,0 +1,11 @@ +package com.cursedcauldron.wildbackport.common.blocks.entity; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.block.entity.SignBlockEntity; +import net.minecraft.world.level.block.state.BlockState; + +public class MangroveSignBlockEntity extends SignBlockEntity { + public MangroveSignBlockEntity(BlockPos pos, BlockState state) { + super(pos, state); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/entity/SculkCatalystBlockEntity.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/entity/SculkCatalystBlockEntity.java new file mode 100644 index 0000000..1422a37 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/entity/SculkCatalystBlockEntity.java @@ -0,0 +1,90 @@ +package com.cursedcauldron.wildbackport.common.blocks.entity; + +import com.cursedcauldron.wildbackport.client.registry.WBCriteriaTriggers; +import com.cursedcauldron.wildbackport.common.blocks.SculkCatalystBlock; +import com.cursedcauldron.wildbackport.common.blocks.SculkSpreadManager; +import com.cursedcauldron.wildbackport.common.entities.access.EntityExperience; +import com.cursedcauldron.wildbackport.common.registry.WBBlockEntities; +import com.cursedcauldron.wildbackport.common.registry.WBGameEvents; +import com.cursedcauldron.wildbackport.common.utils.PositionUtils; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.gameevent.BlockPositionSource; +import net.minecraft.world.level.gameevent.GameEvent; +import net.minecraft.world.level.gameevent.GameEventListener; +import net.minecraft.world.level.gameevent.PositionSource; +import org.jetbrains.annotations.Nullable; + +//<> + +public class SculkCatalystBlockEntity extends BlockEntity implements GameEventListener { + private final BlockPositionSource positionSource = new BlockPositionSource(this.worldPosition); + private final SculkSpreadManager spreadManager = SculkSpreadManager.create(); + + public SculkCatalystBlockEntity(BlockPos pos, BlockState state) { + super(WBBlockEntities.SCULK_CATALYST.get(), pos, state); + } + + @Override + public PositionSource getListenerSource() { + return this.positionSource; + } + + @Override + public int getListenerRadius() { + return 8; + } + + @Override + public boolean handleGameEvent(Level level, GameEvent event, @Nullable Entity entity, BlockPos pos) { + if (!this.isRemoved()) { + if (event == WBGameEvents.ENTITY_DIE.get()) { + if (entity instanceof LivingEntity living && living instanceof EntityExperience mob) { + if (!mob.isExpDropDisabled()) { + int charge = mob.getExpToDrop(); + if (!living.isBaby() && charge > 0) { + this.spreadManager.spread(new BlockPos(PositionUtils.relative(PositionUtils.toVec(pos), Direction.UP, 0.5D)), charge); + LivingEntity attacker = living.getLastHurtByMob(); + if (attacker instanceof ServerPlayer player) { + DamageSource source = living.getLastDamageSource() == null ? DamageSource.playerAttack(player) : living.getLastDamageSource(); + WBCriteriaTriggers.KILL_MOB_NEAR_SCULK_CATALYST.trigger(player, entity, source); + } + } + + mob.disableExpDrop(); + SculkCatalystBlock.bloom((ServerLevel) level, this.worldPosition, this.getBlockState(), level.getRandom()); + } + + return true; + } + } + } + + return false; + } + + public static void tick(Level level, BlockPos pos, BlockState state, SculkCatalystBlockEntity catalyst) { + catalyst.spreadManager.tick(level, pos, level.getRandom(), true); + } + + @Override + public void load(CompoundTag tag) { + super.load(tag); + this.spreadManager.readTag(tag); + } + + @Override + protected void saveAdditional(CompoundTag tag) { + super.saveAdditional(tag); + this.spreadManager.writeTag(tag); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/entity/SculkShriekerBlockEntity.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/entity/SculkShriekerBlockEntity.java new file mode 100644 index 0000000..b2c95de --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/blocks/entity/SculkShriekerBlockEntity.java @@ -0,0 +1,186 @@ +package com.cursedcauldron.wildbackport.common.blocks.entity; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.client.particle.ShriekParticleOptions; +import com.cursedcauldron.wildbackport.client.registry.WBSoundEvents; +import com.cursedcauldron.wildbackport.common.blocks.SculkShriekerBlock; +import com.cursedcauldron.wildbackport.common.entities.warden.VibrationListenerSource; +import com.cursedcauldron.wildbackport.common.entities.Warden; +import com.cursedcauldron.wildbackport.common.entities.warden.WardenSpawnHelper; +import com.cursedcauldron.wildbackport.common.entities.warden.WardenSpawnTracker; +import com.cursedcauldron.wildbackport.common.registry.WBBlockEntities; +import com.cursedcauldron.wildbackport.common.registry.WBGameEvents; +import com.cursedcauldron.wildbackport.common.tag.WBGameEventTags; +import com.mojang.serialization.Dynamic; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import net.minecraft.Util; +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtOps; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.sounds.SoundSource; +import net.minecraft.tags.TagKey; +import net.minecraft.util.Mth; +import net.minecraft.world.Difficulty; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.MobSpawnType; +import net.minecraft.world.entity.projectile.Projectile; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.gameevent.BlockPositionSource; +import net.minecraft.world.level.gameevent.GameEvent; +import net.minecraft.world.level.gameevent.GameEventListener; +import net.minecraft.world.phys.Vec3; +import org.jetbrains.annotations.Nullable; + +import java.util.OptionalInt; + +//<> + +public class SculkShriekerBlockEntity extends BlockEntity implements VibrationListenerSource.VibrationConfig { + private static final Int2ObjectMap SOUND_BY_LEVEL = Util.make(new Int2ObjectOpenHashMap<>(), map -> { + map.put(1, WBSoundEvents.WARDEN_NEARBY_CLOSE); + map.put(2, WBSoundEvents.WARDEN_NEARBY_CLOSER); + map.put(3, WBSoundEvents.WARDEN_NEARBY_CLOSEST); + map.put(4, WBSoundEvents.WARDEN_LISTENING_ANGRY); + }); + private int warningLevel; + private VibrationListenerSource listener = new VibrationListenerSource(new BlockPositionSource(this.worldPosition), 8, this, null, 0.0F, 0); + + public SculkShriekerBlockEntity(BlockPos pos, BlockState state) { + super(WBBlockEntities.SCULK_SHRIEKER.get(), pos, state); + } + + public VibrationListenerSource getListener() { + return this.listener; + } + + @Override + public void load(CompoundTag tag) { + super.load(tag); + if (tag.contains("warning_level", 99)) { + this.warningLevel = tag.getInt("warning_level"); + } + + if (tag.contains("listener", 10)) { + VibrationListenerSource.codec(this).parse(new Dynamic<>(NbtOps.INSTANCE, tag.getCompound("listener"))).resultOrPartial(WildBackport.LOGGER::error).ifPresent(listener -> this.listener = listener); + } + } + + @Override + protected void saveAdditional(CompoundTag tag) { + super.saveAdditional(tag); + tag.putInt("warning_level", this.warningLevel); + VibrationListenerSource.codec(this).encodeStart(NbtOps.INSTANCE, this.listener).resultOrPartial(WildBackport.LOGGER::error).ifPresent(listener -> tag.put("listener", listener)); + } + + @Override + public TagKey getListenableEvents() { + return WBGameEventTags.WARDEN_CAN_LISTEN; + } + + @Override + public boolean shouldListen(ServerLevel level, GameEventListener listener, BlockPos pos, GameEvent event, @Nullable Entity entity) { + return !this.isRemoved() && !this.getBlockState().getValue(SculkShriekerBlock.SHRIEKING) && tryGetPlayer(entity) != null; + } + + @Nullable + public static ServerPlayer tryGetPlayer(@Nullable Entity entity) { + if (entity instanceof ServerPlayer player) { + return player; + } else { + if (entity != null) { + Entity passenger = entity.getControllingPassenger(); + if (passenger instanceof ServerPlayer player) { + return player; + } + } + + if (entity instanceof Projectile projectile) { + Entity owner = projectile.getOwner(); + if (owner instanceof ServerPlayer player) { + return player; + } + } + + return null; + } + } + + @Override + public void onSignalReceive(ServerLevel level, GameEventListener listener, BlockPos pos, GameEvent event, @Nullable Entity entity, @Nullable Entity source, float distance) { + this.tryShriek(level, tryGetPlayer(source != null ? source : entity)); + } + + public void tryShriek(ServerLevel level, @Nullable ServerPlayer player) { + if (player != null) { + BlockState state = this.getBlockState(); + if (!state.getValue(SculkShriekerBlock.SHRIEKING)) { + this.warningLevel = 0; + if (!this.canRespond(level) || this.tryToWarn(level, player)) { + this.shriek(level, player); + } + } + } + } + + private boolean tryToWarn(ServerLevel level, ServerPlayer player) { + OptionalInt warning = WardenSpawnTracker.tryWarn(level, this.getBlockPos(), player); + warning.ifPresent(warningLevel -> this.warningLevel = warningLevel); + return warning.isPresent(); + } + + private void shriek(ServerLevel level, @Nullable Entity entity) { + BlockPos pos = this.getBlockPos(); + BlockState state = this.getBlockState(); + level.setBlock(pos, state.setValue(SculkShriekerBlock.SHRIEKING, true), 2); + level.scheduleTick(pos, state.getBlock(), 90); + + level.playSound(null, pos.getX(), pos.getY(), pos.getZ(), WBSoundEvents.BLOCK_SCULK_SHRIEKER_SHRIEK, SoundSource.BLOCKS, 2.0F, 0.6F + level.random.nextFloat() * 0.4F); + for (int i = 0; i < 10; i++) { + int delay = i * 5; + level.sendParticles(new ShriekParticleOptions(delay), pos.getX() + 0.5D, pos.getY() + SculkShriekerBlock.TOP_Y, pos.getZ() + 0.5D, 1, 0.0D, 0.0D, 0.0D, 0.0D); + } + + level.gameEvent(entity, WBGameEvents.SHRIEK.get(), pos); + } + + private boolean canRespond(ServerLevel level) { + //TODO: add gamerule for warden spawning + return this.getBlockState().getValue(SculkShriekerBlock.CAN_SUMMON) && level.getDifficulty() != Difficulty.PEACEFUL; + } + + public void tryRespond(ServerLevel level) { + if (this.canRespond(level) && this.warningLevel > 0) { + if (!this.trySummonWarden(level)) { + this.playWardenReplySound(); + } + + Warden.addDarknessEffectToClosePlayers(level, Vec3.atCenterOf(this.getBlockPos()), null, 40); + } + } + + private void playWardenReplySound() { + SoundEvent sound = SOUND_BY_LEVEL.get(this.warningLevel); + if (sound != null && this.level != null) { + BlockPos pos = this.getBlockPos(); + int x = pos.getX() + Mth.randomBetweenInclusive(this.level.random, -10, 10); + int y = pos.getY() + Mth.randomBetweenInclusive(this.level.random, -10, 10); + int z = pos.getZ() + Mth.randomBetweenInclusive(this.level.random, -10, 10); + this.level.playSound(null, x, y, z, sound, SoundSource.HOSTILE, 5.0F, 1.0F); + } + } + + private boolean trySummonWarden(ServerLevel level) { + return this.warningLevel >= 4 && WardenSpawnHelper.trySpawnMob(EntityType.IRON_GOLEM, MobSpawnType.TRIGGERED, level, this.getBlockPos(), 20, 5, 6).isPresent(); + } + + @Override + public void onSignalSchedule() { + this.setChanged(); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/enchantments/SwiftSneakEnchantment.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/enchantments/SwiftSneakEnchantment.java new file mode 100644 index 0000000..21ff16d --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/enchantments/SwiftSneakEnchantment.java @@ -0,0 +1,41 @@ +package com.cursedcauldron.wildbackport.common.enchantments; + +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.item.enchantment.Enchantment; +import net.minecraft.world.item.enchantment.EnchantmentCategory; + +public class SwiftSneakEnchantment extends Enchantment { + public SwiftSneakEnchantment(Rarity rarity, EquipmentSlot[] equipmentSlots) { + super(rarity, EnchantmentCategory.ARMOR_LEGS, equipmentSlots); + } + + @Override + public int getMinCost(int level) { + return level * 25; + } + + @Override + public int getMaxCost(int level) { + return this.getMinCost(level) + 50; + } + + @Override + public boolean isTreasureOnly() { + return true; + } + + @Override + public boolean isDiscoverable() { + return false; + } + + @Override + public boolean isTradeable() { + return true; + } + + @Override + public int getMaxLevel() { + return 3; + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/Allay.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/Allay.java new file mode 100644 index 0000000..5fbcf26 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/Allay.java @@ -0,0 +1,375 @@ +package com.cursedcauldron.wildbackport.common.entities; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.client.registry.WBSoundEvents; +import com.cursedcauldron.wildbackport.common.entities.brain.AllayBrain; +import com.cursedcauldron.wildbackport.common.entities.warden.MobPositionSource; +import com.cursedcauldron.wildbackport.common.entities.warden.VibrationListenerSource; +import com.cursedcauldron.wildbackport.common.registry.WBGameEvents; +import com.cursedcauldron.wildbackport.common.registry.entity.WBMemoryModules; +import com.cursedcauldron.wildbackport.common.tag.WBGameEventTags; +import com.google.common.collect.ImmutableList; +import com.mojang.serialization.Dynamic; +import net.minecraft.core.BlockPos; +import net.minecraft.core.GlobalPos; +import net.minecraft.core.Vec3i; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtOps; +import net.minecraft.network.protocol.game.DebugPackets; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.sounds.SoundSource; +import net.minecraft.tags.TagKey; +import net.minecraft.util.Mth; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.SimpleContainer; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityDimensions; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.MoverType; +import net.minecraft.world.entity.PathfinderMob; +import net.minecraft.world.entity.Pose; +import net.minecraft.world.entity.ai.Brain; +import net.minecraft.world.entity.ai.attributes.AttributeSupplier; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.ai.behavior.BehaviorUtils; +import net.minecraft.world.entity.ai.control.FlyingMoveControl; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; +import net.minecraft.world.entity.ai.memory.MemoryStatus; +import net.minecraft.world.entity.ai.navigation.FlyingPathNavigation; +import net.minecraft.world.entity.ai.navigation.PathNavigation; +import net.minecraft.world.entity.ai.sensing.Sensor; +import net.minecraft.world.entity.ai.sensing.SensorType; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.entity.npc.InventoryCarrier; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.enchantment.EnchantmentHelper; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.gameevent.GameEvent; +import net.minecraft.world.level.gameevent.GameEventListener; +import net.minecraft.world.level.gameevent.GameEventListenerRegistrar; +import net.minecraft.world.phys.Vec3; +import org.jetbrains.annotations.Nullable; + +import java.util.Optional; +import java.util.UUID; + +//<> + +public class Allay extends PathfinderMob implements InventoryCarrier, VibrationListenerSource.VibrationConfig { + private static final Vec3i PICKUP_REACH = new Vec3i(1, 1, 1); + protected static final ImmutableList>> SENSORS = ImmutableList.of(SensorType.NEAREST_LIVING_ENTITIES, SensorType.NEAREST_PLAYERS, SensorType.HURT_BY, SensorType.NEAREST_ITEMS); + protected static final ImmutableList> MEMORIES = ImmutableList.of(MemoryModuleType.PATH, MemoryModuleType.LOOK_TARGET, MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, MemoryModuleType.WALK_TARGET, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryModuleType.HURT_BY, MemoryModuleType.NEAREST_VISIBLE_WANTED_ITEM, WBMemoryModules.LIKED_PLAYER.get(), WBMemoryModules.LIKED_NOTEBLOCK.get(), WBMemoryModules.LIKED_NOTEBLOCK_COOLDOWN_TICKS.get(), WBMemoryModules.ITEM_PICKUP_COOLDOWN_TICKS.get()); + public static final ImmutableList SOUND_PITCHES = ImmutableList.of(0.5625F, 0.625F, 0.75F, 0.9375F, 1.0F, 1.0F, 1.125F, 1.25F, 1.5F, 1.875F, 2.0F, 2.25F, 2.5F, 3.0F, 3.75F, 4.0F); + private final GameEventListenerRegistrar registrar; + private VibrationListenerSource listener; + private final SimpleContainer inventory = new SimpleContainer(1); + private float holdingTicks; + private float holdingTicksOld; + + public Allay(EntityType type, Level level) { + super(type, level); + this.moveControl = new FlyingMoveControl(this, 20, true); + this.setCanPickUpLoot(this.canPickUpLoot()); + this.listener = new VibrationListenerSource(new MobPositionSource(this, this.getEyeHeight()), 16, this, null, 0.0F, 0); + this.registrar = new GameEventListenerRegistrar(this.listener); + } + + @Override + protected Brain.Provider brainProvider() { + return Brain.provider(MEMORIES, SENSORS); + } + + @Override + protected Brain makeBrain(Dynamic dynamic) { + return AllayBrain.makeBrain(this.brainProvider().makeBrain(dynamic)); + } + + @Override @SuppressWarnings("unchecked") + public Brain getBrain() { + return (Brain)super.getBrain(); + } + + public static AttributeSupplier.Builder createAttributes() { + return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 20.0D).add(Attributes.FLYING_SPEED, 0.1F).add(Attributes.MOVEMENT_SPEED, 0.1F).add(Attributes.ATTACK_DAMAGE, 2.0D).add(Attributes.FOLLOW_RANGE, 48.0D); + } + + @Override + protected PathNavigation createNavigation(Level level) { + FlyingPathNavigation navigation = new FlyingPathNavigation(this, level); + navigation.setCanOpenDoors(false); + navigation.setCanFloat(true); + navigation.setCanPassDoors(true); + return navigation; + } + + @Override + public void travel(Vec3 movementInput) { + if (this.isEffectiveAi() || this.isControlledByLocalInstance()) { + if (this.isInWater()) { + this.moveRelative(0.02F, movementInput); + this.move(MoverType.SELF, this.getDeltaMovement()); + this.setDeltaMovement(this.getDeltaMovement().scale(0.8F)); + } else if (this.isInLava()) { + this.moveRelative(0.02F, movementInput); + this.move(MoverType.SELF, this.getDeltaMovement()); + this.setDeltaMovement(this.getDeltaMovement().scale(0.5F)); + } else { + this.moveRelative(this.getSpeed(), movementInput); + this.move(MoverType.SELF, this.getDeltaMovement()); + this.setDeltaMovement(this.getDeltaMovement().scale(0.91F)); + } + } + + this.calculateEntityAnimation(this, false); + } + + @Override + protected float getStandingEyeHeight(Pose pose, EntityDimensions dimensions) { + return dimensions.height * 0.6F; + } + + @Override + public boolean causeFallDamage(float fallDistance, float damageMultiplier, DamageSource source) { + return false; + } + + @Override + public boolean hurt(DamageSource source, float amount) { + if (source.getEntity() instanceof Player player) { + Optional likedPlayer = this.getBrain().getMemory(WBMemoryModules.LIKED_PLAYER.get()); + if (likedPlayer.isPresent() && player.getUUID().equals(likedPlayer.get())) return false; + } + + return super.hurt(source, amount); + } + + @Override + protected void playStepSound(BlockPos pos, BlockState state) {} + + @Override + protected void checkFallDamage(double fallenDistance, boolean canLand, BlockState state, BlockPos pos) {} + + @Override @Nullable + protected SoundEvent getAmbientSound() { + return this.hasItemInSlot(EquipmentSlot.MAINHAND) ? WBSoundEvents.ALLAY_AMBIENT_WITH_ITEM : WBSoundEvents.ALLAY_AMBIENT_WITHOUT_ITEM; + } + + @Override @Nullable + protected SoundEvent getHurtSound(DamageSource source) { + return WBSoundEvents.ALLAY_HURT; + } + + @Override @Nullable + protected SoundEvent getDeathSound() { + return WBSoundEvents.ALLAY_DEATH; + } + + @Override + protected float getSoundVolume() { + return 0.4F; + } + + @Override + protected void customServerAiStep() { + this.level.getProfiler().push("allayBrain"); + this.getBrain().tick((ServerLevel)this.level, this); + this.level.getProfiler().pop(); + this.level.getProfiler().push("allayActivityUpdate"); + AllayBrain.updateActivity(this); + this.level.getProfiler().pop(); + super.customServerAiStep(); + } + + @Override + public void aiStep() { + super.aiStep(); + if (!this.level.isClientSide && this.isAlive() && this.tickCount % 10 == 0) this.heal(1.0F); + } + + @Override + public void tick() { + super.tick(); + if (this.level.isClientSide) { + this.holdingTicksOld = this.holdingTicks; + if (this.hasItemInHand()) { + this.holdingTicks = Mth.clamp(this.holdingTicks + 1.0F, 0.0F, 5.0F); + } else { + this.holdingTicks = Mth.clamp(this.holdingTicks - 1.0F, 0.0F, 5.0F); + } + } else { + this.listener.tick(this.level); + } + } + + @Override + public boolean canPickUpLoot() { + return !this.isOnPickupCooldown() && this.hasItemInHand(); + } + + public boolean hasItemInHand() { + return !this.getItemInHand(InteractionHand.MAIN_HAND).isEmpty(); + } + + @Override + public boolean canTakeItem(ItemStack stack) { + return false; + } + + private boolean isOnPickupCooldown() { + return this.getBrain().checkMemory(WBMemoryModules.ITEM_PICKUP_COOLDOWN_TICKS.get(), MemoryStatus.VALUE_PRESENT); + } + + @Override + protected InteractionResult mobInteract(Player player, InteractionHand hand) { + ItemStack playerStack = player.getItemInHand(hand); + ItemStack allayStack = this.getItemInHand(InteractionHand.MAIN_HAND); + if (allayStack.isEmpty() && !playerStack.isEmpty()) { + ItemStack stack = playerStack.copy(); + stack.setCount(1); + this.setItemInHand(InteractionHand.MAIN_HAND, stack); + if (!player.getAbilities().instabuild) playerStack.shrink(1); + + this.level.playSound(player, this, WBSoundEvents.ALLAY_ITEM_GIVEN, SoundSource.NEUTRAL, 2.0F, 1.0F); + this.getBrain().setMemory(WBMemoryModules.LIKED_PLAYER.get(), player.getUUID()); + return InteractionResult.SUCCESS; + } else if (!allayStack.isEmpty() && hand == InteractionHand.MAIN_HAND && playerStack.isEmpty()) { + this.setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY); + this.level.playSound(player, this, WBSoundEvents.ALLAY_ITEM_TAKEN, SoundSource.NEUTRAL, 2.0F, 1.0F); + this.swing(InteractionHand.MAIN_HAND); + + for (ItemStack stack : this.getInventory().removeAllItems()) BehaviorUtils.throwItem(this, stack, this.position()); + + this.getBrain().eraseMemory(WBMemoryModules.LIKED_PLAYER.get()); + player.addItem(allayStack); + return InteractionResult.SUCCESS; + } else { + return super.mobInteract(player, hand); + } + } + + @Override + public SimpleContainer getInventory() { + return this.inventory; + } + + public static Vec3i getPickupReach() { + return PICKUP_REACH; + } + + @Override + public boolean wantsToPickUp(ItemStack stack) { + ItemStack allayStack = this.getItemInHand(InteractionHand.MAIN_HAND); + return !allayStack.isEmpty() && allayStack.sameItemStackIgnoreDurability(stack) && this.inventory.canAddItem(stack); + } + + @Override + protected void pickUpItem(ItemEntity itemEntity) { + ItemStack stack = itemEntity.getItem(); + if (this.wantsToPickUp(stack)) { + SimpleContainer inventory = this.getInventory(); + boolean canAdd = inventory.canAddItem(stack); + if (!canAdd) return; + + this.onItemPickup(itemEntity); + this.take(itemEntity, stack.getCount()); + ItemStack addedStack = inventory.addItem(stack); + if (addedStack.isEmpty()) { + itemEntity.discard(); + } else { + stack.setCount(addedStack.getCount()); + } + } + } + + @Override + protected void sendDebugPackets() { + super.sendDebugPackets(); + DebugPackets.sendEntityBrain(this); + } + + @Override + protected boolean isFlapping() { + return !this.isOnGround(); + } + + @Override @Nullable + public GameEventListenerRegistrar getGameEventListenerRegistrar() { + return this.registrar; + } + + public boolean isFlying() { + return this.animationSpeed > 0.3F; + } + + public float getHoldingItemAnimationProgress(float animationProgress) { + return Mth.lerp(animationProgress, this.holdingTicksOld, this.holdingTicks) / 5.0F; + } + + @Override + protected void dropEquipment() { + super.dropEquipment(); + this.inventory.removeAllItems().forEach(this::spawnAtLocation); + ItemStack stack = this.getItemBySlot(EquipmentSlot.MAINHAND); + if (!stack.isEmpty() && !EnchantmentHelper.hasVanishingCurse(stack)) { + this.spawnAtLocation(stack); + this.setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY); + } + } + + @Override + public boolean removeWhenFarAway(double distance) { + return false; + } + + @Override + public boolean shouldListen(ServerLevel level, GameEventListener listener, BlockPos pos, GameEvent event, @Nullable Entity entity) { + if (this.level == level && !this.isRemoved() && !this.isNoAi()) { + if (!this.brain.hasMemoryValue(WBMemoryModules.LIKED_NOTEBLOCK.get())) { + return true; + } else { + Optional likedNoteblock = this.brain.getMemory(WBMemoryModules.LIKED_NOTEBLOCK.get()); + return likedNoteblock.isPresent() && likedNoteblock.get().dimension() == level.dimension() && likedNoteblock.get().pos() == pos; + } + } else { + return false; + } + } + + @Override + public void onSignalReceive(ServerLevel level, GameEventListener listener, BlockPos pos, GameEvent event, @Nullable Entity entity, @Nullable Entity source, float distance) { + if (event == WBGameEvents.NOTE_BLOCK_PLAY.get()) AllayBrain.hearNoteblock(this, new BlockPos(pos)); + } + + @Override + public TagKey getListenableEvents() { + return WBGameEventTags.ALLAY_CAN_LISTEN; + } + + @Override + public void addAdditionalSaveData(CompoundTag tag) { + super.addAdditionalSaveData(tag); + tag.put("Inventory", this.inventory.createTag()); + VibrationListenerSource.codec(this).encodeStart(NbtOps.INSTANCE, this.listener).resultOrPartial(WildBackport.LOGGER::error).ifPresent(listener -> tag.put("listener", listener)); + } + + @Override + public void readAdditionalSaveData(CompoundTag tag) { + super.readAdditionalSaveData(tag); + this.inventory.fromTag(tag.getList("Inventory", 10)); + if (tag.contains("listener", 10)) VibrationListenerSource.codec(this).parse(new Dynamic<>(NbtOps.INSTANCE, tag.getCompound("listener"))).resultOrPartial(WildBackport.LOGGER::error).ifPresent(listener -> this.listener = listener); + } + + //iterate pathfinding start node candidate positions + + @Override + public Vec3 getLeashOffset() { + return new Vec3(0.0D, this.getEyeHeight() * 0.6D, this.getBbWidth() * 0.1D); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/ChestBoat.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/ChestBoat.java new file mode 100644 index 0000000..eb2b0e3 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/ChestBoat.java @@ -0,0 +1,240 @@ +package com.cursedcauldron.wildbackport.common.entities; + +import com.cursedcauldron.wildbackport.common.registry.WBItems; +import com.cursedcauldron.wildbackport.common.registry.entity.WBEntities; +import net.minecraft.advancements.CriteriaTriggers; +import net.minecraft.core.NonNullList; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.Container; +import net.minecraft.world.ContainerHelper; +import net.minecraft.world.Containers; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.MenuProvider; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.SlotAccess; +import net.minecraft.world.entity.monster.piglin.PiglinAi; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.vehicle.Boat; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.ChestMenu; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.GameRules; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.gameevent.GameEvent; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.LootTable; +import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; +import net.minecraft.world.level.storage.loot.parameters.LootContextParams; +import org.jetbrains.annotations.Nullable; + +//<> + +public class ChestBoat extends MangroveBoat implements Container, MenuProvider { + private NonNullList stacks = NonNullList.withSize(27, ItemStack.EMPTY); + @Nullable + private ResourceLocation lootTable; + private long lootTableSeed; + + public ChestBoat(EntityType type, Level level) { + super(type, level); + } + + public ChestBoat(Level level, double x, double y, double z) { + super(WBEntities.CHEST_BOAT.get(), level); + this.setPos(x, y, z); + this.xo = x; + this.yo = y; + this.zo = z; + } + + @Override + public double getPassengersRidingOffset() { + return 0.15F; + } + + @Override + protected boolean canAddPassenger(Entity entity) { + return this.getPassengers().size() < 1; + } + + @Override + protected void addAdditionalSaveData(CompoundTag tag) { + super.addAdditionalSaveData(tag); + if (this.lootTable != null) { + tag.putString("LootTable", this.lootTable.toString()); + if (this.lootTableSeed != 0L) tag.putLong("LootTableSeed", this.lootTableSeed); + } else { + ContainerHelper.saveAllItems(tag, this.stacks); + } + } + + @Override + protected void readAdditionalSaveData(CompoundTag tag) { + super.readAdditionalSaveData(tag); + this.stacks = NonNullList.withSize(this.getContainerSize(), ItemStack.EMPTY); + if (tag.contains("LootTable", 8)) { + this.lootTable = new ResourceLocation(tag.getString("LootTable")); + this.lootTableSeed = tag.getLong("LootTableSeed"); + } else { + ContainerHelper.loadAllItems(tag, this.stacks); + } + } + + @Override + protected void dropItems(DamageSource source) { + super.dropItems(source); + if (this.level.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) { + Containers.dropContents(this.level, this, this); + if (!this.level.isClientSide) { + Entity entity = source.getDirectEntity(); + if (entity != null && entity.getType() == EntityType.PLAYER) PiglinAi.angerNearbyPiglins((Player)entity, true); + } + } + } + + @Override + public void remove(Entity.RemovalReason reason) { + if (!this.level.isClientSide && reason.shouldDestroy()) Containers.dropContents(this.level, this, this); + super.remove(reason); + } + + @Override + public InteractionResult interact(Player player, InteractionHand hand) { + if (player.isCrouching()) { + player.openMenu(this); + if (!player.level.isClientSide) { + this.gameEvent(GameEvent.CONTAINER_OPEN, player); + PiglinAi.angerNearbyPiglins(player, true); + return InteractionResult.CONSUME; + } else { + return InteractionResult.SUCCESS; + } + } + + return super.interact(player, hand); + } + + public void openInventory(Player player) { + player.openMenu(this); + if (!player.level.isClientSide()) { + this.gameEvent(GameEvent.CONTAINER_OPEN, player); + PiglinAi.angerNearbyPiglins(player, true); + } + } + + @Override @SuppressWarnings("UnnecessaryDefault") + public Item getDropItem() { + return switch (this.getBoatType()) { + case OAK -> WBItems.OAK_CHEST_BOAT.get(); + case SPRUCE -> WBItems.SPRUCE_CHEST_BOAT.get(); + case BIRCH -> WBItems.BIRCH_CHEST_BOAT.get(); + case JUNGLE -> WBItems.JUNGLE_CHEST_BOAT.get(); + case ACACIA -> WBItems.ACACIA_CHEST_BOAT.get(); + case DARK_OAK -> WBItems.DARK_OAK_CHEST_BOAT.get(); + default -> WBItems.MANGROVE_CHEST_BOAT.get(); + }; + } + + public void unpackLootTable(@Nullable Player player) { + MinecraftServer server = this.level.getServer(); + if (this.lootTable != null && server != null) { + LootTable lootTable = server.getLootTables().get(this.lootTable); + if (player != null) CriteriaTriggers.GENERATE_LOOT.trigger((ServerPlayer)player, this.lootTable); + + this.lootTable = null; + LootContext.Builder builder = new LootContext.Builder((ServerLevel)this.level).withParameter(LootContextParams.ORIGIN, this.position()).withOptionalRandomSeed(this.lootTableSeed); + if (player != null) builder.withLuck(player.getLuck()).withParameter(LootContextParams.THIS_ENTITY, player); + + lootTable.fill(this, builder.create(LootContextParamSets.CHEST)); + } + } + + @Override + public void clearContent() { + this.unpackLootTable(null); + this.stacks.clear(); + } + + @Override + public int getContainerSize() { + return 27; + } + + @Override + public ItemStack getItem(int slot) { + this.unpackLootTable(null); + return this.stacks.get(slot); + } + + @Override + public ItemStack removeItem(int slot, int amount) { + this.unpackLootTable(null); + return ContainerHelper.removeItem(this.stacks, slot, amount); + } + + @Override + public ItemStack removeItemNoUpdate(int slot) { + this.unpackLootTable(null); + ItemStack stack = this.stacks.get(slot); + if (stack.isEmpty()) { + return ItemStack.EMPTY; + } else { + this.stacks.set(slot, ItemStack.EMPTY); + return stack; + } + } + + @Override + public void setItem(int slot, ItemStack stack) { + this.unpackLootTable(null); + this.stacks.set(slot, stack); + if (!stack.isEmpty() && stack.getCount() > this.getMaxStackSize()) stack.setCount(this.getMaxStackSize()); + } + + @Override + public SlotAccess getSlot(int slot) { + return slot >= 0 && slot < this.getContainerSize() ? new SlotAccess() { + @Override public ItemStack get() { + return ChestBoat.this.getItem(slot); + } + + @Override public boolean set(ItemStack stack) { + ChestBoat.this.setItem(slot, stack); + return true; + } + } : super.getSlot(slot); + } + + @Override + public void setChanged() {} + + @Override + public boolean stillValid(Player player) { + return !this.isRemoved() && this.position().closerThan(player.position(), 8.0D); + } + + @Override + public boolean isEmpty() { + for (ItemStack stack : this.stacks) if (!stack.isEmpty()) return false; + return true; + } + + @Override @Nullable + public AbstractContainerMenu createMenu(int i, Inventory inventory, Player player) { + if (this.lootTable == null || !player.isSpectator()) { + this.unpackLootTable(inventory.player); + return ChestMenu.threeRows(i, inventory, this); + } + + return null; + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/Frog.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/Frog.java new file mode 100644 index 0000000..60f971a --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/Frog.java @@ -0,0 +1,439 @@ +package com.cursedcauldron.wildbackport.common.entities; + +import com.cursedcauldron.wildbackport.client.animation.api.AnimationState; +import com.cursedcauldron.wildbackport.client.registry.WBSoundEvents; +import com.cursedcauldron.wildbackport.common.entities.brain.FrogBrain; +import com.cursedcauldron.wildbackport.common.entities.access.api.Poses; +import com.cursedcauldron.wildbackport.common.registry.entity.WBEntities; +import com.cursedcauldron.wildbackport.common.registry.entity.WBMemoryModules; +import com.cursedcauldron.wildbackport.common.registry.entity.WBSensorTypes; +import com.cursedcauldron.wildbackport.common.tag.WBBiomeTags; +import com.cursedcauldron.wildbackport.common.tag.WBBlockTags; +import com.cursedcauldron.wildbackport.common.tag.WBEntityTypeTags; +import com.google.common.collect.ImmutableList; +import com.mojang.serialization.Dynamic; +import net.minecraft.advancements.CriteriaTriggers; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Holder; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.protocol.game.DebugPackets; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.network.syncher.EntityDataSerializers; +import net.minecraft.network.syncher.SynchedEntityData; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.stats.Stats; +import net.minecraft.util.Unit; +import net.minecraft.world.DifficultyInstance; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.AgeableMob; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.ExperienceOrb; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.MobSpawnType; +import net.minecraft.world.entity.MoverType; +import net.minecraft.world.entity.Pose; +import net.minecraft.world.entity.SpawnGroupData; +import net.minecraft.world.entity.ai.Brain; +import net.minecraft.world.entity.ai.attributes.AttributeSupplier; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.ai.control.LookControl; +import net.minecraft.world.entity.ai.control.SmoothSwimmingMoveControl; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; +import net.minecraft.world.entity.ai.navigation.PathNavigation; +import net.minecraft.world.entity.ai.navigation.WaterBoundPathNavigation; +import net.minecraft.world.entity.ai.sensing.Sensor; +import net.minecraft.world.entity.ai.sensing.SensorType; +import net.minecraft.world.entity.animal.Animal; +import net.minecraft.world.entity.monster.Slime; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.GameRules; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.ServerLevelAccessor; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.pathfinder.AmphibiousNodeEvaluator; +import net.minecraft.world.level.pathfinder.BlockPathTypes; +import net.minecraft.world.level.pathfinder.PathFinder; +import net.minecraft.world.phys.Vec3; +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; +import java.util.Comparator; +import java.util.Objects; +import java.util.Optional; +import java.util.OptionalInt; +import java.util.Random; + +//<> + +public class Frog extends Animal { + public static final Ingredient FOOD = Ingredient.of(Items.SLIME_BALL); + protected static final ImmutableList>> SENSORS = ImmutableList.of(SensorType.NEAREST_LIVING_ENTITIES, SensorType.HURT_BY, WBSensorTypes.FROG_ATTACKABLES.get(), WBSensorTypes.FROG_TEMPTATIONS.get(), WBSensorTypes.IS_IN_WATER.get()); + protected static final ImmutableList> MEMORIES = ImmutableList.of(MemoryModuleType.LOOK_TARGET, MemoryModuleType.NEAREST_LIVING_ENTITIES, MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, MemoryModuleType.WALK_TARGET, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryModuleType.PATH, MemoryModuleType.BREED_TARGET, MemoryModuleType.LONG_JUMP_COOLDOWN_TICKS, MemoryModuleType.LONG_JUMP_MID_JUMP, MemoryModuleType.ATTACK_TARGET, MemoryModuleType.TEMPTING_PLAYER, MemoryModuleType.TEMPTATION_COOLDOWN_TICKS, MemoryModuleType.IS_TEMPTED, MemoryModuleType.HURT_BY, MemoryModuleType.HURT_BY_ENTITY, MemoryModuleType.NEAREST_ATTACKABLE, WBMemoryModules.IS_IN_WATER.get(), WBMemoryModules.IS_PREGNANT.get(), WBMemoryModules.UNREACHABLE_TONGUE_TARGETS.get()); + private static final EntityDataAccessor VARIANT_ID = SynchedEntityData.defineId(Frog.class, EntityDataSerializers.INT); + private static final EntityDataAccessor TARGET_ID = SynchedEntityData.defineId(Frog.class, EntityDataSerializers.OPTIONAL_UNSIGNED_INT); + public final AnimationState longJumpingAnimationState = new AnimationState(); + public final AnimationState croakingAnimationState = new AnimationState(); + public final AnimationState usingTongueAnimationState = new AnimationState(); + public final AnimationState walkingAnimationState = new AnimationState(); + public final AnimationState swimmingAnimationState = new AnimationState(); + public final AnimationState idlingInWaterAnimationState = new AnimationState(); + + public Frog(EntityType type, Level level) { + super(type, level); + this.lookControl = new FrogLookController(this); + this.setPathfindingMalus(BlockPathTypes.WATER, 4.0F); + this.setPathfindingMalus(BlockPathTypes.TRAPDOOR, -1.0F); + this.moveControl = new SmoothSwimmingMoveControl(this, 85, 10, 0.02F, 0.1F, true); + this.maxUpStep = 1.0F; + } + + @Override + protected Brain.Provider brainProvider() { + return Brain.provider(MEMORIES, SENSORS); + } + + @Override + protected Brain makeBrain(Dynamic dynamic) { + return FrogBrain.create(this.brainProvider().makeBrain(dynamic)); + } + + @Override @SuppressWarnings("unchecked") + public Brain getBrain() { + return (Brain)super.getBrain(); + } + + @Override + protected void defineSynchedData() { + super.defineSynchedData(); + this.entityData.define(VARIANT_ID, 0); + this.entityData.define(TARGET_ID, OptionalInt.empty()); + } + + public void clearFrogTarget() { + this.entityData.set(TARGET_ID, OptionalInt.empty()); + } + + public Optional getFrogTarget() { + return this.entityData.get(TARGET_ID).stream().mapToObj(this.level::getEntity).filter(Objects::nonNull).findFirst(); + } + + public void setFrogTarget(Entity entity) { + this.entityData.set(TARGET_ID, OptionalInt.of(entity.getId())); + } + + @Override + public int getHeadRotSpeed() { + return 35; + } + + @Override + public int getMaxHeadYRot() { + return 5; + } + + public Variant getVariant() { + return Variant.byId(this.entityData.get(VARIANT_ID)); + } + + public void setVariant(Variant variant) { + this.entityData.set(VARIANT_ID, variant.getId()); + } + + @Override + public void addAdditionalSaveData(CompoundTag tag) { + super.addAdditionalSaveData(tag); + tag.putInt("Variant", this.getVariant().getId()); + } + + @Override + public void readAdditionalSaveData(CompoundTag tag) { + super.readAdditionalSaveData(tag); + this.setVariant(Variant.byId(tag.getInt("Variant"))); + } + + @Override + public boolean canBreatheUnderwater() { + return true; + } + + private boolean isMovingOnLand() { + return this.onGround && this.getDeltaMovement().horizontalDistanceSqr() > 1.0E-6D && !this.isInWaterOrBubble(); + } + + private boolean isMovingOnWater() { + return this.getDeltaMovement().horizontalDistanceSqr() > 1.0E-6D && this.isInWaterOrBubble(); + } + + @Override + protected void customServerAiStep() { + this.level.getProfiler().push("frogBrain"); + this.getBrain().tick((ServerLevel)this.level, this); + this.level.getProfiler().pop(); + this.level.getProfiler().push("frogActivityUpdate"); + FrogBrain.updateActivities(this); + this.level.getProfiler().pop(); + super.customServerAiStep(); + } + + @Override + public void tick() { + if (this.level.isClientSide()) { + if (this.isMovingOnLand()) { + this.walkingAnimationState.startIfNotRunning(this.tickCount); + } else { + this.walkingAnimationState.stop(); + } + + if (this.isMovingOnWater()) { + this.idlingInWaterAnimationState.stop(); + this.swimmingAnimationState.startIfNotRunning(this.tickCount); + } else if (this.isInWaterOrBubble()) { + this.swimmingAnimationState.stop(); + this.idlingInWaterAnimationState.startIfNotRunning(this.tickCount); + } else { + this.swimmingAnimationState.stop(); + this.idlingInWaterAnimationState.stop(); + } + } + + super.tick(); + } + + @Override + public void onSyncedDataUpdated(EntityDataAccessor data) { + if (DATA_POSE.equals(data)) { + if (this.isInPose(Pose.LONG_JUMPING)) { + this.longJumpingAnimationState.start(this.tickCount); + } else { + this.longJumpingAnimationState.stop(); + } + + if (this.isInPose(Poses.CROAKING.get())) { + this.croakingAnimationState.start(this.tickCount); + } else { + this.croakingAnimationState.stop(); + } + + if (this.isInPose(Poses.USING_TONGUE.get())) { + this.usingTongueAnimationState.start(this.tickCount); + } else { + this.usingTongueAnimationState.stop(); + } + } + + super.onSyncedDataUpdated(data); + } + + public boolean isInPose(Pose pose) { + return this.getPose() == pose; + } + + @Nullable @Override + public AgeableMob getBreedOffspring(ServerLevel level, AgeableMob mob) { + Frog frog = WBEntities.FROG.get().create(level); + if (frog != null) FrogBrain.coolDownLongJump(frog, level.getRandom()); + return frog; + } + + @Override + public boolean isBaby() { + return false; + } + + @Override + public void setBaby(boolean baby) {} + + @Override + public void spawnChildFromBreeding(ServerLevel level, Animal partner) { + ServerPlayer player = this.getLoveCause(); + if (player == null) player = partner.getLoveCause(); + + if (player != null) { + player.awardStat(Stats.ANIMALS_BRED); + CriteriaTriggers.BRED_ANIMALS.trigger(player, this, partner, null); + } + + this.setAge(6000); + partner.setAge(6000); + this.resetLove(); + partner.resetLove(); + this.getBrain().setMemory(WBMemoryModules.IS_PREGNANT.get(), Unit.INSTANCE); + level.broadcastEntityEvent(this, (byte)18); + if (level.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) level.addFreshEntity(new ExperienceOrb(level, this.getX(), this.getY(), this.getZ(), this.getRandom().nextInt(7) + 1)); + } + + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor accessor, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData groupData, @Nullable CompoundTag tag) { + Holder biome = accessor.getBiome(this.blockPosition()); + if (biome.is(WBBiomeTags.SPAWNS_COLD_VARIANT_FROGS)) { + this.setVariant(Variant.COLD); + } else if (biome.is(WBBiomeTags.SPAWNS_WARM_VARIANT_FROGS)) { + this.setVariant(Variant.WARM); + } else { + this.setVariant(Variant.TEMPERATE); + } + + FrogBrain.coolDownLongJump(this, accessor.getRandom()); + return super.finalizeSpawn(accessor, difficulty, spawnType, groupData, tag); + } + + public static AttributeSupplier.Builder createAttributes() { + return Mob.createMobAttributes().add(Attributes.MOVEMENT_SPEED, 1.0D).add(Attributes.MAX_HEALTH, 10.0D).add(Attributes.ATTACK_DAMAGE, 10.0D); + } + + @Nullable @Override + protected SoundEvent getAmbientSound() { + return WBSoundEvents.FROG_AMBIENT; + } + + @Nullable @Override + protected SoundEvent getHurtSound(DamageSource source) { + return WBSoundEvents.FROG_HURT; + } + + @Nullable @Override + protected SoundEvent getDeathSound() { + return WBSoundEvents.FROG_DEATH; + } + + @Override + protected void playStepSound(BlockPos pos, BlockState state) { + this.playSound(WBSoundEvents.FROG_STEP, 0.15F, 1.0F); + } + + @Override + public boolean isPushedByFluid() { + return false; + } + + @Override + protected void sendDebugPackets() { + super.sendDebugPackets(); + DebugPackets.sendEntityBrain(this); + } + + @Override + protected int calculateFallDamage(float fallDistance, float damageMultiplier) { + return super.calculateFallDamage(fallDistance, damageMultiplier) - 5; + } + + @Override + public void travel(Vec3 motion) { + if (this.isEffectiveAi() && this.isInWater()) { + this.moveRelative(this.getSpeed(), motion); + this.move(MoverType.SELF, this.getDeltaMovement()); + this.setDeltaMovement(this.getDeltaMovement().scale(0.9D)); + } else { + super.travel(motion); + } + } + + @Override + public boolean canCutCorner(BlockPathTypes path) { + return super.canCutCorner(path) && path != BlockPathTypes.WATER_BORDER; + } + + public static boolean isValidFrogFood(LivingEntity entity) { + return (!(entity instanceof Slime slime) || slime.getSize() == 1) && entity.getType().is(WBEntityTypeTags.FROG_FOOD); + } + + @Override + protected PathNavigation createNavigation(Level level) { + return new FrogPathNavigator(this, level); + } + + @Override + public boolean isFood(ItemStack stack) { + return FOOD.test(stack); + } + + public static boolean checkFrogSpawnRules(EntityType type, LevelAccessor accessor, MobSpawnType spawnType, BlockPos pos, Random random) { + return accessor.getBlockState(pos.below()).is(WBBlockTags.FROGS_SPAWNABLE_ON) && isBrightEnoughToSpawn(accessor, pos); + } + + class FrogLookController extends LookControl { + FrogLookController(Mob mobEntity) { + super(mobEntity); + } + @Override + protected boolean resetXRotOnTick() { + return Frog.this.getFrogTarget().isEmpty(); + } + } + + static class FrogNodeEvaluator extends AmphibiousNodeEvaluator { + private final BlockPos.MutableBlockPos preferredBlock = new BlockPos.MutableBlockPos(); + + public FrogNodeEvaluator(boolean penalizeDeepWater) { + super(penalizeDeepWater); + } + + @Override + public BlockPathTypes getBlockPathType(BlockGetter getter, int x, int y, int z) { + this.preferredBlock.set(x, y - 1, z); + BlockState state = getter.getBlockState(this.preferredBlock); + return state.is(WBBlockTags.FROG_PREFER_JUMP_TO) ? BlockPathTypes.OPEN : FrogNodeEvaluator.getBlockPathTypeStatic(getter, this.preferredBlock.move(Direction.UP)); + } + } + + static class FrogPathNavigator extends WaterBoundPathNavigation { + FrogPathNavigator(Frog frog, Level world) { + super(frog, world); + } + @Override + protected PathFinder createPathFinder(int range) { + this.nodeEvaluator = new FrogNodeEvaluator(true); + return new PathFinder(this.nodeEvaluator, range); + } + + @Override + protected boolean canUpdatePath() { + return true; + } + + @Override + public boolean isStableDestination(BlockPos pos) { + return !this.level.getBlockState(pos.below()).isAir(); + } + } + + public enum Variant { + TEMPERATE(0, "temperate"), + WARM(1, "warm"), + COLD(2, "cold"); + private static final Variant[] VARIANTS = Arrays.stream(Variant.values()).sorted(Comparator.comparingInt(Variant::getId)).toArray(Variant[]::new); + private final int id; + private final String name; + + Variant(int id, String name) { + this.id = id; + this.name = name; + } + + public int getId() { + return this.id; + } + + public String getName() { + return this.name; + } + + public static Variant byId(int id) { + if (id < 0 || id >= VARIANTS.length) { + id = 0; + } + + return VARIANTS[id]; + } + } +} diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/MangroveBoat.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/MangroveBoat.java new file mode 100644 index 0000000..05531a9 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/MangroveBoat.java @@ -0,0 +1,61 @@ +package com.cursedcauldron.wildbackport.common.entities; + +import com.cursedcauldron.wildbackport.common.entities.access.api.BoatTypes; +import com.cursedcauldron.wildbackport.common.registry.WBItems; +import com.cursedcauldron.wildbackport.common.registry.entity.WBEntities; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.vehicle.Boat; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.GameRules; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.gameevent.GameEvent; + +//<> + +public class MangroveBoat extends Boat { + public MangroveBoat(EntityType type, Level level) { + super(type, level); + } + + public MangroveBoat(Level level, double x, double y, double z) { + super(WBEntities.MANGROVE_BOAT.get(), level); + this.setPos(x, y, z); + this.xo = x; + this.yo = y; + this.zo = z; + } + + @Override + public boolean hurt(DamageSource source, float amount) { + if (this.isInvulnerableTo(source)) { + return false; + } else if (!this.level.isClientSide() && !this.isRemoved()) { + this.setHurtDir(-this.getHurtDir()); + this.setHurtTime(10); + this.setDamage(this.getDamage() + amount * 10.0F); + this.markHurt(); + this.gameEvent(GameEvent.ENTITY_DAMAGED, source.getEntity()); + boolean isCreativePlayer = source.getEntity() instanceof Player player && player.getAbilities().instabuild; + if (isCreativePlayer || this.getDamage() > 40.0F) { + if (!isCreativePlayer && this.level.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) this.dropItems(source); + + this.discard(); + } + + return true; + } else { + return true; + } + } + + protected void dropItems(DamageSource source) { + this.spawnAtLocation(this.getDropItem()); + } + + @Override + public Item getDropItem() { + return this.getBoatType() != BoatTypes.MANGROVE.get() ? super.getDropItem() : WBItems.MANGROVE_BOAT.get(); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/Tadpole.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/Tadpole.java new file mode 100644 index 0000000..3c75eb9 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/Tadpole.java @@ -0,0 +1,237 @@ +package com.cursedcauldron.wildbackport.common.entities; + +import com.cursedcauldron.wildbackport.client.registry.WBSoundEvents; +import com.cursedcauldron.wildbackport.common.entities.brain.TadpoleBrain; +import com.cursedcauldron.wildbackport.common.registry.WBItems; +import com.cursedcauldron.wildbackport.common.registry.entity.WBEntities; +import com.google.common.collect.ImmutableList; +import com.mojang.serialization.Dynamic; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.protocol.game.DebugPackets; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.MobSpawnType; +import net.minecraft.world.entity.ai.Brain; +import net.minecraft.world.entity.ai.attributes.AttributeSupplier; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.ai.control.SmoothSwimmingLookControl; +import net.minecraft.world.entity.ai.control.SmoothSwimmingMoveControl; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; +import net.minecraft.world.entity.ai.navigation.PathNavigation; +import net.minecraft.world.entity.ai.navigation.WaterBoundPathNavigation; +import net.minecraft.world.entity.ai.sensing.Sensor; +import net.minecraft.world.entity.ai.sensing.SensorType; +import net.minecraft.world.entity.animal.AbstractFish; +import net.minecraft.world.entity.animal.Bucketable; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import org.jetbrains.annotations.Nullable; + +//<> + +public class Tadpole extends AbstractFish { + public static final int MAX_TADPOLE_AGE = Math.abs(-24000); + public static final float WIDTH = 0.4F; + public static final float HEIGHT = 0.3F; + private int age; + protected static final ImmutableList>> SENSORS = ImmutableList.of(SensorType.NEAREST_LIVING_ENTITIES, SensorType.NEAREST_PLAYERS, SensorType.HURT_BY); + protected static final ImmutableList> MEMORIES = ImmutableList.of(MemoryModuleType.LOOK_TARGET, MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, MemoryModuleType.WALK_TARGET, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryModuleType.PATH, MemoryModuleType.NEAREST_VISIBLE_ADULT); + + public Tadpole(EntityType type, Level level) { + super(type, level); + this.moveControl = new SmoothSwimmingMoveControl(this, 85, 10, 0.02F, 0.1F, true); + this.lookControl = new SmoothSwimmingLookControl(this, 10); + } + + @Override + protected PathNavigation createNavigation(Level world) { + return new WaterBoundPathNavigation(this, world); + } + + @Override + protected Brain.Provider brainProvider() { + return Brain.provider(MEMORIES, SENSORS); + } + + @Override + protected Brain makeBrain(Dynamic dynamic) { + return TadpoleBrain.create(this.brainProvider().makeBrain(dynamic)); + } + + @Override @SuppressWarnings("unchecked") + public Brain getBrain() { + return (Brain) super.getBrain(); + } + + @Override + protected SoundEvent getFlopSound() { + return WBSoundEvents.TADPOLE_FLOP; + } + + @Override + protected void customServerAiStep() { + this.level.getProfiler().push("tadpoleBrain"); + this.getBrain().tick((ServerLevel)this.level, this); + this.level.getProfiler().pop(); + this.level.getProfiler().push("tadpoleActivityUpdate"); + TadpoleBrain.updateActivities(this); + this.level.getProfiler().pop(); + super.customServerAiStep(); + } + + public static AttributeSupplier.Builder createAttributes() { + return Mob.createMobAttributes().add(Attributes.MOVEMENT_SPEED, 1.0D).add(Attributes.MAX_HEALTH, 6.0D); + } + + @Override + public void aiStep() { + super.aiStep(); + if (!this.level.isClientSide()) { + this.setAge(this.age + 1); + } + } + + @Override + public void addAdditionalSaveData(CompoundTag nbt) { + super.addAdditionalSaveData(nbt); + nbt.putInt("Age", this.age); + } + + @Override + public void readAdditionalSaveData(CompoundTag nbt) { + super.readAdditionalSaveData(nbt); + this.setAge(nbt.getInt("Age")); + } + + @Override @Nullable + protected SoundEvent getAmbientSound() { + return null; + } + + @Override @Nullable + protected SoundEvent getHurtSound(DamageSource source) { + return WBSoundEvents.TADPOLE_HURT; + } + + @Override @Nullable + protected SoundEvent getDeathSound() { + return WBSoundEvents.TADPOLE_DEATH; + } + + @Override + protected InteractionResult mobInteract(Player player, InteractionHand hand) { + ItemStack stack = player.getItemInHand(hand); + if (this.isSlimeBall(stack)) { + this.eatSlimeBall(player, stack); + return InteractionResult.sidedSuccess(this.level.isClientSide()); + } else { + return Bucketable.bucketMobPickup(player, hand, this).orElse(super.mobInteract(player, hand)); + } + } + + @Override + protected void sendDebugPackets() { + super.sendDebugPackets(); + DebugPackets.sendEntityBrain(this); + } + + @Override + public boolean fromBucket() { + return true; + } + + @Override + public void setFromBucket(boolean fromBucket) {} + + @Override + public void saveToBucketTag(ItemStack stack) { + Bucketable.saveDefaultDataToBucketTag(this, stack); + CompoundTag nbtCompound = stack.getOrCreateTag(); + nbtCompound.putInt("Age", this.getAge()); + } + + @Override + public void loadFromBucketTag(CompoundTag nbt) { + Bucketable.loadDefaultDataFromBucketTag(this, nbt); + if (nbt.contains("Age")) { + this.setAge(nbt.getInt("Age")); + } + } + + @Override + public ItemStack getBucketItemStack() { + return new ItemStack(WBItems.TADPOLE_BUCKET.get()); + } + + @Override + public SoundEvent getPickupSound() { + return WBSoundEvents.BUCKED_FILL_TADPOLE; + } + + private boolean isSlimeBall(ItemStack stack) { + return Frog.FOOD.test(stack); + } + + private void eatSlimeBall(Player player, ItemStack stack) { + this.decrementItem(player, stack); + this.increaseAge((int)((float)(this.getTicksUntilGrowth() / 20) * 0.1F)); + this.level.addParticle(ParticleTypes.HAPPY_VILLAGER, this.getRandomX(1.0D), this.getRandomY() + 0.5D, this.getRandomZ(1.0D), 0.0D, 0.0D, 0.0D); + } + + private void decrementItem(Player player, ItemStack stack) { + if (!player.getAbilities().instabuild) { + stack.shrink(1); + } + } + + private int getAge() { + return this.age; + } + + private void increaseAge(int seconds) { + this.setAge(this.age + seconds * 20); + } + + private void setAge(int age) { + this.age = age; + if (this.age >= MAX_TADPOLE_AGE) { + this.growUp(); + } + } + + private void growUp() { + if (this.level instanceof ServerLevel server) { + Frog frog = WBEntities.FROG.get().create(this.level); + if (frog == null) return; + + frog.moveTo(this.getX(), this.getY(), this.getZ(), this.getYRot(), this.getXRot()); + frog.finalizeSpawn(server, this.level.getCurrentDifficultyAt(frog.blockPosition()), MobSpawnType.CONVERSION, null, null); + frog.setNoAi(this.isNoAi()); + if (this.hasCustomName()) { + frog.setCustomName(this.getCustomName()); + frog.setCustomNameVisible(this.isCustomNameVisible()); + } + + frog.setPersistenceRequired(); + this.playSound(WBSoundEvents.TADPOLE_GROW_UP, 0.15F, 1.0F); + server.addFreshEntityWithPassengers(frog); + this.discard(); + } + } + + private int getTicksUntilGrowth() { + return Math.max(0, MAX_TADPOLE_AGE - this.age); + } + + @Override + protected boolean shouldDropExperience() { + return false; + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/Warden.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/Warden.java new file mode 100644 index 0000000..1978e6f --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/Warden.java @@ -0,0 +1,533 @@ +package com.cursedcauldron.wildbackport.common.entities; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.client.animation.api.AnimationState; +import com.cursedcauldron.wildbackport.client.registry.WBSoundEvents; +import com.cursedcauldron.wildbackport.common.entities.brain.WardenBrain; +import com.cursedcauldron.wildbackport.common.entities.brain.warden.SonicBoom; +import com.cursedcauldron.wildbackport.common.entities.access.api.Poses; +import com.cursedcauldron.wildbackport.common.entities.warden.Angriness; +import com.cursedcauldron.wildbackport.common.entities.warden.MobPositionSource; +import com.cursedcauldron.wildbackport.common.entities.warden.VibrationListenerSource; +import com.cursedcauldron.wildbackport.common.entities.warden.WardenAngerManager; +import com.cursedcauldron.wildbackport.common.registry.entity.WBEntities; +import com.cursedcauldron.wildbackport.common.registry.entity.WBMemoryModules; +import com.cursedcauldron.wildbackport.common.tag.WBGameEventTags; +import com.cursedcauldron.wildbackport.common.utils.MobUtils; +import com.mojang.serialization.Dynamic; +import net.minecraft.core.BlockPos; +import net.minecraft.core.particles.BlockParticleOption; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtOps; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ClientboundAddEntityPacket; +import net.minecraft.network.protocol.game.DebugPackets; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.network.syncher.EntityDataSerializers; +import net.minecraft.network.syncher.SynchedEntityData; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.tags.TagKey; +import net.minecraft.util.Mth; +import net.minecraft.util.Unit; +import net.minecraft.world.DifficultyInstance; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.damagesource.IndirectEntityDamageSource; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.effect.MobEffects; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityDimensions; +import net.minecraft.world.entity.EntitySelector; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.MobSpawnType; +import net.minecraft.world.entity.Pose; +import net.minecraft.world.entity.SpawnGroupData; +import net.minecraft.world.entity.ai.Brain; +import net.minecraft.world.entity.ai.attributes.AttributeSupplier; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; +import net.minecraft.world.entity.monster.Monster; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.ServerLevelAccessor; +import net.minecraft.world.level.block.RenderShape; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.gameevent.GameEvent; +import net.minecraft.world.level.gameevent.GameEventListener; +import net.minecraft.world.level.gameevent.GameEventListenerRegistrar; +import net.minecraft.world.level.pathfinder.BlockPathTypes; +import net.minecraft.world.phys.Vec3; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; +import java.util.Optional; +import java.util.Random; + +//<> + +public class Warden extends Monster implements VibrationListenerSource.VibrationConfig { + private static final EntityDataAccessor ANGER = SynchedEntityData.defineId(Warden.class, EntityDataSerializers.INT); + private int tendrilPitchEnd; + private int tendrilPitchStart; + private int heartPitchEnd; + private int heartPitchStart; + public AnimationState roaringAnimationState = new AnimationState(); + public AnimationState sniffingAnimationState = new AnimationState(); + public AnimationState emergingAnimationState = new AnimationState(); + public AnimationState diggingAnimationState = new AnimationState(); + public AnimationState attackingAnimationState = new AnimationState(); + public AnimationState sonicBoomAnimationState = new AnimationState(); + private final GameEventListenerRegistrar gameEventHandler; + private VibrationListenerSource listener; + private WardenAngerManager angerManager = new WardenAngerManager(this::isValidTarget, Collections.emptyList()); + + public Warden(EntityType type, Level level) { + super(type, level); + this.listener = new VibrationListenerSource(new MobPositionSource(this, this.getEyeHeight()), 16, this, null, 0.0F, 0); + this.gameEventHandler = new GameEventListenerRegistrar(this.listener); + this.xpReward = 5; + this.getNavigation().setCanFloat(true); + this.setPathfindingMalus(BlockPathTypes.UNPASSABLE_RAIL, 0.0F); + this.setPathfindingMalus(BlockPathTypes.DAMAGE_OTHER, 8.0F); + this.setPathfindingMalus(BlockPathTypes.POWDER_SNOW, 8.0F); + this.setPathfindingMalus(BlockPathTypes.LAVA, 8.0F); + this.setPathfindingMalus(BlockPathTypes.DAMAGE_FIRE, 0.0F); + this.setPathfindingMalus(BlockPathTypes.DANGER_FIRE, 0.0F); + } + + @Override + public Packet getAddEntityPacket() { + return new ClientboundAddEntityPacket(this, this.hasPose(Poses.EMERGING.get()) ? 1 : 0); + } + + @Override + public void recreateFromPacket(ClientboundAddEntityPacket packet) { + super.recreateFromPacket(packet); + if (packet.getData() == 1) this.setPose(Poses.EMERGING.get()); + } + + @Override + public boolean checkSpawnObstruction(LevelReader reader) { + return super.checkSpawnObstruction(reader) && reader.noCollision(this, this.getType().getDimensions().makeBoundingBox(this.position())); + } + + @Override + public float getWalkTargetValue(BlockPos pos, LevelReader reader) { + return 0.0F; + } + + @Override + public boolean isInvulnerableTo(DamageSource source) { + return this.isDiggingOrEmerging() && !source.isBypassInvul() || super.isInvulnerableTo(source); + } + + private boolean isDiggingOrEmerging() { + return this.hasPose(Poses.DIGGING.get()) || this.hasPose(Poses.EMERGING.get()); + } + + @Override + protected boolean canRide(Entity entity) { + return false; + } + + @Override + protected float nextStep() { + return this.moveDist + 0.55F; + } + + public static AttributeSupplier.Builder createAttributes() { + return Monster.createMonsterAttributes().add(Attributes.MAX_HEALTH, 500.0D).add(Attributes.MOVEMENT_SPEED, 0.3F).add(Attributes.KNOCKBACK_RESISTANCE, 1.0D).add(Attributes.ATTACK_KNOCKBACK, 1.5D).add(Attributes.ATTACK_DAMAGE, 30.0D); + } + + @Override + public boolean occludesVibrations() { + return true; + } + + @Override + protected float getSoundVolume() { + return 4.0F; + } + + @Nullable @Override + protected SoundEvent getAmbientSound() { + return !this.hasPose(Poses.ROARING.get()) && !this.isDiggingOrEmerging() ? this.getAngriness().getSound() : null; + } + + @Override + protected SoundEvent getHurtSound(DamageSource source) { + return WBSoundEvents.WARDEN_HURT; + } + + @Override + protected SoundEvent getDeathSound() { + return WBSoundEvents.WARDEN_DEATH; + } + + @Override + protected void playStepSound(BlockPos pos, BlockState state) { + this.playSound(WBSoundEvents.WARDEN_STEP, 10.0F, 1.0F); + } + + @Override + public boolean doHurtTarget(Entity entity) { + this.level.broadcastEntityEvent(this, (byte)4); + this.playSound(WBSoundEvents.WARDEN_ATTACK_IMPACT, 10.0F, this.getVoicePitch()); + SonicBoom.setCooldown(this, 40); + return super.doHurtTarget(entity); + } + + @Override + protected void defineSynchedData() { + super.defineSynchedData(); + this.entityData.define(ANGER, 0); + } + + public int getAnger() { + return this.entityData.get(ANGER); + } + + private void updateAnger() { + this.entityData.set(ANGER, this.getPrimeSuspectAnger()); + } + + @Override + public void tick() { + if (this.level instanceof ServerLevel server) { + this.listener.tick(server); + if (this.isPersistenceRequired() || this.requiresCustomPersistence()) { + WardenBrain.setDigCooldown(this); + } + } + + super.tick(); + if (this.level.isClientSide) { + if (this.tickCount % this.getHeartRate() == 0) { + this.heartPitchEnd = 10; + if (!this.isSilent()) { + this.level.playLocalSound(this.getX(), this.getY(), this.getZ(), WBSoundEvents.WARDEN_HEARTBEAT, this.getSoundSource(), 5.0F, this.getVoicePitch(), false); + } + } + + this.tendrilPitchStart = this.tendrilPitchEnd; + if (this.tendrilPitchEnd > 0) { + --this.tendrilPitchEnd; + } + + this.heartPitchStart = this.heartPitchEnd; + if (this.heartPitchEnd > 0) { + --this.heartPitchEnd; + } + + if (this.hasPose(Poses.EMERGING.get())) { + this.addDigParticles(this.emergingAnimationState); + } + + if (this.hasPose(Poses.DIGGING.get())) { + this.addDigParticles(this.diggingAnimationState); + } + } + } + + @Override + protected void customServerAiStep() { + ServerLevel level = (ServerLevel)this.level; + level.getProfiler().push("wardenBrain"); + this.getBrain().tick(level, this); + this.level.getProfiler().pop(); + super.customServerAiStep(); + if ((this.tickCount + this.getId()) % 120 == 0) { + addDarknessEffectToClosePlayers(level, this.position(), this, 20); + } + + if (this.tickCount % 20 == 0) { + this.angerManager.tick(level, this::isValidTarget); + this.updateAnger(); + } + + WardenBrain.updateActivity(this); + } + + @Override + public void handleEntityEvent(byte status) { + if (status == 4) { + this.roaringAnimationState.stop(); + this.attackingAnimationState.start(this.tickCount); + } else if (status == 61) { + this.tendrilPitchEnd = 10; + } else if (status == 62) { + this.sonicBoomAnimationState.start(this.tickCount); + } else { + super.handleEntityEvent(status); + } + } + + private int getHeartRate() { + return 40 - Mth.floor(Mth.clamp((float)this.getAnger() / (float) Angriness.ANGRY.getThreshold(), 0.0F, 1.0F) * 30.0F); + } + + public float getTendrilPitch(float tickDelta) { + return Mth.lerp(tickDelta, (float)this.tendrilPitchStart, (float)this.tendrilPitchEnd) / 10.0F; + } + + public float getHeartPitch(float tickDelta) { + return Mth.lerp(tickDelta, (float)this.heartPitchStart, (float)this.heartPitchEnd) / 10.0F; + } + + private void addDigParticles(AnimationState animationState) { + if ((float)animationState.runningTime() < 4500.0F) { + Random random = this.getRandom(); + BlockState state = this.getBlockStateOn(); + if (state.getRenderShape() != RenderShape.INVISIBLE) { + for (int i = 0; i < 30; i++) { + double x = this.getX() + (double)Mth.randomBetween(random, -0.7F, 0.7F); + double y = this.getY(); + double z = this.getZ() + (double)Mth.randomBetween(random, -0.7F, 0.7F); + this.level.addParticle(new BlockParticleOption(ParticleTypes.BLOCK, state), x, y, z, 0.0D, 0.0D, 0.0D); + } + } + } + } + + @Override + public void onSyncedDataUpdated(EntityDataAccessor data) { + if (DATA_POSE.equals(data)) { + if (this.hasPose(Poses.EMERGING.get())) { + this.emergingAnimationState.start(this.tickCount); + } else if (this.hasPose(Poses.DIGGING.get())) { + this.diggingAnimationState.start(this.tickCount); + } else if (this.hasPose(Poses.ROARING.get())) { + this.roaringAnimationState.start(this.tickCount); + } else if (this.hasPose(Poses.SNIFFING.get())) { + this.sniffingAnimationState.start(this.tickCount); + } + } + + super.onSyncedDataUpdated(data); + } + + public boolean hasPose(Pose pose) { + return this.getPose() == pose; + } + + @Override + public boolean ignoreExplosion() { + return this.isDiggingOrEmerging(); + } + + @Override + protected Brain makeBrain(Dynamic dynamic) { + return WardenBrain.makeBrain(this, dynamic); + } + + @Override @SuppressWarnings("unchecked") + public Brain getBrain() { + return (Brain)super.getBrain(); + } + + @Override + protected void sendDebugPackets() { + super.sendDebugPackets(); + DebugPackets.sendEntityBrain(this); + } + + @Override + public TagKey getListenableEvents() { + return WBGameEventTags.WARDEN_CAN_LISTEN; + } + + @Override + public boolean canTriggerAvoidVibration() { + return true; + } + + public boolean isValidTarget(@Nullable Entity entity) { + if (entity instanceof LivingEntity living) { + return this.level == entity.level && EntitySelector.NO_CREATIVE_OR_SPECTATOR.test(entity) && !this.isAlliedTo(entity) && living.getType() != EntityType.ARMOR_STAND && living.getType() != WBEntities.WARDEN.get() && !living.isInvulnerable() && !living.isDeadOrDying() && this.level.getWorldBorder().isWithinBounds(living.getBoundingBox()); + } + + return false; + } + + public static void addDarknessEffectToClosePlayers(ServerLevel level, Vec3 pos, @Nullable Entity entity, int range) { + MobEffectInstance instance = new MobEffectInstance(MobEffects.BLINDNESS, 260, 0, false, false); + MobUtils.addEffectToPlayersWithinDistance(level, entity, pos, range, instance, 200); + } + + @Override + public void addAdditionalSaveData(CompoundTag tag) { + super.addAdditionalSaveData(tag); + WardenAngerManager.createCodec(this::isValidTarget).encodeStart(NbtOps.INSTANCE, this.angerManager).resultOrPartial(WildBackport.LOGGER::error).ifPresent(manager -> tag.put("anger", manager)); + VibrationListenerSource.codec(this).encodeStart(NbtOps.INSTANCE, this.listener).resultOrPartial(WildBackport.LOGGER::error).ifPresent(listener -> tag.put("listener", listener)); + } + + @Override + public void readAdditionalSaveData(CompoundTag tag) { + super.readAdditionalSaveData(tag); + if (tag.contains("anger")) { + WardenAngerManager.createCodec(this::isValidTarget).parse(new Dynamic<>(NbtOps.INSTANCE, tag.get("anger"))).resultOrPartial(WildBackport.LOGGER::error).ifPresent(manager -> this.angerManager = manager); + this.updateAnger(); + } + + if (tag.contains("listener", 10)) VibrationListenerSource.codec(this).parse(new Dynamic<>(NbtOps.INSTANCE, tag.getCompound("listener"))).resultOrPartial(WildBackport.LOGGER::error).ifPresent(listener -> this.listener = listener); + } + + private void playListeningSound() { + if (!this.hasPose(Poses.ROARING.get())) this.playSound(this.getAngriness().getListeningSound(), 10.0F, this.getVoicePitch()); + } + + public Angriness getAngriness() { + return Angriness.getForAnger(this.getPrimeSuspectAnger()); + } + + public int getPrimeSuspectAnger() { + return this.angerManager.getPrimeSuspectAnger(); + } + + public void removeSuspect(Entity entity) { + this.angerManager.removeSuspect(entity); + } + + public void increaseAngerAt(Entity entity) { + this.increaseAngerAt(entity, 35, true); + } + + public void increaseAngerAt(Entity entity, int amount, boolean listening) { + if (!this.isNoAi() && this.isValidTarget(entity)) { + WardenBrain.setDigCooldown(this); + boolean targetNotPlayer = !(this.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET).orElse(null) instanceof Player); + int anger = this.angerManager.increaseAngerAt(entity, amount); + if (entity instanceof Player && targetNotPlayer && Angriness.getForAnger(anger).isAngry()) { + this.getBrain().eraseMemory(MemoryModuleType.ATTACK_TARGET); + } + + if (listening) this.playListeningSound(); + } + } + + public Optional getEntityAngryAt() { + return this.getAngriness().isAngry() ? this.angerManager.getPrimeSuspect() : Optional.empty(); + } + + @Nullable @Override + public LivingEntity getTarget() { + return this.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET).orElse(null); + } + + @Override + public boolean removeWhenFarAway(double sqrDist) { + return false; + } + + @Nullable @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor accessor, DifficultyInstance difficulty, MobSpawnType spawn, @Nullable SpawnGroupData groupData, @Nullable CompoundTag tag) { + this.getBrain().setMemoryWithExpiry(WBMemoryModules.DIG_COOLDOWN.get(), Unit.INSTANCE, 1200L); + if (spawn == MobSpawnType.TRIGGERED) { + this.setPose(Poses.EMERGING.get()); + this.getBrain().setMemoryWithExpiry(WBMemoryModules.IS_EMERGING.get(), Unit.INSTANCE, WardenBrain.EMERGE_DURATION); + this.playSound(WBSoundEvents.WARDEN_AGITATED, 5.0F, 1.0F); + } + + return super.finalizeSpawn(accessor, difficulty, spawn, groupData, tag); + } + + @Override + public boolean hurt(DamageSource source, float amount) { + boolean hurt = super.hurt(source, amount); + if (!this.level.isClientSide && !this.isNoAi() && !this.isDiggingOrEmerging()) { + Entity entity = source.getEntity(); + this.increaseAngerAt(entity, Angriness.ANGRY.getThreshold() + 20, false); + if (this.brain.getMemory(MemoryModuleType.ATTACK_TARGET).isEmpty() && entity instanceof LivingEntity living) { + if (!(source instanceof IndirectEntityDamageSource) || this.closerThan(living, 5.0D)) { + this.updateAttackTarget(living); + } + } + } + + return hurt; + } + + public void updateAttackTarget(LivingEntity entity) { + this.getBrain().eraseMemory(WBMemoryModules.ROAR_TARGET.get()); + entity.getBrain().setMemory(MemoryModuleType.ATTACK_TARGET, entity); + entity.getBrain().eraseMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE); + SonicBoom.setCooldown(this, 200); + } + + @Override + public EntityDimensions getDimensions(Pose pose) { + EntityDimensions dimensions = super.getDimensions(pose); + return this.isDiggingOrEmerging() ? EntityDimensions.fixed(dimensions.width, 1.0F) : dimensions; + } + + @Override + public boolean isPushable() { + return !this.isDiggingOrEmerging() && super.isPushable(); + } + + @Override + protected void doPush(Entity entity) { + if (!this.isNoAi() && !this.getBrain().hasMemoryValue(WBMemoryModules.TOUCH_COOLDOWN.get())) { + this.getBrain().setMemoryWithExpiry(WBMemoryModules.TOUCH_COOLDOWN.get(), Unit.INSTANCE, 20L); + this.increaseAngerAt(entity); + WardenBrain.setDisturbanceLocation(this, entity.blockPosition()); + } + + super.doPush(entity); + } + + @Override + public boolean shouldListen(ServerLevel level, GameEventListener listener, BlockPos pos, GameEvent event, @Nullable Entity entity) { + if (!this.isNoAi() && !this.isDeadOrDying() && !this.getBrain().hasMemoryValue(WBMemoryModules.VIBRATION_COOLDOWN.get()) && !this.isDiggingOrEmerging() && level.getWorldBorder().isWithinBounds(pos) && !this.isRemoved() && this.level == level) { + if (entity instanceof LivingEntity living) { + return this.isValidTarget(living); + } + + return true; + } else { + return false; + } + } + + @Override + public void onSignalReceive(ServerLevel level, GameEventListener listener, BlockPos pos, GameEvent event, @Nullable Entity entity, @Nullable Entity source, float distance) { + if (!this.isDeadOrDying()) { + this.brain.setMemoryWithExpiry(WBMemoryModules.VIBRATION_COOLDOWN.get(), Unit.INSTANCE, 40L); + level.broadcastEntityEvent(this, (byte)61); + this.playSound(WBSoundEvents.WARDEN_TENDRIL_CLICKS, 5.0F, this.getVoicePitch()); + BlockPos position = pos; + if (source != null) { + if (this.closerThan(source, 30.0D)) { + if (this.getBrain().hasMemoryValue(WBMemoryModules.RECENT_PROJECTILE.get())) { + if (this.isValidTarget(source)) { + position = source.blockPosition(); + } + + this.increaseAngerAt(source); + } else { + this.increaseAngerAt(source, 10, true); + } + } + + this.getBrain().setMemoryWithExpiry(WBMemoryModules.RECENT_PROJECTILE.get(), Unit.INSTANCE, 100L); + } else { + this.increaseAngerAt(entity); + } + + if (!this.getAngriness().isAngry()) { + Optional primeSuspect = this.angerManager.getPrimeSuspect(); + if (source != null || primeSuspect.isEmpty() || primeSuspect.get() == entity) { + WardenBrain.setDisturbanceLocation(this, position); + } + } + } + } + + @Nullable @Override + public GameEventListenerRegistrar getGameEventListenerRegistrar() { + return this.gameEventHandler; + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/access/EntityExperience.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/access/EntityExperience.java new file mode 100644 index 0000000..a44b866 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/access/EntityExperience.java @@ -0,0 +1,9 @@ +package com.cursedcauldron.wildbackport.common.entities.access; + +public interface EntityExperience { + void disableExpDrop(); + + boolean isExpDropDisabled(); + + int getExpToDrop(); +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/access/WardenTracker.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/access/WardenTracker.java new file mode 100644 index 0000000..1fca650 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/access/WardenTracker.java @@ -0,0 +1,12 @@ +package com.cursedcauldron.wildbackport.common.entities.access; + +import com.cursedcauldron.wildbackport.common.entities.warden.WardenSpawnTracker; +import net.minecraft.world.entity.player.Player; + +public interface WardenTracker { + WardenSpawnTracker getWardenSpawnTracker(); + + static WardenSpawnTracker getWardenSpawnTracker(Player player) { + return ((WardenTracker)player).getWardenSpawnTracker(); + } +} diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/access/api/BoatTypes.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/access/api/BoatTypes.java new file mode 100644 index 0000000..4f49b43 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/access/api/BoatTypes.java @@ -0,0 +1,32 @@ +package com.cursedcauldron.wildbackport.common.entities.access.api; + +import com.cursedcauldron.wildbackport.common.registry.WBBlocks; +import net.minecraft.world.entity.vehicle.Boat; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; + +//<> + +public enum BoatTypes { + MANGROVE(Blocks.OAK_PLANKS, "mangrove"); + + private final Block planks; + private final String name; + + BoatTypes(Block planks, String name) { + this.planks = planks; + this.name = name; + } + + public Block getPlanks() { + return this.planks; + } + + public String getName() { + return this.name; + } + + public Boat.Type get() { + return Boat.Type.byName(this.getName()); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/access/api/Poses.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/access/api/Poses.java new file mode 100644 index 0000000..89dfa17 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/access/api/Poses.java @@ -0,0 +1,18 @@ +package com.cursedcauldron.wildbackport.common.entities.access.api; + +import net.minecraft.world.entity.Pose; + +//<> + +public enum Poses { + ROARING, + SNIFFING, + EMERGING, + DIGGING, + CROAKING, + USING_TONGUE; + + public Pose get() { + return Pose.valueOf(this.name()); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/AllayBrain.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/AllayBrain.java new file mode 100644 index 0000000..0a95d78 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/AllayBrain.java @@ -0,0 +1,116 @@ +package com.cursedcauldron.wildbackport.common.entities.brain; + +import com.cursedcauldron.wildbackport.common.entities.Allay; +import com.cursedcauldron.wildbackport.common.entities.brain.allay.FlyingRandomStroll; +import com.cursedcauldron.wildbackport.common.entities.brain.allay.GoAndGiveItemsToTarget; +import com.cursedcauldron.wildbackport.common.entities.brain.allay.StayCloseToTarget; +import com.cursedcauldron.wildbackport.common.registry.entity.WBMemoryModules; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.mojang.datafixers.util.Pair; +import net.minecraft.core.BlockPos; +import net.minecraft.core.GlobalPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.util.valueproviders.UniformInt; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.Brain; +import net.minecraft.world.entity.ai.behavior.AnimalPanic; +import net.minecraft.world.entity.ai.behavior.BlockPosTracker; +import net.minecraft.world.entity.ai.behavior.CountDownCooldownTicks; +import net.minecraft.world.entity.ai.behavior.DoNothing; +import net.minecraft.world.entity.ai.behavior.EntityTracker; +import net.minecraft.world.entity.ai.behavior.GoToWantedItem; +import net.minecraft.world.entity.ai.behavior.LookAtTargetSink; +import net.minecraft.world.entity.ai.behavior.MoveToTargetSink; +import net.minecraft.world.entity.ai.behavior.PositionTracker; +import net.minecraft.world.entity.ai.behavior.RunOne; +import net.minecraft.world.entity.ai.behavior.RunSometimes; +import net.minecraft.world.entity.ai.behavior.SetEntityLookTarget; +import net.minecraft.world.entity.ai.behavior.SetWalkTargetFromLookTarget; +import net.minecraft.world.entity.ai.behavior.Swim; +import net.minecraft.world.entity.schedule.Activity; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Blocks; + +import java.util.Optional; +import java.util.UUID; + +//<> + +public class AllayBrain { + public static Brain makeBrain(Brain brain) { + initCoreActivity(brain); + initIdleActivity(brain); + brain.setCoreActivities(ImmutableSet.of(Activity.CORE)); + brain.setDefaultActivity(Activity.IDLE); + brain.useDefaultActivity(); + return brain; + } + + private static void initCoreActivity(Brain brain) { + brain.addActivity(Activity.CORE, 0, ImmutableList.of(new Swim(0.8F), new AnimalPanic(2.5F), new LookAtTargetSink(45, 90), new MoveToTargetSink(), new CountDownCooldownTicks(WBMemoryModules.LIKED_NOTEBLOCK_COOLDOWN_TICKS.get()), new CountDownCooldownTicks(WBMemoryModules.ITEM_PICKUP_COOLDOWN_TICKS.get()))); + } + + private static void initIdleActivity(Brain brain) { + brain.addActivityWithConditions(Activity.IDLE, ImmutableList.of(Pair.of(0, new GoToWantedItem<>(entity -> { + return true; + }, 1.75F, true, 32)), Pair.of(1, new GoAndGiveItemsToTarget<>(AllayBrain::getItemDepositPosition, 2.25F)), Pair.of(2, new StayCloseToTarget<>(AllayBrain::getItemDepositPosition, 4, 16, 2.25F)), Pair.of(3, new RunSometimes<>(new SetEntityLookTarget(entity -> { + return true; + }, 6.0F), UniformInt.of(30, 60))), Pair.of(4, new RunOne<>(ImmutableList.of(Pair.of(new FlyingRandomStroll(1.0F), 2), Pair.of(new SetWalkTargetFromLookTarget(1.0F, 3), 2), Pair.of(new DoNothing(30, 60), 1))))), ImmutableSet.of()); + } + + public static void updateActivity(Allay allay) { + allay.getBrain().setActiveActivityToFirstValid(ImmutableList.of(Activity.IDLE)); + } + + public static void hearNoteblock(LivingEntity entity, BlockPos pos) { + Brain brain = entity.getBrain(); + GlobalPos globalPos = GlobalPos.of(entity.getLevel().dimension(), pos); + Optional likedNoteblock = brain.getMemory(WBMemoryModules.LIKED_NOTEBLOCK.get()); + if (likedNoteblock.isEmpty()) { + brain.setMemory(WBMemoryModules.LIKED_NOTEBLOCK.get(), globalPos); + brain.setMemory(WBMemoryModules.LIKED_NOTEBLOCK_COOLDOWN_TICKS.get(), 600); + } else if (likedNoteblock.get().equals(globalPos)) { + brain.setMemory(WBMemoryModules.LIKED_NOTEBLOCK_COOLDOWN_TICKS.get(), 600); + } + } + + private static Optional getItemDepositPosition(LivingEntity entity) { + Brain brain = entity.getBrain(); + Optional likedNoteblock = brain.getMemory(WBMemoryModules.LIKED_NOTEBLOCK.get()); + if (likedNoteblock.isPresent()) { + GlobalPos pos = likedNoteblock.get(); + if (shouldDepositItemsAtLikedNoteblock(entity, brain, pos)) return Optional.of(new BlockPosTracker(pos.pos().above())); + brain.eraseMemory(WBMemoryModules.LIKED_NOTEBLOCK.get()); + } + + return getLikedPlayerPositionTracker(entity); + } + + private static boolean shouldDepositItemsAtLikedNoteblock(LivingEntity entity, Brain brain, GlobalPos pos) { + Optional cooldownTicks = brain.getMemory(WBMemoryModules.LIKED_NOTEBLOCK_COOLDOWN_TICKS.get()); + Level level = entity.getLevel(); + return level.dimension() == pos.dimension() && level.getBlockState(pos.pos()).is(Blocks.NOTE_BLOCK) && cooldownTicks.isPresent(); + } + + private static Optional getLikedPlayerPositionTracker(LivingEntity entity) { + return getLikedPlayer(entity).map(player -> new EntityTracker(player, true)); + } + + public static Optional getLikedPlayer(LivingEntity entity) { + Level level = entity.getLevel(); + if (!level.isClientSide && level instanceof ServerLevel server) { + Optional likedPlayer = entity.getBrain().getMemory(WBMemoryModules.LIKED_PLAYER.get()); + if (likedPlayer.isPresent()) { + if (server.getEntity(likedPlayer.get()) instanceof ServerPlayer player) { + if ((player.gameMode.isSurvival() || player.gameMode.isCreative()) && player.closerThan(entity, 64.0D)) return Optional.of(player); + } + + return Optional.empty(); + } + } + + return Optional.empty(); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/FrogBrain.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/FrogBrain.java new file mode 100644 index 0000000..45ab6a6 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/FrogBrain.java @@ -0,0 +1,105 @@ +package com.cursedcauldron.wildbackport.common.entities.brain; + +import com.cursedcauldron.wildbackport.client.registry.WBSoundEvents; +import com.cursedcauldron.wildbackport.common.entities.Frog; +import com.cursedcauldron.wildbackport.common.entities.brain.frog.BiasedLongJumpTask; +import com.cursedcauldron.wildbackport.common.entities.brain.frog.Croak; +import com.cursedcauldron.wildbackport.common.entities.brain.frog.FrogEat; +import com.cursedcauldron.wildbackport.common.entities.brain.frog.LayFrogSpawnTask; +import com.cursedcauldron.wildbackport.common.entities.brain.frog.WalkTowardsLand; +import com.cursedcauldron.wildbackport.common.entities.brain.frog.WalkTowardsWater; +import com.cursedcauldron.wildbackport.common.registry.WBBlocks; +import com.cursedcauldron.wildbackport.common.registry.entity.WBActivities; +import com.cursedcauldron.wildbackport.common.registry.entity.WBEntities; +import com.cursedcauldron.wildbackport.common.registry.entity.WBMemoryModules; +import com.cursedcauldron.wildbackport.common.tag.WBBlockTags; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.mojang.datafixers.util.Pair; +import net.minecraft.util.valueproviders.UniformInt; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.Brain; +import net.minecraft.world.entity.ai.behavior.AnimalMakeLove; +import net.minecraft.world.entity.ai.behavior.AnimalPanic; +import net.minecraft.world.entity.ai.behavior.CountDownCooldownTicks; +import net.minecraft.world.entity.ai.behavior.DoNothing; +import net.minecraft.world.entity.ai.behavior.FollowTemptation; +import net.minecraft.world.entity.ai.behavior.GateBehavior; +import net.minecraft.world.entity.ai.behavior.LongJumpMidJump; +import net.minecraft.world.entity.ai.behavior.LookAtTargetSink; +import net.minecraft.world.entity.ai.behavior.MoveToTargetSink; +import net.minecraft.world.entity.ai.behavior.RandomStroll; +import net.minecraft.world.entity.ai.behavior.RunIf; +import net.minecraft.world.entity.ai.behavior.RunOne; +import net.minecraft.world.entity.ai.behavior.RunSometimes; +import net.minecraft.world.entity.ai.behavior.SetEntityLookTarget; +import net.minecraft.world.entity.ai.behavior.SetWalkTargetFromLookTarget; +import net.minecraft.world.entity.ai.behavior.StartAttacking; +import net.minecraft.world.entity.ai.behavior.StopAttackingIfTargetInvalid; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; +import net.minecraft.world.entity.ai.memory.MemoryStatus; +import net.minecraft.world.entity.schedule.Activity; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.level.block.Blocks; + +import java.util.Random; + +public class FrogBrain { + private static final UniformInt LONG_JUMP_COOLDOWN_RANGE = UniformInt.of(100, 140); + + public static void coolDownLongJump(Frog frog, Random random) { + frog.getBrain().setMemory(MemoryModuleType.LONG_JUMP_COOLDOWN_TICKS, LONG_JUMP_COOLDOWN_RANGE.sample(random)); + } + + public static Brain create(Brain brain) { + addCoreActivities(brain); + addIdleActivities(brain); + addSwimActivities(brain); + addLaySpawnActivities(brain); + addTongueActivities(brain); + addLongJumpActivities(brain); + brain.setCoreActivities(ImmutableSet.of(Activity.CORE)); + brain.setDefaultActivity(Activity.IDLE); + brain.useDefaultActivity(); + return brain; + } + + private static void addCoreActivities(Brain brain) { + brain.addActivity(Activity.CORE, 0, ImmutableList.of(new AnimalPanic(2.0F), new LookAtTargetSink(45, 90), new MoveToTargetSink(), new CountDownCooldownTicks(MemoryModuleType.TEMPTATION_COOLDOWN_TICKS), new CountDownCooldownTicks(MemoryModuleType.LONG_JUMP_COOLDOWN_TICKS))); + } + + private static void addIdleActivities(Brain brain) { + brain.addActivityWithConditions(Activity.IDLE, ImmutableList.of(Pair.of(0, new RunSometimes(new SetEntityLookTarget(EntityType.PLAYER, 6.0F), UniformInt.of(30, 60))), Pair.of(0, new AnimalMakeLove(WBEntities.FROG.get(), 1.0F)), Pair.of(1, new FollowTemptation(entity -> 1.25F)), Pair.of(2, new StartAttacking<>(FrogBrain::isNotBreeding, frog -> frog.getBrain().getMemory(MemoryModuleType.NEAREST_ATTACKABLE))), Pair.of(3, new WalkTowardsLand(6, 1.0F)), Pair.of(4, new RunOne<>(ImmutableMap.of(MemoryModuleType.WALK_TARGET, MemoryStatus.VALUE_ABSENT), ImmutableList.of(Pair.of(new RandomStroll(1.0F), 1), Pair.of(new SetWalkTargetFromLookTarget(1.0F, 3), 1), Pair.of(new Croak(), 3), Pair.of(new RunIf<>(Entity::isOnGround, new DoNothing(5, 20)), 2))))), ImmutableSet.of(Pair.of(MemoryModuleType.LONG_JUMP_MID_JUMP, MemoryStatus.VALUE_ABSENT), Pair.of(WBMemoryModules.IS_IN_WATER.get(), MemoryStatus.VALUE_ABSENT))); + } + + private static void addSwimActivities(Brain brain) { + brain.addActivityWithConditions(WBActivities.SWIM.get(), ImmutableList.of(Pair.of(0, new RunSometimes(new SetEntityLookTarget(EntityType.PLAYER, 6.0F), UniformInt.of(30, 60))), Pair.of(1, new FollowTemptation(entity -> 1.25F)), Pair.of(2, new StartAttacking<>(FrogBrain::isNotBreeding, frog -> frog.getBrain().getMemory(MemoryModuleType.NEAREST_ATTACKABLE))), Pair.of(3, new WalkTowardsLand(8, 1.5F)), Pair.of(5, new GateBehavior<>(ImmutableMap.of(MemoryModuleType.WALK_TARGET, MemoryStatus.VALUE_ABSENT), ImmutableSet.of(), GateBehavior.OrderPolicy.ORDERED, GateBehavior.RunningPolicy.TRY_ALL, ImmutableList.of(Pair.of(new RandomStroll(0.75F), 1), Pair.of(new RandomStroll(1.0F, true), 1), Pair.of(new SetWalkTargetFromLookTarget(1.0F, 3), 1), Pair.of(new RunIf<>(Entity::isInWaterOrBubble, new DoNothing(30, 60)), 5))))), ImmutableSet.of(Pair.of(MemoryModuleType.LONG_JUMP_MID_JUMP, MemoryStatus.VALUE_ABSENT), Pair.of(WBMemoryModules.IS_IN_WATER.get(), MemoryStatus.VALUE_PRESENT))); + } + + private static void addLaySpawnActivities(Brain brain) { + brain.addActivityWithConditions(WBActivities.LAY_SPAWN.get(), ImmutableList.of(Pair.of(0, new RunSometimes(new SetEntityLookTarget(EntityType.PLAYER, 6.0F), UniformInt.of(30, 60))), Pair.of(1, new StartAttacking<>(FrogBrain::isNotBreeding, frog -> frog.getBrain().getMemory(MemoryModuleType.NEAREST_ATTACKABLE))), Pair.of(2, new WalkTowardsWater(8, 1.0F)), Pair.of(3, new LayFrogSpawnTask(WBBlocks.FROGSPAWN.get(), WBMemoryModules.IS_PREGNANT.get())), Pair.of(4, new RunOne<>(ImmutableList.of(Pair.of(new RandomStroll(1.0F), 2), Pair.of(new SetWalkTargetFromLookTarget(1.0F, 3), 1), Pair.of(new Croak(), 2), Pair.of(new RunIf<>(Entity::isOnGround, new DoNothing(5, 20)), 1))))), ImmutableSet.of(Pair.of(MemoryModuleType.LONG_JUMP_MID_JUMP, MemoryStatus.VALUE_ABSENT), Pair.of(WBMemoryModules.IS_PREGNANT.get(), MemoryStatus.VALUE_PRESENT))); + } + + private static void addLongJumpActivities(Brain brain) { + brain.addActivityWithConditions(Activity.LONG_JUMP, ImmutableList.of(Pair.of(0, new LongJumpMidJump(LONG_JUMP_COOLDOWN_RANGE, WBSoundEvents.FROG_STEP)), Pair.of(1, new BiasedLongJumpTask<>(LONG_JUMP_COOLDOWN_RANGE, 2, 4, 1.5F, frog -> WBSoundEvents.FROG_LONG_JUMP, WBBlockTags.FROG_PREFER_JUMP_TO, 0.5F, state -> state.is(Blocks.LILY_PAD)))), ImmutableSet.of(Pair.of(MemoryModuleType.TEMPTING_PLAYER, MemoryStatus.VALUE_ABSENT), Pair.of(MemoryModuleType.BREED_TARGET, MemoryStatus.VALUE_ABSENT), Pair.of(MemoryModuleType.LONG_JUMP_COOLDOWN_TICKS, MemoryStatus.VALUE_ABSENT), Pair.of(WBMemoryModules.IS_IN_WATER.get(), MemoryStatus.VALUE_ABSENT))); + } + + private static void addTongueActivities(Brain brain) { + brain.addActivityAndRemoveMemoryWhenStopped(WBActivities.TONGUE.get(), 0, ImmutableList.of(new StopAttackingIfTargetInvalid<>(), new FrogEat(WBSoundEvents.FROG_TONGUE, WBSoundEvents.FROG_EAT)), MemoryModuleType.ATTACK_TARGET); + } + + private static boolean isNotBreeding(Frog frog) { + return !frog.getBrain().hasMemoryValue(MemoryModuleType.BREED_TARGET); + } + + public static void updateActivities(Frog frog) { + frog.getBrain().setActiveActivityToFirstValid(ImmutableList.of(WBActivities.TONGUE.get(), WBActivities.LAY_SPAWN.get(), Activity.LONG_JUMP, WBActivities.SWIM.get(), Activity.IDLE)); + } + + public static Ingredient getTemptItems() { + return Frog.FOOD; + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/TadpoleBrain.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/TadpoleBrain.java new file mode 100644 index 0000000..29905f2 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/TadpoleBrain.java @@ -0,0 +1,51 @@ +package com.cursedcauldron.wildbackport.common.entities.brain; + +import com.cursedcauldron.wildbackport.common.entities.Tadpole; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.mojang.datafixers.util.Pair; +import net.minecraft.util.valueproviders.UniformInt; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.Brain; +import net.minecraft.world.entity.ai.behavior.AnimalPanic; +import net.minecraft.world.entity.ai.behavior.CountDownCooldownTicks; +import net.minecraft.world.entity.ai.behavior.DoNothing; +import net.minecraft.world.entity.ai.behavior.GateBehavior; +import net.minecraft.world.entity.ai.behavior.LookAtTargetSink; +import net.minecraft.world.entity.ai.behavior.MoveToTargetSink; +import net.minecraft.world.entity.ai.behavior.RandomStroll; +import net.minecraft.world.entity.ai.behavior.RandomSwim; +import net.minecraft.world.entity.ai.behavior.RunIf; +import net.minecraft.world.entity.ai.behavior.RunSometimes; +import net.minecraft.world.entity.ai.behavior.SetEntityLookTarget; +import net.minecraft.world.entity.ai.behavior.SetWalkTargetFromLookTarget; +import net.minecraft.world.entity.ai.behavior.TryFindWater; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; +import net.minecraft.world.entity.ai.memory.MemoryStatus; +import net.minecraft.world.entity.schedule.Activity; + +public class TadpoleBrain { + public static Brain create(Brain brain) { + TadpoleBrain.addCoreActivities(brain); + TadpoleBrain.addIdleActivities(brain); + brain.setCoreActivities(ImmutableSet.of(Activity.CORE)); + brain.setDefaultActivity(Activity.IDLE); + brain.useDefaultActivity(); + return brain; + } + + private static void addCoreActivities(Brain brain) { + brain.addActivity(Activity.CORE, 0, ImmutableList.of(new AnimalPanic(2.0f), new LookAtTargetSink(45, 90), new MoveToTargetSink(), new CountDownCooldownTicks(MemoryModuleType.TEMPTATION_COOLDOWN_TICKS))); + } + + private static void addIdleActivities(Brain brain) { + brain.addActivity(Activity.IDLE, ImmutableList.of(Pair.of(0, new RunSometimes(new SetEntityLookTarget(EntityType.PLAYER, 6.0f), UniformInt.of(30, 60))), Pair.of(3, new TryFindWater(6, 0.15f)), Pair.of(4, new GateBehavior<>(ImmutableMap.of(MemoryModuleType.WALK_TARGET, MemoryStatus.VALUE_ABSENT), ImmutableSet.of(), GateBehavior.OrderPolicy.ORDERED, GateBehavior.RunningPolicy.TRY_ALL, ImmutableList.of(Pair.of(new RandomSwim(0.5f), 2), Pair.of(new RandomStroll(0.15f), 2), Pair.of(new SetWalkTargetFromLookTarget(0.5f, 3), 3), Pair.of(new RunIf<>(Entity::isInWaterOrBubble, new DoNothing(30, 60)), 5)))))); + } + + public static void updateActivities(Tadpole tadpole) { + tadpole.getBrain().setActiveActivityToFirstValid(ImmutableList.of(Activity.IDLE)); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/WardenBrain.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/WardenBrain.java new file mode 100644 index 0000000..38fbee3 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/WardenBrain.java @@ -0,0 +1,143 @@ +package com.cursedcauldron.wildbackport.common.entities.brain; + +import com.cursedcauldron.wildbackport.common.entities.brain.warden.ForgetAttackTargetTask; +import com.cursedcauldron.wildbackport.common.entities.brain.warden.Digging; +import com.cursedcauldron.wildbackport.common.entities.brain.warden.Dismount; +import com.cursedcauldron.wildbackport.common.entities.brain.warden.Emerging; +import com.cursedcauldron.wildbackport.common.entities.brain.warden.GoToTargetLocation; +import com.cursedcauldron.wildbackport.common.entities.brain.warden.Roar; +import com.cursedcauldron.wildbackport.common.entities.brain.warden.SetRoarTarget; +import com.cursedcauldron.wildbackport.common.entities.brain.warden.SetWardenLookTarget; +import com.cursedcauldron.wildbackport.common.entities.brain.warden.Sniffing; +import com.cursedcauldron.wildbackport.common.entities.brain.warden.SonicBoom; +import com.cursedcauldron.wildbackport.common.entities.brain.warden.TryToSniff; +import com.cursedcauldron.wildbackport.common.entities.Warden; +import com.cursedcauldron.wildbackport.common.registry.entity.WBActivities; +import com.cursedcauldron.wildbackport.common.registry.entity.WBMemoryModules; +import com.cursedcauldron.wildbackport.common.registry.entity.WBSensorTypes; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.mojang.datafixers.util.Pair; +import com.mojang.serialization.Dynamic; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.Mth; +import net.minecraft.util.Unit; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.Brain; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.ai.behavior.Behavior; +import net.minecraft.world.entity.ai.behavior.BlockPosTracker; +import net.minecraft.world.entity.ai.behavior.DoNothing; +import net.minecraft.world.entity.ai.behavior.LookAtTargetSink; +import net.minecraft.world.entity.ai.behavior.MeleeAttack; +import net.minecraft.world.entity.ai.behavior.MoveToTargetSink; +import net.minecraft.world.entity.ai.behavior.RandomStroll; +import net.minecraft.world.entity.ai.behavior.RunOne; +import net.minecraft.world.entity.ai.behavior.SetEntityLookTarget; +import net.minecraft.world.entity.ai.behavior.SetWalkTargetFromAttackTargetIfTargetOutOfReach; +import net.minecraft.world.entity.ai.behavior.Swim; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; +import net.minecraft.world.entity.ai.memory.MemoryStatus; +import net.minecraft.world.entity.ai.sensing.Sensor; +import net.minecraft.world.entity.ai.sensing.SensorType; +import net.minecraft.world.entity.schedule.Activity; + +import java.util.List; + +//<> + +public class WardenBrain { + private static final int DIGGING_DURATION = Mth.ceil(100.0F); + public static final int EMERGE_DURATION = Mth.ceil(133.59999F); + public static final int ROAR_DURATION = Mth.ceil(84.0F); + private static final int SNIFFING_DURATION = Mth.ceil(83.2F); + private static final List>> SENSORS = List.of(SensorType.NEAREST_PLAYERS, WBSensorTypes.WARDEN_ENTITY_SENSOR.get()); + private static final List> MEMORIES = List.of(MemoryModuleType.NEAREST_LIVING_ENTITIES, MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, MemoryModuleType.NEAREST_VISIBLE_PLAYER, MemoryModuleType.NEAREST_VISIBLE_ATTACKABLE_PLAYER, MemoryModuleType.NEAREST_VISIBLE_NEMESIS, MemoryModuleType.LOOK_TARGET, MemoryModuleType.WALK_TARGET, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryModuleType.PATH, MemoryModuleType.ATTACK_TARGET, MemoryModuleType.ATTACK_COOLING_DOWN, MemoryModuleType.NEAREST_ATTACKABLE, WBMemoryModules.ROAR_TARGET.get(), WBMemoryModules.DISTURBANCE_LOCATION.get(), WBMemoryModules.RECENT_PROJECTILE.get(), WBMemoryModules.IS_SNIFFING.get(), WBMemoryModules.IS_EMERGING.get(), WBMemoryModules.ROAR_SOUND_DELAY.get(), WBMemoryModules.DIG_COOLDOWN.get(), WBMemoryModules.ROAR_SOUND_COOLDOWN.get(), WBMemoryModules.SNIFF_COOLDOWN.get(), WBMemoryModules.TOUCH_COOLDOWN.get(), WBMemoryModules.VIBRATION_COOLDOWN.get(), WBMemoryModules.SONIC_BOOM_COOLDOWN.get(), WBMemoryModules.SONIC_BOOM_SOUND_COOLDOWN.get(), WBMemoryModules.SONIC_BOOM_SOUND_DELAY.get()); + private static final Behavior DIG_COOLDOWN_SETTER = new Behavior<>(ImmutableMap.of(WBMemoryModules.DIG_COOLDOWN.get(), MemoryStatus.REGISTERED)) { + @Override protected void start(ServerLevel level, Warden warden, long time) { + setDigCooldown(warden); + } + }; + + public static void updateActivity(Warden warden) { + warden.getBrain().setActiveActivityToFirstValid(ImmutableList.of(WBActivities.EMERGE.get(), WBActivities.DIG.get(), WBActivities.ROAR.get(), Activity.FIGHT, WBActivities.INVESTIGATE.get(), WBActivities.SNIFF.get(), Activity.IDLE)); + } + + public static Brain makeBrain(Warden warden, Dynamic dynamic) { + Brain.Provider provider = Brain.provider(MEMORIES, SENSORS); + Brain brain = provider.makeBrain(dynamic); + initCoreActivity(brain); + initEmergeActivity(brain); + initDiggingActivity(brain); + initIdleActivity(brain); + initRoarActivity(brain); + initFightActivity(warden, brain); + initInvestigateActivity(brain); + initSniffingActivity(brain); + brain.setCoreActivities(ImmutableSet.of(Activity.CORE)); + brain.setDefaultActivity(Activity.IDLE); + brain.useDefaultActivity(); + return brain; + } + + private static void initCoreActivity(Brain brain) { + brain.addActivity(Activity.CORE, 0, ImmutableList.of(new Swim(0.8F), new SetWardenLookTarget(), new LookAtTargetSink(45, 90), new MoveToTargetSink())); + } + + private static void initEmergeActivity(Brain brain) { + brain.addActivityAndRemoveMemoryWhenStopped(WBActivities.EMERGE.get(), 5, ImmutableList.of(new Emerging<>(EMERGE_DURATION)), WBMemoryModules.IS_EMERGING.get()); + } + + private static void initDiggingActivity(Brain brain) { + brain.addActivityWithConditions(WBActivities.DIG.get(), ImmutableList.of(Pair.of(0, new Dismount()), Pair.of(1, new Digging<>(DIGGING_DURATION))), ImmutableSet.of(Pair.of(WBMemoryModules.ROAR_TARGET.get(), MemoryStatus.VALUE_ABSENT), Pair.of(WBMemoryModules.DIG_COOLDOWN.get(), MemoryStatus.VALUE_ABSENT))); + } + + private static void initIdleActivity(Brain brain) { + brain.addActivity(Activity.IDLE, 10, ImmutableList.of(new SetRoarTarget<>(Warden::getEntityAngryAt), new TryToSniff(), new RunOne<>(ImmutableMap.of(WBMemoryModules.IS_SNIFFING.get(), MemoryStatus.VALUE_ABSENT), ImmutableList.of(Pair.of(new RandomStroll(0.5F), 2), Pair.of(new DoNothing(30, 60), 1))))); + } + + private static void initInvestigateActivity(Brain brain) { + brain.addActivityAndRemoveMemoryWhenStopped(WBActivities.INVESTIGATE.get(), 5, ImmutableList.of(new SetRoarTarget<>(Warden::getEntityAngryAt), new GoToTargetLocation<>(WBMemoryModules.DISTURBANCE_LOCATION.get(), 2, 0.7F)), WBMemoryModules.DISTURBANCE_LOCATION.get()); + } + + private static void initSniffingActivity(Brain brain) { + brain.addActivityAndRemoveMemoryWhenStopped(WBActivities.SNIFF.get(), 5, ImmutableList.of(new SetRoarTarget<>(Warden::getEntityAngryAt), new Sniffing<>(SNIFFING_DURATION)), WBMemoryModules.IS_SNIFFING.get()); + } + + private static void initRoarActivity(Brain brain) { + brain.addActivityAndRemoveMemoryWhenStopped(WBActivities.ROAR.get(), 10, ImmutableList.of(new Roar()), WBMemoryModules.ROAR_TARGET.get()); + } + + private static void initFightActivity(Warden warden, Brain brain) { + brain.addActivityAndRemoveMemoryWhenStopped(Activity.FIGHT, 10, ImmutableList.of(DIG_COOLDOWN_SETTER, new ForgetAttackTargetTask<>(target -> { + return !warden.getAngriness().isAngry() || !warden.isValidTarget(target); + }, WardenBrain::onTargetInvalid, false), new SetEntityLookTarget(target -> { + return isTarget(warden, target); + }, (float)warden.getAttributeValue(Attributes.FOLLOW_RANGE)), new SetWalkTargetFromAttackTargetIfTargetOutOfReach(1.2F), new SonicBoom(), new MeleeAttack(18)), MemoryModuleType.ATTACK_TARGET); + } + + private static boolean isTarget(Warden warden, LivingEntity entity) { + return warden.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET).filter(target -> target == entity).isPresent(); + } + + private static void onTargetInvalid(Warden warden, LivingEntity entity) { + if (!warden.isValidTarget(entity)) warden.removeSuspect(entity); + setDigCooldown(warden); + } + + public static void setDigCooldown(LivingEntity entity) { + if (entity.getBrain().hasMemoryValue(WBMemoryModules.DIG_COOLDOWN.get())) entity.getBrain().setMemoryWithExpiry(WBMemoryModules.DIG_COOLDOWN.get(), Unit.INSTANCE, 1200L); + } + + public static void setDisturbanceLocation(Warden warden, BlockPos pos) { + if (warden.level.getWorldBorder().isWithinBounds(pos) && warden.getEntityAngryAt().isEmpty() && warden.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET).isEmpty()) { + setDigCooldown(warden); + warden.getBrain().setMemoryWithExpiry(WBMemoryModules.SNIFF_COOLDOWN.get(), Unit.INSTANCE, 100L); + warden.getBrain().setMemoryWithExpiry(MemoryModuleType.LOOK_TARGET, new BlockPosTracker(pos), 100L); + warden.getBrain().setMemoryWithExpiry(WBMemoryModules.DISTURBANCE_LOCATION.get(), pos, 100L); + warden.getBrain().eraseMemory(MemoryModuleType.WALK_TARGET); + } + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/allay/FlyingRandomStroll.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/allay/FlyingRandomStroll.java new file mode 100644 index 0000000..b3f8877 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/allay/FlyingRandomStroll.java @@ -0,0 +1,19 @@ +package com.cursedcauldron.wildbackport.common.entities.brain.allay; + +import net.minecraft.world.entity.PathfinderMob; +import net.minecraft.world.entity.ai.behavior.RandomStroll; +import net.minecraft.world.entity.ai.util.AirAndWaterRandomPos; +import net.minecraft.world.phys.Vec3; +import org.jetbrains.annotations.Nullable; + +public class FlyingRandomStroll extends RandomStroll { + public FlyingRandomStroll(float distance) { + super(distance, true); + } + + @Override @Nullable + protected Vec3 getTargetPos(PathfinderMob mob) { + Vec3 vector = mob.getViewVector(0.0F); + return AirAndWaterRandomPos.getPos(mob, this.maxHorizontalDistance, this.maxVerticalDistance, -2, vector.x, vector.z, (float)Math.PI / 2.0F); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/allay/GoAndGiveItemsToTarget.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/allay/GoAndGiveItemsToTarget.java new file mode 100644 index 0000000..d4f886b --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/allay/GoAndGiveItemsToTarget.java @@ -0,0 +1,97 @@ +package com.cursedcauldron.wildbackport.common.entities.brain.allay; + +import com.cursedcauldron.wildbackport.client.registry.WBSoundEvents; +import com.cursedcauldron.wildbackport.common.entities.Allay; +import com.cursedcauldron.wildbackport.common.entities.brain.AllayBrain; +import com.cursedcauldron.wildbackport.common.registry.entity.WBMemoryModules; +import com.cursedcauldron.wildbackport.common.utils.MobUtils; +import com.google.common.collect.ImmutableMap; +import net.minecraft.Util; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.behavior.Behavior; +import net.minecraft.world.entity.ai.behavior.PositionTracker; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; +import net.minecraft.world.entity.ai.memory.MemoryStatus; +import net.minecraft.world.entity.npc.InventoryCarrier; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.Vec3; + +import java.util.Optional; +import java.util.function.Function; + +//<> + +public class GoAndGiveItemsToTarget extends Behavior { + private final Function> targetPosition; + private final float speedModifier; + + public GoAndGiveItemsToTarget(Function> targetPosition, float speedModifier) { + super(ImmutableMap.of(MemoryModuleType.LOOK_TARGET, MemoryStatus.REGISTERED, MemoryModuleType.WALK_TARGET, MemoryStatus.REGISTERED, WBMemoryModules.ITEM_PICKUP_COOLDOWN_TICKS.get(), MemoryStatus.REGISTERED)); + this.targetPosition = targetPosition; + this.speedModifier = speedModifier; + } + + @Override + protected boolean checkExtraStartConditions(ServerLevel level, E entity) { + return this.canThrowItemToTarget(entity); + } + + @Override + protected boolean canStillUse(ServerLevel level, E entity, long time) { + return this.canThrowItemToTarget(entity); + } + + @Override + protected void start(ServerLevel level, E entity, long time) { + this.targetPosition.apply(entity).ifPresent(target -> MobUtils.setWalkAndLookTargetMemories(entity, target, this.speedModifier, 3)); + } + + @Override + protected void tick(ServerLevel level, E entity, long time) { + Optional optional = this.targetPosition.apply(entity); + if (optional.isPresent()) { + PositionTracker tracker = optional.get(); + double d0 = tracker.currentPosition().distanceTo(entity.getEyePosition()); + if (d0 < 3.0D) { + ItemStack itemstack = entity.getInventory().removeItem(0, 1); + if (!itemstack.isEmpty()) { + throwItem(entity, itemstack, getThrowPosition(tracker)); + if (entity instanceof Allay allay) { + AllayBrain.getLikedPlayer(allay).ifPresent(p_217224_ -> this.triggerDropItemOnBlock(tracker, itemstack, p_217224_)); + } + + entity.getBrain().setMemory(WBMemoryModules.ITEM_PICKUP_COOLDOWN_TICKS.get(), 60); + } + } + + } + } + + private void triggerDropItemOnBlock(PositionTracker tracker, ItemStack stack, ServerPlayer player) { + BlockPos pos = tracker.currentBlockPosition().below(); +// WBCriteriaTriggers.ALLAY_DROP_ITEM_ON_BLOCK.trigger(player, pos, stack); + } + + private boolean canThrowItemToTarget(E entity) { + return !entity.getInventory().isEmpty() && this.targetPosition.apply(entity).isPresent(); + } + + private static Vec3 getThrowPosition(PositionTracker tracker) { + return tracker.currentPosition().add(0.0D, 1.0D, 0.0D); + } + + public static void throwItem(LivingEntity entity, ItemStack stack, Vec3 position) { + Vec3 vec3 = new Vec3(0.2F, 0.3F, 0.2F); + MobUtils.throwItem(entity, stack, position, vec3, 0.2F); + Level level = entity.level; + if (level.getGameTime() % 7L == 0L && level.random.nextDouble() < 0.9D) { + float pitch = Util.getRandom(Allay.SOUND_PITCHES, level.getRandom()); + level.playSound(null, entity, WBSoundEvents.ALLAY_ITEM_THROW, SoundSource.NEUTRAL, 1.0F, pitch); + } + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/allay/StayCloseToTarget.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/allay/StayCloseToTarget.java new file mode 100644 index 0000000..8e4d985 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/allay/StayCloseToTarget.java @@ -0,0 +1,39 @@ +package com.cursedcauldron.wildbackport.common.entities.brain.allay; + +import com.cursedcauldron.wildbackport.common.utils.MobUtils; +import com.google.common.collect.ImmutableMap; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.behavior.Behavior; +import net.minecraft.world.entity.ai.behavior.PositionTracker; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; +import net.minecraft.world.entity.ai.memory.MemoryStatus; + +import java.util.Optional; +import java.util.function.Function; + +public class StayCloseToTarget extends Behavior { + private final Function> targetPosition; + private final int closeEnough; + private final int tooFar; + private final float speedModifier; + + public StayCloseToTarget(Function> targetPosition, int closeEnough, int tooFar, float speedModifier) { + super(ImmutableMap.of(MemoryModuleType.WALK_TARGET, MemoryStatus.VALUE_ABSENT)); + this.targetPosition = targetPosition; + this.closeEnough = closeEnough; + this.tooFar = tooFar; + this.speedModifier = speedModifier; + } + + @Override + protected boolean checkExtraStartConditions(ServerLevel level, E entity) { + Optional tracker = this.targetPosition.apply(entity); + return tracker.isPresent() && !entity.position().closerThan(tracker.get().currentPosition(), this.tooFar); + } + + @Override + protected void start(ServerLevel level, E entity, long time) { + MobUtils.setWalkAndLookTargetMemories(entity, this.targetPosition.apply(entity).get(), this.speedModifier, this.closeEnough); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/frog/BiasedLongJumpTask.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/frog/BiasedLongJumpTask.java new file mode 100644 index 0000000..2f9cdb8 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/frog/BiasedLongJumpTask.java @@ -0,0 +1,69 @@ +package com.cursedcauldron.wildbackport.common.entities.brain.frog; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.tags.TagKey; +import net.minecraft.util.valueproviders.UniformInt; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.function.Function; +import java.util.function.Predicate; + +public class BiasedLongJumpTask extends FrogJumpToRandomPos { + private final TagKey preferredBlocks; + private final float chance; + private final List targetCandidates = new ArrayList<>(); + private boolean priorityOnPreferred; + + public BiasedLongJumpTask(UniformInt cooldown, int yRange, int xzRange, float range, Function landingSound, TagKey preferredBlocks, float chance, Predicate landingBlocks) { + super(cooldown, yRange, xzRange, range, landingSound, landingBlocks); + this.preferredBlocks = preferredBlocks; + this.chance = chance; + } + + @Override + protected void start(ServerLevel level, E entity, long time) { + super.start(level, entity, time); + this.targetCandidates.clear(); + this.priorityOnPreferred = entity.getRandom().nextFloat() < this.chance; + } + + @Override + protected Optional jumpTarget(ServerLevel level) { + if (!this.priorityOnPreferred) { + return super.jumpTarget(level); + } else { + BlockPos.MutableBlockPos mutable = new BlockPos.MutableBlockPos(); + + while (!this.targets.isEmpty()) { + Optional jumpTarget = super.jumpTarget(level); + if (jumpTarget.isPresent()) { + FrogJumpToRandomPos.Target target = jumpTarget.get(); + if (level.getBlockState(mutable.setWithOffset(target.getPos(), Direction.DOWN)).is(this.preferredBlocks)) { + return jumpTarget; + } + + this.targetCandidates.add(target); + } + } + + return !this.targetCandidates.isEmpty() ? Optional.of(this.targetCandidates.remove(0)) : Optional.empty(); + } + } + + @Override + protected boolean canLandOn(ServerLevel level, E entity, BlockPos pos) { + return super.canLandOn(level, entity, pos) && this.cantLandInFluid(level, pos); + } + + private boolean cantLandInFluid(ServerLevel level, BlockPos pos) { + return level.getFluidState(pos).isEmpty() && level.getFluidState(pos.below()).isEmpty(); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/frog/Croak.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/frog/Croak.java new file mode 100644 index 0000000..687e04e --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/frog/Croak.java @@ -0,0 +1,47 @@ +package com.cursedcauldron.wildbackport.common.entities.brain.frog; + +import com.cursedcauldron.wildbackport.common.entities.Frog; +import com.cursedcauldron.wildbackport.common.entities.access.api.Poses; +import com.google.common.collect.ImmutableMap; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Pose; +import net.minecraft.world.entity.ai.behavior.Behavior; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; +import net.minecraft.world.entity.ai.memory.MemoryStatus; + +public class Croak extends Behavior { + private int ticks; + + public Croak() { + super(ImmutableMap.of(MemoryModuleType.WALK_TARGET, MemoryStatus.VALUE_ABSENT), 100); + } + + @Override + protected boolean checkExtraStartConditions(ServerLevel level, Frog frog) { + return frog.isInPose(Pose.STANDING); + } + + @Override + protected boolean canStillUse(ServerLevel level, Frog frog, long time) { + return this.ticks < 40; + } + + @Override + protected void start(ServerLevel level, Frog frog, long time) { + + if (!frog.isInWaterOrBubble() && !frog.isInLava()) { + frog.setPose(Poses.CROAKING.get()); + this.ticks = 0; + } + } + + @Override + protected void stop(ServerLevel level, Frog frog, long time) { + frog.setPose(Pose.STANDING); + } + + @Override + protected void tick(ServerLevel level, Frog frog, long time) { + ++this.ticks; + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/frog/FrogAttackablesSensor.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/frog/FrogAttackablesSensor.java new file mode 100644 index 0000000..898f52a --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/frog/FrogAttackablesSensor.java @@ -0,0 +1,31 @@ +package com.cursedcauldron.wildbackport.common.entities.brain.frog; + +import com.cursedcauldron.wildbackport.common.entities.Frog; +import com.cursedcauldron.wildbackport.common.registry.entity.WBMemoryModules; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; +import net.minecraft.world.entity.ai.sensing.NearestVisibleLivingEntitySensor; +import net.minecraft.world.entity.ai.sensing.Sensor; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +//<> + +public class FrogAttackablesSensor extends NearestVisibleLivingEntitySensor { + @Override + protected boolean isMatchingEntity(LivingEntity entity, LivingEntity target) { + return !entity.getBrain().hasMemoryValue(MemoryModuleType.HAS_HUNTING_COOLDOWN) && Sensor.isEntityAttackable(entity, target) && Frog.isValidFrogFood(target) && !this.cantReachTarget(entity, target) && target.closerThan(entity, 10.0D); + } + + private boolean cantReachTarget(LivingEntity entity, LivingEntity target) { + List targets = entity.getBrain().getMemory(WBMemoryModules.UNREACHABLE_TONGUE_TARGETS.get()).orElseGet(ArrayList::new); + return targets.contains(target.getUUID()); + } + + @Override + protected MemoryModuleType getMemory() { + return MemoryModuleType.NEAREST_ATTACKABLE; + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/frog/FrogEat.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/frog/FrogEat.java new file mode 100644 index 0000000..f7aec6b --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/frog/FrogEat.java @@ -0,0 +1,162 @@ +package com.cursedcauldron.wildbackport.common.entities.brain.frog; + +import com.cursedcauldron.wildbackport.common.entities.Frog; +import com.cursedcauldron.wildbackport.common.entities.access.api.Poses; +import com.cursedcauldron.wildbackport.common.registry.WBBlocks; +import com.cursedcauldron.wildbackport.common.registry.entity.WBMemoryModules; +import com.google.common.collect.ImmutableMap; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.Pose; +import net.minecraft.world.entity.ai.behavior.Behavior; +import net.minecraft.world.entity.ai.behavior.BehaviorUtils; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; +import net.minecraft.world.entity.ai.memory.MemoryStatus; +import net.minecraft.world.entity.ai.memory.WalkTarget; +import net.minecraft.world.entity.monster.MagmaCube; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.pathfinder.Path; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +//<> + +public class FrogEat extends Behavior { + private int eatTick; + private int moveToTargetTick; + private final SoundEvent tongueSound; + private final SoundEvent eatSound; + private Phase phase = Phase.DONE; + + public FrogEat(SoundEvent tongueSound, SoundEvent eatSound) { + super(ImmutableMap.of(MemoryModuleType.WALK_TARGET, MemoryStatus.VALUE_ABSENT, MemoryModuleType.LOOK_TARGET, MemoryStatus.REGISTERED, MemoryModuleType.ATTACK_TARGET, MemoryStatus.VALUE_PRESENT), 100); + this.tongueSound = tongueSound; + this.eatSound = eatSound; + } + + @Override + protected boolean checkExtraStartConditions(ServerLevel level, Frog frog) { + LivingEntity target = frog.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET).get(); + boolean flag = this.canMoveToTarget(frog, target); + if (!flag) { + frog.getBrain().eraseMemory(MemoryModuleType.ATTACK_TARGET); + this.cantReachTarget(frog, target); + } + + return flag && frog.getPose() != Poses.CROAKING.get() && Frog.isValidFrogFood(target); + } + + @Override + protected boolean canStillUse(ServerLevel level, Frog frog, long time) { + return frog.getBrain().hasMemoryValue(MemoryModuleType.ATTACK_TARGET) && this.phase != Phase.DONE; + } + + @Override + protected void start(ServerLevel level, Frog frog, long time) { + LivingEntity entity = frog.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET).get(); + BehaviorUtils.lookAtEntity(frog, entity); + frog.setFrogTarget(entity); + frog.getBrain().setMemory(MemoryModuleType.WALK_TARGET, new WalkTarget(entity.position(), 2.0F, 0)); + this.moveToTargetTick = 10; + this.phase = Phase.MOVE_TO_TARGET; + } + + @Override + protected void stop(ServerLevel level, Frog frog, long time) { + frog.getBrain().eraseMemory(MemoryModuleType.ATTACK_TARGET); + frog.clearFrogTarget(); + frog.setPose(Pose.STANDING); + } + + private void eat(ServerLevel level, Frog frog) { + level.playSound(null, frog, this.eatSound, SoundSource.NEUTRAL, 2.0F, 1.0F); + Optional target = frog.getFrogTarget(); + if (target.isPresent()) { + Entity entity = target.get(); + if (entity.isAlive()) { + frog.doHurtTarget(entity); + if (!entity.isAlive()) { + entity.spawnAtLocation(dropStack(frog, entity)); + entity.remove(Entity.RemovalReason.KILLED); + } + } + } + } + + //Change this to loot table + private static ItemStack dropStack(Frog frog, Entity entity) { + if (entity instanceof MagmaCube) { + return new ItemStack(switch (frog.getVariant()) { + case TEMPERATE -> WBBlocks.OCHRE_FROGLIGHT.get().asItem(); + case WARM -> WBBlocks.PEARLESCENT_FROGLIGHT.get().asItem(); + case COLD -> WBBlocks.VERDANT_FROGLIGHT.get().asItem(); + }); + } else { + return new ItemStack(Items.SLIME_BALL); + } + } + + @Override + protected void tick(ServerLevel level, Frog frog, long time) { + LivingEntity target = frog.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET).get(); + frog.setFrogTarget(target); + switch (this.phase) { + case MOVE_TO_TARGET: + if (target.distanceTo(frog) < 1.75F) { + level.playSound(null, frog, this.tongueSound, SoundSource.NEUTRAL, 2.0F, 1.0F); + frog.setPose(Poses.USING_TONGUE.get()); + target.setDeltaMovement(target.position().vectorTo(frog.position()).normalize().scale(0.75D)); + this.eatTick = 0; + this.phase = Phase.CATCH_ANIMATION; + } else if (this.moveToTargetTick <= 0) { + frog.getBrain().setMemory(MemoryModuleType.WALK_TARGET, new WalkTarget(target.position(), 2.0F, 0)); + this.moveToTargetTick = 10; + } else { + --this.moveToTargetTick; + } + break; + case CATCH_ANIMATION: + if (this.eatTick++ >= 6) { + this.phase = Phase.EAT_ANIMATION; + this.eat(level, frog); + } + break; + case EAT_ANIMATION: + if (this.eatTick >= 10) { + this.phase = Phase.DONE; + } else { + ++this.eatTick; + } + case DONE: + } + } + + private boolean canMoveToTarget(Frog frog, LivingEntity entity) { + Path path = frog.getNavigation().createPath(entity, 0); + return path != null && path.getDistToTarget() < 1.75F; + } + + private void cantReachTarget(Frog frog, LivingEntity entity) { + List targets = frog.getBrain().getMemory(WBMemoryModules.UNREACHABLE_TONGUE_TARGETS.get()).orElseGet(ArrayList::new); + boolean notTargeting = !targets.contains(entity.getUUID()); + if (targets.size() == 5 && notTargeting) targets.remove(0); + + if (notTargeting) targets.add(entity.getUUID()); + + frog.getBrain().setMemoryWithExpiry(WBMemoryModules.UNREACHABLE_TONGUE_TARGETS.get(), targets, 100L); + } + + enum Phase { + MOVE_TO_TARGET, + CATCH_ANIMATION, + EAT_ANIMATION, + DONE + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/frog/FrogJumpToRandomPos.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/frog/FrogJumpToRandomPos.java new file mode 100644 index 0000000..d9df1f7 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/frog/FrogJumpToRandomPos.java @@ -0,0 +1,247 @@ +package com.cursedcauldron.wildbackport.common.entities.brain.frog; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.sounds.SoundSource; +import net.minecraft.util.Mth; +import net.minecraft.util.random.WeightedEntry; +import net.minecraft.util.random.WeightedRandom; +import net.minecraft.util.valueproviders.UniformInt; +import net.minecraft.world.entity.EntityDimensions; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.Pose; +import net.minecraft.world.entity.ai.behavior.Behavior; +import net.minecraft.world.entity.ai.behavior.BlockPosTracker; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; +import net.minecraft.world.entity.ai.memory.MemoryStatus; +import net.minecraft.world.entity.ai.navigation.PathNavigation; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.pathfinder.Path; +import net.minecraft.world.level.pathfinder.WalkNodeEvaluator; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +public class FrogJumpToRandomPos extends Behavior { + private static final List ANGLES = Lists.newArrayList(65, 70, 75, 80); + private final UniformInt cooldown; + protected final int yRange; + protected final int xzRange; + protected final float maxRange; + protected List targets = Lists.newArrayList(); + protected Optional lastPos = Optional.empty(); + @Nullable + protected Vec3 lastTarget; + protected int tries; + protected long targetTime; + private final Function landingSound; + private final Predicate landingBlocks; + + public FrogJumpToRandomPos(UniformInt cooldown, int yRange, int xzRange, float range, Function landingSound, Predicate landingBlocks) { + super(ImmutableMap.of(MemoryModuleType.LOOK_TARGET, MemoryStatus.REGISTERED, MemoryModuleType.LONG_JUMP_COOLDOWN_TICKS, MemoryStatus.VALUE_ABSENT, MemoryModuleType.LONG_JUMP_MID_JUMP, MemoryStatus.VALUE_ABSENT), 200); + this.cooldown = cooldown; + this.yRange = yRange; + this.xzRange = xzRange; + this.maxRange = range; + this.landingSound = landingSound; + this.landingBlocks = landingBlocks; + } + + @Override + protected boolean checkExtraStartConditions(ServerLevel level, Mob entity) { + boolean canUse = entity.isOnGround() && !entity.isInWater() && !entity.isInLava() && !level.getBlockState(entity.blockPosition()).is(Blocks.HONEY_BLOCK); + if (!canUse) entity.getBrain().setMemory(MemoryModuleType.LONG_JUMP_COOLDOWN_TICKS, this.cooldown.sample(level.random) / 2); + return canUse; + } + + @Override + protected boolean canStillUse(ServerLevel level, Mob entity, long time) { + boolean canUse = this.lastPos.isPresent() && this.lastPos.get().equals(entity.position()) && this.tries > 0 && !entity.isInWaterOrBubble() && (this.lastTarget != null || !this.targets.isEmpty()); + if (!canUse && entity.getBrain().getMemory(MemoryModuleType.LONG_JUMP_MID_JUMP).isEmpty()) { + entity.getBrain().setMemory(MemoryModuleType.LONG_JUMP_COOLDOWN_TICKS, this.cooldown.sample(level.random) / 2); + entity.getBrain().eraseMemory(MemoryModuleType.LOOK_TARGET); + } + + return canUse; + } + + @Override + protected void start(ServerLevel level, E entity, long time) { + this.lastTarget = null; + this.tries = 20; + this.lastPos = Optional.of(entity.position()); + BlockPos pos = entity.blockPosition(); + int x = pos.getX(); + int y = pos.getY(); + int z = pos.getZ(); + this.targets = BlockPos.betweenClosedStream(x - this.xzRange, y - this.yRange, z - this.xzRange, x + this.xzRange, y + this.yRange, z + this.xzRange).filter(position -> !position.equals(pos)).map(position -> new Target(position.immutable(), Mth.ceil(pos.distSqr(position)))).collect(Collectors.toCollection(Lists::newArrayList)); + } + + @Override + protected void tick(ServerLevel level, E entity, long time) { + if (this.lastTarget != null) { + if (time - this.targetTime >= 40L) { + entity.setYRot(entity.yBodyRot); + entity.setDiscardFriction(true); + double length = this.lastTarget.length(); + double height = length + entity.getJumpBoostPower(); + entity.setDeltaMovement(this.lastTarget.scale(height / length)); + entity.getBrain().setMemory(MemoryModuleType.LONG_JUMP_MID_JUMP, true); + level.playSound(null, entity, this.landingSound.apply(entity), SoundSource.NEUTRAL, 1.0F, 1.0F); + } + } else { + --this.tries; + this.pickTarget(level, entity, time); + } + } + + protected void pickTarget(ServerLevel level, E entity, long time) { + while (true) { + if (!this.targets.isEmpty()) { + Optional jumpTarget = this.jumpTarget(level); + if (jumpTarget.isEmpty()) continue; + + Target target = jumpTarget.get(); + BlockPos pos = target.getPos(); + if (!canLandOn(level, entity, pos)) continue; + + Vec3 center = Vec3.atCenterOf(pos); + Vec3 lastTarget = this.getRammingVelocity(entity, center); + if (lastTarget == null) continue; + + entity.getBrain().setMemory(MemoryModuleType.LOOK_TARGET, new BlockPosTracker(pos)); + PathNavigation navigation = entity.getNavigation(); + Path path = navigation.createPath(pos, 0, 8); + if (path != null && path.canReach()) continue; + + this.lastTarget = lastTarget; + this.targetTime = time; + return; + } + + return; + } + } + + protected Optional jumpTarget(ServerLevel level) { + Optional target = WeightedRandom.getRandomItem(level.random, this.targets); + target.ifPresent(this.targets::remove); + return target; + } + + protected boolean canLandOn(ServerLevel level, E entity, BlockPos pos) { + BlockPos position = entity.blockPosition(); + int x = position.getX(); + int z = position.getZ(); + if (x == pos.getX() && z == pos.getZ()) { + return false; + } else if (!entity.getNavigation().isStableDestination(pos) && !this.landingBlocks.test(level.getBlockState(pos.below()))) { + return false; + } else { + return entity.getPathfindingMalus(WalkNodeEvaluator.getBlockPathTypeStatic(entity.level, pos.mutable())) == 0.0F; + } + } + + @Nullable + protected Vec3 getRammingVelocity(Mob entity, Vec3 pos) { + List angles = Lists.newArrayList(ANGLES); + Collections.shuffle(angles); + + for (int angle : angles) { + Vec3 velocity = this.getRammingVelocity(entity, pos, angle); + if (velocity != null) return velocity; + } + + return null; + } + + @Nullable + private Vec3 getRammingVelocity(Mob entity, Vec3 pos, int angle) { + Vec3 position = entity.position(); + Vec3 scale = new Vec3(pos.x - position.x, 0.0, pos.z - position.z).normalize().scale(0.5D); + pos = pos.subtract(scale); + Vec3 distance = pos.subtract(position); + float maxAngle = (float)angle * (float)Math.PI / 180.0F; + double xzRange = Math.atan2(distance.z, distance.x); + double yRange = distance.subtract(0.0D, distance.y, 0.0D).lengthSqr(); + double yRadius = Math.sqrt(yRange); + double i = Math.sin(2.0F * maxAngle); + double k = Math.pow(Math.cos(maxAngle), 2.0D); + double yMax = Math.sin(maxAngle); + double xzMax = Math.cos(maxAngle); + double zOffset = Math.sin(xzRange); + double xOffset = Math.cos(xzRange); + double jumpHeight = yRange * 0.08 / (yRadius * i - 2.0 * distance.y * k); + if (jumpHeight < 0.0) { + return null; + } else { + double range = Math.sqrt(jumpHeight); + if (range > (double)this.maxRange) { + return null; + } else { + double xzDistance = range * xzMax; + double yDistance = range * yMax; + int radius = Mth.ceil(yRadius / xzDistance) * 2; + double index = 0.0; + Vec3 source = null; + + for (int j = 0; j < radius - 1; ++j) { + index += yRadius / (double)radius; + double x = index * xOffset; + double y = yMax / xzMax * index - Math.pow(index, 2.0) * 0.08 / (2.0 * jumpHeight * Math.pow(xzMax, 2.0)); + double z = index * zOffset; + Vec3 target = new Vec3(position.x + x, position.y + y, position.z + z); + if (source != null && !this.canReach(entity, source, target)) { + return null; + } + + source = target; + } + + return new Vec3(xzDistance * xOffset, yDistance, xzDistance * zOffset).scale(0.95F); + } + } + } + + private boolean canReach(Mob entity, Vec3 source, Vec3 target) { + EntityDimensions dimensions = entity.getDimensions(Pose.LONG_JUMPING); + Vec3 distance = target.subtract(source); + double size = Math.min(dimensions.width, dimensions.height); + int height = Mth.ceil(distance.length() / size); + Vec3 normal = distance.normalize(); + Vec3 vector = source; + for (int i = 0; i < height; ++i) { + vector = i == height - 1 ? target : vector.add(normal.scale(size * (double)0.9F)); + AABB box = dimensions.makeBoundingBox(vector); + if (!entity.level.noCollision(entity, box)) { + return false; + } + } + + return true; + } + + public static class Target extends WeightedEntry.IntrusiveBase { + private final BlockPos pos; + + public Target(BlockPos pos, int weight) { + super(weight); + this.pos = pos; + } + + public BlockPos getPos() { + return this.pos; + } + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/frog/IsInWaterSensor.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/frog/IsInWaterSensor.java new file mode 100644 index 0000000..fdc7975 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/frog/IsInWaterSensor.java @@ -0,0 +1,28 @@ +package com.cursedcauldron.wildbackport.common.entities.brain.frog; + +import com.cursedcauldron.wildbackport.common.registry.entity.WBMemoryModules; +import com.google.common.collect.ImmutableSet; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.Unit; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; +import net.minecraft.world.entity.ai.sensing.Sensor; + +import java.util.Set; + +public class IsInWaterSensor extends Sensor { + + @Override + public Set> requires() { + return ImmutableSet.of(WBMemoryModules.IS_IN_WATER.get()); + } + + @Override + protected void doTick(ServerLevel world, LivingEntity entity) { + if (entity.isInWater()) { + entity.getBrain().setMemory(WBMemoryModules.IS_IN_WATER.get(), Unit.INSTANCE); + } else { + entity.getBrain().eraseMemory(WBMemoryModules.IS_IN_WATER.get()); + } + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/frog/LayFrogSpawnTask.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/frog/LayFrogSpawnTask.java new file mode 100644 index 0000000..47ceed8 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/frog/LayFrogSpawnTask.java @@ -0,0 +1,45 @@ +package com.cursedcauldron.wildbackport.common.entities.brain.frog; + +import com.cursedcauldron.wildbackport.client.registry.WBSoundEvents; +import com.cursedcauldron.wildbackport.common.entities.Frog; +import com.cursedcauldron.wildbackport.common.registry.entity.WBMemoryModules; +import com.google.common.collect.ImmutableMap; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.entity.ai.behavior.Behavior; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; +import net.minecraft.world.entity.ai.memory.MemoryStatus; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; + +public class LayFrogSpawnTask extends Behavior { + private final Block frogSpawn; + private final MemoryModuleType triggerMemory; + + public LayFrogSpawnTask(Block block, MemoryModuleType memoryModuleType) { + super(ImmutableMap.of(MemoryModuleType.ATTACK_TARGET, MemoryStatus.VALUE_ABSENT, MemoryModuleType.WALK_TARGET, MemoryStatus.VALUE_PRESENT, WBMemoryModules.IS_PREGNANT.get(), MemoryStatus.VALUE_PRESENT)); + this.frogSpawn = block; + this.triggerMemory = memoryModuleType; + } + + @Override + protected boolean checkExtraStartConditions(ServerLevel serverWorld, Frog arg) { + return !arg.isInWaterOrBubble() && arg.isOnGround(); + } + + @Override + protected void start(ServerLevel serverWorld, Frog arg, long l) { + BlockPos blockPos = arg.blockPosition().below(); + for (Direction direction : Direction.Plane.HORIZONTAL) { + BlockPos blockPos3; + BlockPos blockPos2 = blockPos.relative(direction); + if (!serverWorld.getBlockState(blockPos2).is(Blocks.WATER) || !serverWorld.getBlockState(blockPos3 = blockPos2.above()).isAir()) continue; + serverWorld.setBlock(blockPos3, this.frogSpawn.defaultBlockState(), 3); + serverWorld.playSound(null, arg, WBSoundEvents.FROG_LAY_SPAWN, SoundSource.BLOCKS, 1.0f, 1.0f); + arg.getBrain().eraseMemory(this.triggerMemory); + return; + } + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/frog/WalkTowardsLand.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/frog/WalkTowardsLand.java new file mode 100644 index 0000000..be8198c --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/frog/WalkTowardsLand.java @@ -0,0 +1,58 @@ +package com.cursedcauldron.wildbackport.common.entities.brain.frog; + +import com.google.common.collect.ImmutableMap; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.tags.FluidTags; +import net.minecraft.world.entity.PathfinderMob; +import net.minecraft.world.entity.ai.behavior.Behavior; +import net.minecraft.world.entity.ai.behavior.BehaviorUtils; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; +import net.minecraft.world.entity.ai.memory.MemoryStatus; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.shapes.CollisionContext; + +public class WalkTowardsLand extends Behavior { + private final int distance; + private final float speedModifier; + private long nextStartTime; + + public WalkTowardsLand(int distance, float speedModifier) { + super(ImmutableMap.of(MemoryModuleType.ATTACK_TARGET, MemoryStatus.VALUE_ABSENT, MemoryModuleType.WALK_TARGET, MemoryStatus.VALUE_ABSENT, MemoryModuleType.LOOK_TARGET, MemoryStatus.REGISTERED)); + this.distance = distance; + this.speedModifier = speedModifier; + } + + @Override + protected void stop(ServerLevel level, PathfinderMob entity, long time) { + this.nextStartTime = time + 60L; + } + + @Override + protected boolean checkExtraStartConditions(ServerLevel level, PathfinderMob entity) { + return entity.level.getFluidState(entity.blockPosition()).is(FluidTags.WATER); + } + + @Override + protected void start(ServerLevel level, PathfinderMob entity, long time) { + if (time >= this.nextStartTime) { + BlockPos pos = entity.blockPosition(); + BlockPos.MutableBlockPos mutable = new BlockPos.MutableBlockPos(); + CollisionContext context = CollisionContext.of(entity); + + for (BlockPos position : BlockPos.withinManhattan(pos, this.distance, this.distance, this.distance)) { + if (position.getX() != pos.getX() || position.getZ() != pos.getZ()) { + BlockState state = level.getBlockState(position); + BlockState landState = level.getBlockState(mutable.setWithOffset(position, Direction.DOWN)); + if (!state.is(Blocks.WATER) && level.getFluidState(position).isEmpty() && state.getCollisionShape(level, position, context).isEmpty() && landState.isFaceSturdy(level, mutable, Direction.UP)) { + this.nextStartTime = time + 60L; + BehaviorUtils.setWalkAndLookTargetMemories(entity, position.immutable(), this.speedModifier, 1); + return; + } + } + } + } + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/frog/WalkTowardsWater.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/frog/WalkTowardsWater.java new file mode 100644 index 0000000..3d7754a --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/frog/WalkTowardsWater.java @@ -0,0 +1,60 @@ +package com.cursedcauldron.wildbackport.common.entities.brain.frog; + +import com.google.common.collect.ImmutableMap; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.tags.FluidTags; +import net.minecraft.world.entity.AgeableMob; +import net.minecraft.world.entity.ai.behavior.Behavior; +import net.minecraft.world.entity.ai.behavior.BehaviorUtils; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; +import net.minecraft.world.entity.ai.memory.MemoryStatus; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.phys.shapes.CollisionContext; + +//<> + +public class WalkTowardsWater extends Behavior { + private final int distance; + private final float speedModifier; + private long nextStartTime; + + public WalkTowardsWater(int distance, float speedModifier) { + super(ImmutableMap.of(MemoryModuleType.ATTACK_TARGET, MemoryStatus.VALUE_ABSENT, MemoryModuleType.WALK_TARGET, MemoryStatus.VALUE_ABSENT, MemoryModuleType.LOOK_TARGET, MemoryStatus.REGISTERED)); + this.distance = distance; + this.speedModifier = speedModifier; + } + + @Override + protected void stop(ServerLevel level, AgeableMob entity, long time) { + this.nextStartTime = time + 40L; + } + + @Override + protected boolean checkExtraStartConditions(ServerLevel level, AgeableMob entity) { + return !entity.level.getFluidState(entity.blockPosition()).is(FluidTags.WATER); + } + + @Override + protected void start(ServerLevel level, AgeableMob entity, long time) { + if (time >= this.nextStartTime) { + CollisionContext context = CollisionContext.of(entity); + BlockPos pos = entity.blockPosition(); + BlockPos.MutableBlockPos mutable = new BlockPos.MutableBlockPos(); + + for (BlockPos position : BlockPos.withinManhattan(pos, this.distance, this.distance, this.distance)) { + if (position.getX() != pos.getX() || position.getZ() != pos.getZ() && level.getBlockState(position).getCollisionShape(level, position, context).isEmpty() && level.getBlockState(mutable.setWithOffset(position, Direction.DOWN)).getCollisionShape(level, position, context).isEmpty()) { + for (Direction direction : Direction.Plane.HORIZONTAL) { + mutable.setWithOffset(position, direction); + if (level.getBlockState(mutable).isAir() && level.getBlockState(mutable.move(Direction.DOWN)).is(Blocks.WATER)) { + this.nextStartTime = time + 40L; + BehaviorUtils.setWalkAndLookTargetMemories(entity, position, this.speedModifier, 0); + return; + } + } + } + } + } + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/Digging.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/Digging.java new file mode 100644 index 0000000..53bfdd2 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/Digging.java @@ -0,0 +1,47 @@ +package com.cursedcauldron.wildbackport.common.entities.brain.warden; + +import com.cursedcauldron.wildbackport.client.registry.WBSoundEvents; +import com.cursedcauldron.wildbackport.common.entities.access.api.Poses; +import com.cursedcauldron.wildbackport.common.entities.Warden; +import com.google.common.collect.ImmutableMap; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.ai.behavior.Behavior; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; +import net.minecraft.world.entity.ai.memory.MemoryStatus; + +//<> + +public class Digging extends Behavior { + public Digging(int duration) { + super(ImmutableMap.of(MemoryModuleType.ATTACK_TARGET, MemoryStatus.VALUE_ABSENT, MemoryModuleType.WALK_TARGET, MemoryStatus.VALUE_ABSENT), duration); + } + + @Override + protected boolean canStillUse(ServerLevel level, E entity, long time) { + return entity.getRemovalReason() == null; + } + + @Override + protected boolean checkExtraStartConditions(ServerLevel level, E entity) { + return entity.isOnGround() || entity.isInWater() || entity.isInLava(); + } + + @Override + protected void start(ServerLevel level, E entity, long time) { + if (entity.isOnGround()) { + entity.setPose(Poses.DIGGING.get()); + entity.playSound(WBSoundEvents.WARDEN_DIG, 5.0F, 1.0F); + } else { + entity.playSound(WBSoundEvents.WARDEN_AGITATED, 5.0F, 1.0F); + this.stop(level, entity, time); + } + } + + @Override + protected void stop(ServerLevel level, E entity, long time) { + if (entity.getRemovalReason() == null) { + entity.remove(Entity.RemovalReason.DISCARDED); + } + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/Dismount.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/Dismount.java new file mode 100644 index 0000000..1c38618 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/Dismount.java @@ -0,0 +1,22 @@ +package com.cursedcauldron.wildbackport.common.entities.brain.warden; + +import com.google.common.collect.ImmutableMap; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.behavior.Behavior; + +public class Dismount extends Behavior { + public Dismount() { + super(ImmutableMap.of()); + } + + @Override + protected boolean checkExtraStartConditions(ServerLevel level, LivingEntity entity) { + return entity.isPassenger(); + } + + @Override + protected void start(ServerLevel level, LivingEntity entity, long time) { + entity.unRide(); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/Emerging.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/Emerging.java new file mode 100644 index 0000000..5aaaf70 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/Emerging.java @@ -0,0 +1,38 @@ +package com.cursedcauldron.wildbackport.common.entities.brain.warden; + +import com.cursedcauldron.wildbackport.client.registry.WBSoundEvents; +import com.cursedcauldron.wildbackport.common.entities.access.api.Poses; +import com.cursedcauldron.wildbackport.common.entities.Warden; +import com.cursedcauldron.wildbackport.common.registry.entity.WBMemoryModules; +import com.google.common.collect.ImmutableMap; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Pose; +import net.minecraft.world.entity.ai.behavior.Behavior; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; +import net.minecraft.world.entity.ai.memory.MemoryStatus; + +//<> + +public class Emerging extends Behavior { + public Emerging(int duration) { + super(ImmutableMap.of(WBMemoryModules.IS_EMERGING.get(), MemoryStatus.VALUE_PRESENT, MemoryModuleType.WALK_TARGET, MemoryStatus.VALUE_ABSENT, MemoryModuleType.LOOK_TARGET, MemoryStatus.REGISTERED), duration); + } + + @Override + protected boolean canStillUse(ServerLevel level, E entity, long time) { + return true; + } + + @Override + protected void start(ServerLevel level, E entity, long time) { + entity.setPose(Poses.EMERGING.get()); + entity.playSound(WBSoundEvents.WARDEN_EMERGE, 5.0F, 1.0F); + } + + @Override + protected void stop(ServerLevel level, E entity, long time) { + if (entity.hasPose(Poses.EMERGING.get())) { + entity.setPose(Pose.STANDING); + } + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/ForgetAttackTargetTask.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/ForgetAttackTargetTask.java new file mode 100644 index 0000000..75b5dc1 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/ForgetAttackTargetTask.java @@ -0,0 +1,65 @@ +package com.cursedcauldron.wildbackport.common.entities.brain.warden; + +import com.google.common.collect.ImmutableMap; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.ai.behavior.Behavior; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; +import net.minecraft.world.entity.ai.memory.MemoryStatus; + +import java.util.Optional; +import java.util.function.BiConsumer; +import java.util.function.Predicate; + +public class ForgetAttackTargetTask extends Behavior { + private final Predicate stopAttackingWhen; + private final BiConsumer onTargetErased; + private final boolean canGrowTiredOfTryingToReachTarget; + + public ForgetAttackTargetTask(Predicate stopAttackingWhen, BiConsumer onTargetEased, boolean canGrowTiredOfTryingToReachTarget) { + super(ImmutableMap.of(MemoryModuleType.ATTACK_TARGET, MemoryStatus.VALUE_PRESENT, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryStatus.REGISTERED)); + this.stopAttackingWhen = stopAttackingWhen; + this.onTargetErased = onTargetEased; + this.canGrowTiredOfTryingToReachTarget = canGrowTiredOfTryingToReachTarget; + } + + @Override + protected void start(ServerLevel level, E entity, long time) { + LivingEntity target = this.getAttackTarget(entity); + if (!entity.canAttack(target)) { + this.clearAttackTarget(entity); + } else if (this.canGrowTiredOfTryingToReachTarget && isTiredOfTryingToReachTarget(entity)) { + this.clearAttackTarget(entity); + } else if (this.isCurrentTargetDeadOrRemoved(entity)) { + this.clearAttackTarget(entity); + } else if (this.isCurrentTargetInDifferentLevel(entity)) { + this.clearAttackTarget(entity); + } else if (this.stopAttackingWhen.test(this.getAttackTarget(entity))) { + this.clearAttackTarget(entity); + } + } + + private boolean isCurrentTargetInDifferentLevel(E entity) { + return this.getAttackTarget(entity).level != entity.level; + } + + private LivingEntity getAttackTarget(E entity) { + return entity.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET).get(); + } + + private static boolean isTiredOfTryingToReachTarget(E entity) { + Optional time = entity.getBrain().getMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE); + return time.isPresent() && entity.level.getGameTime() - time.get() > 200L; + } + + private boolean isCurrentTargetDeadOrRemoved(E entity) { + Optional target = entity.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET); + return target.isPresent() && !target.get().isAlive(); + } + + protected void clearAttackTarget(E entity) { + this.onTargetErased.accept(entity, this.getAttackTarget(entity)); + entity.getBrain().eraseMemory(MemoryModuleType.ATTACK_TARGET); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/GoToTargetLocation.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/GoToTargetLocation.java new file mode 100644 index 0000000..f5994ad --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/GoToTargetLocation.java @@ -0,0 +1,45 @@ +package com.cursedcauldron.wildbackport.common.entities.brain.warden; + +import com.google.common.collect.ImmutableMap; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.ai.behavior.Behavior; +import net.minecraft.world.entity.ai.behavior.BehaviorUtils; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; +import net.minecraft.world.entity.ai.memory.MemoryStatus; + +import java.util.Random; + +public class GoToTargetLocation extends Behavior { + private final MemoryModuleType locationMemory; + private final int closeEnoughDistance; + private final float speedModifier; + + public GoToTargetLocation(MemoryModuleType locationMemory, int closeEnoughDistance, float speedModifier) { + super(ImmutableMap.of(locationMemory, MemoryStatus.VALUE_PRESENT, MemoryModuleType.ATTACK_TARGET, MemoryStatus.VALUE_ABSENT, MemoryModuleType.WALK_TARGET, MemoryStatus.VALUE_ABSENT, MemoryModuleType.LOOK_TARGET, MemoryStatus.REGISTERED)); + this.locationMemory = locationMemory; + this.closeEnoughDistance = closeEnoughDistance; + this.speedModifier = speedModifier; + } + + @Override + protected void start(ServerLevel level, E entity, long time) { + BlockPos pos = this.getTargetLocation(entity); + boolean inRange = pos.closerThan(entity.blockPosition(), this.closeEnoughDistance); + if (!inRange) BehaviorUtils.setWalkAndLookTargetMemories(entity, getNearbyPos(entity, pos), this.speedModifier, this.closeEnoughDistance); + } + + private static BlockPos getNearbyPos(Mob mob, BlockPos pos) { + Random random = mob.level.getRandom(); + return pos.offset(getRandomOffset(random), 0, getRandomOffset(random)); + } + + private static int getRandomOffset(Random random) { + return random.nextInt(3) - 1; + } + + private BlockPos getTargetLocation(Mob mob) { + return mob.getBrain().getMemory(this.locationMemory).get(); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/NearestLivingEntitySensor.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/NearestLivingEntitySensor.java new file mode 100644 index 0000000..522801e --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/NearestLivingEntitySensor.java @@ -0,0 +1,39 @@ +package com.cursedcauldron.wildbackport.common.entities.brain.warden; + +import com.google.common.collect.ImmutableSet; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; +import net.minecraft.world.entity.ai.memory.NearestVisibleLivingEntities; +import net.minecraft.world.entity.ai.sensing.Sensor; +import net.minecraft.world.phys.AABB; + +import java.util.Comparator; +import java.util.List; +import java.util.Set; + +//<> + +public class NearestLivingEntitySensor extends Sensor { + @Override + protected void doTick(ServerLevel level, T entity) { + AABB box = entity.getBoundingBox().inflate(this.radiusXZ(), this.radiusY(), this.radiusXZ()); + List entities = level.getEntitiesOfClass(LivingEntity.class, box, (target) -> target != entity && target.isAlive()); + entities.sort(Comparator.comparingDouble(entity::distanceToSqr)); + entity.getBrain().setMemory(MemoryModuleType.NEAREST_LIVING_ENTITIES, entities); + entity.getBrain().setMemory(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, new NearestVisibleLivingEntities(entity, entities)); + } + + protected int radiusXZ() { + return 16; + } + + protected int radiusY() { + return 16; + } + + @Override + public Set> requires() { + return ImmutableSet.of(MemoryModuleType.NEAREST_LIVING_ENTITIES, MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/Roar.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/Roar.java new file mode 100644 index 0000000..223ab90 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/Roar.java @@ -0,0 +1,53 @@ +package com.cursedcauldron.wildbackport.common.entities.brain.warden; + +import com.cursedcauldron.wildbackport.client.registry.WBSoundEvents; +import com.cursedcauldron.wildbackport.common.entities.access.api.Poses; +import com.cursedcauldron.wildbackport.common.entities.Warden; +import com.cursedcauldron.wildbackport.common.entities.brain.WardenBrain; +import com.cursedcauldron.wildbackport.common.registry.entity.WBMemoryModules; +import com.google.common.collect.ImmutableMap; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.Unit; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.Pose; +import net.minecraft.world.entity.ai.behavior.Behavior; +import net.minecraft.world.entity.ai.behavior.BehaviorUtils; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; +import net.minecraft.world.entity.ai.memory.MemoryStatus; + +public class Roar extends Behavior { + public Roar() { + super(ImmutableMap.of(WBMemoryModules.ROAR_TARGET.get(), MemoryStatus.VALUE_PRESENT, MemoryModuleType.ATTACK_TARGET, MemoryStatus.VALUE_ABSENT, WBMemoryModules.ROAR_SOUND_COOLDOWN.get(), MemoryStatus.REGISTERED, WBMemoryModules.ROAR_SOUND_DELAY.get(), MemoryStatus.REGISTERED), WardenBrain.ROAR_DURATION); + } + + @Override + protected void start(ServerLevel level, Warden warden, long time) { + warden.getBrain().setMemoryWithExpiry(WBMemoryModules.ROAR_SOUND_DELAY.get(), Unit.INSTANCE, 25L); + warden.getBrain().eraseMemory(MemoryModuleType.WALK_TARGET); + LivingEntity entity = warden.getBrain().getMemory(WBMemoryModules.ROAR_TARGET.get()).get(); + BehaviorUtils.lookAtEntity(warden, entity); + warden.setPose(Poses.ROARING.get()); + warden.increaseAngerAt(entity, 20, false); + } + + @Override + protected boolean canStillUse(ServerLevel level, Warden warden, long time) { + return true; + } + + @Override + protected void tick(ServerLevel level, Warden warden, long time) { + if (!warden.getBrain().hasMemoryValue(WBMemoryModules.ROAR_SOUND_DELAY.get()) && !warden.getBrain().hasMemoryValue(WBMemoryModules.ROAR_SOUND_COOLDOWN.get())) { + warden.getBrain().setMemoryWithExpiry(WBMemoryModules.ROAR_SOUND_COOLDOWN.get(), Unit.INSTANCE, WardenBrain.ROAR_DURATION - 25); + warden.playSound(WBSoundEvents.WARDEN_ROAR, 3.0F, 1.0F); + } + } + + @Override + protected void stop(ServerLevel level, Warden warden, long time) { + if (warden.hasPose(Poses.ROARING.get())) warden.setPose(Pose.STANDING); + + warden.getBrain().getMemory(WBMemoryModules.ROAR_TARGET.get()).ifPresent(warden::updateAttackTarget); + warden.getBrain().eraseMemory(WBMemoryModules.ROAR_TARGET.get()); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/SetRoarTarget.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/SetRoarTarget.java new file mode 100644 index 0000000..f00d2c2 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/SetRoarTarget.java @@ -0,0 +1,35 @@ +package com.cursedcauldron.wildbackport.common.entities.brain.warden; + +import com.cursedcauldron.wildbackport.common.entities.Warden; +import com.cursedcauldron.wildbackport.common.registry.entity.WBMemoryModules; +import com.google.common.collect.ImmutableMap; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.behavior.Behavior; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; +import net.minecraft.world.entity.ai.memory.MemoryStatus; + +import java.util.Optional; +import java.util.function.Function; + +public class SetRoarTarget extends Behavior { + private final Function> targetFinder; + + public SetRoarTarget(Function> target) { + super(ImmutableMap.of(WBMemoryModules.ROAR_TARGET.get(), MemoryStatus.VALUE_ABSENT, MemoryModuleType.ATTACK_TARGET, MemoryStatus.VALUE_ABSENT, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryStatus.REGISTERED)); + this.targetFinder = target; + } + + @Override + protected boolean checkExtraStartConditions(ServerLevel level, E entity) { + return this.targetFinder.apply(entity).filter(entity::isValidTarget).isPresent(); + } + + @Override + protected void start(ServerLevel level, E entity, long time) { + this.targetFinder.apply(entity).ifPresent(target -> { + entity.getBrain().setMemory(WBMemoryModules.ROAR_TARGET.get(), target); + entity.getBrain().eraseMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE); + }); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/SetWardenLookTarget.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/SetWardenLookTarget.java new file mode 100644 index 0000000..992d350 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/SetWardenLookTarget.java @@ -0,0 +1,31 @@ +package com.cursedcauldron.wildbackport.common.entities.brain.warden; + +import com.cursedcauldron.wildbackport.common.entities.Warden; +import com.cursedcauldron.wildbackport.common.registry.entity.WBMemoryModules; +import com.google.common.collect.ImmutableMap; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.ai.behavior.Behavior; +import net.minecraft.world.entity.ai.behavior.BlockPosTracker; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; +import net.minecraft.world.entity.ai.memory.MemoryStatus; + +//<> + +public class SetWardenLookTarget extends Behavior { + public SetWardenLookTarget() { + super(ImmutableMap.of(WBMemoryModules.DISTURBANCE_LOCATION.get(), MemoryStatus.REGISTERED, WBMemoryModules.ROAR_TARGET.get(), MemoryStatus.REGISTERED, MemoryModuleType.ATTACK_TARGET, MemoryStatus.VALUE_ABSENT)); + } + + @Override + protected boolean checkExtraStartConditions(ServerLevel level, Warden warden) { + return warden.getBrain().hasMemoryValue(WBMemoryModules.DISTURBANCE_LOCATION.get()) || warden.getBrain().hasMemoryValue(WBMemoryModules.ROAR_TARGET.get()); + } + + @Override + protected void start(ServerLevel level, Warden warden, long time) { + BlockPos pos = warden.getBrain().getMemory(WBMemoryModules.ROAR_TARGET.get()).map(Entity::blockPosition).or(() -> warden.getBrain().getMemory(WBMemoryModules.DISTURBANCE_LOCATION.get())).get(); + warden.getBrain().setMemory(MemoryModuleType.LOOK_TARGET, new BlockPosTracker(pos)); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/Sniffing.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/Sniffing.java new file mode 100644 index 0000000..bd9582f --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/Sniffing.java @@ -0,0 +1,48 @@ +package com.cursedcauldron.wildbackport.common.entities.brain.warden; + +import com.cursedcauldron.wildbackport.client.registry.WBSoundEvents; +import com.cursedcauldron.wildbackport.common.entities.access.api.Poses; +import com.cursedcauldron.wildbackport.common.entities.Warden; +import com.cursedcauldron.wildbackport.common.entities.brain.WardenBrain; +import com.cursedcauldron.wildbackport.common.registry.entity.WBMemoryModules; +import com.cursedcauldron.wildbackport.common.utils.MobUtils; +import com.google.common.collect.ImmutableMap; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Pose; +import net.minecraft.world.entity.ai.behavior.Behavior; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; +import net.minecraft.world.entity.ai.memory.MemoryStatus; + +public class Sniffing extends Behavior { + public Sniffing(int duration) { + super(ImmutableMap.of(WBMemoryModules.IS_SNIFFING.get(), MemoryStatus.VALUE_PRESENT, MemoryModuleType.ATTACK_TARGET, MemoryStatus.VALUE_ABSENT, MemoryModuleType.WALK_TARGET, MemoryStatus.VALUE_ABSENT, MemoryModuleType.LOOK_TARGET, MemoryStatus.REGISTERED, MemoryModuleType.NEAREST_ATTACKABLE, MemoryStatus.REGISTERED, WBMemoryModules.DISTURBANCE_LOCATION.get(), MemoryStatus.REGISTERED, WBMemoryModules.SNIFF_COOLDOWN.get(), MemoryStatus.REGISTERED), duration); + } + + @Override + protected boolean canStillUse(ServerLevel level, E entity, long time) { + return true; + } + + @Override + protected void start(ServerLevel level, E entity, long time) { + entity.playSound(WBSoundEvents.WARDEN_SNIFF, 5.0F, 1.0F); + } + + @Override + protected void stop(ServerLevel level, E entity, long time) { + if (entity.hasPose(Poses.SNIFFING.get())) { + entity.setPose(Pose.STANDING); + } + + entity.getBrain().eraseMemory(WBMemoryModules.IS_SNIFFING.get()); + entity.getBrain().getMemory(MemoryModuleType.NEAREST_ATTACKABLE).filter(entity::isValidTarget).ifPresent(target -> { + if (MobUtils.closerThan(entity, target, 6.0D, 20.0D)) { + entity.increaseAngerAt(target); + } + + if (!entity.getBrain().hasMemoryValue(WBMemoryModules.DISTURBANCE_LOCATION.get())) { + WardenBrain.setDisturbanceLocation(entity, target.blockPosition()); + } + }); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/SonicBoom.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/SonicBoom.java new file mode 100644 index 0000000..15a1afd --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/SonicBoom.java @@ -0,0 +1,87 @@ +package com.cursedcauldron.wildbackport.common.entities.brain.warden; + +import com.cursedcauldron.wildbackport.client.registry.WBParticleTypes; +import com.cursedcauldron.wildbackport.client.registry.WBSoundEvents; +import com.cursedcauldron.wildbackport.common.entities.Warden; +import com.cursedcauldron.wildbackport.common.registry.entity.WBMemoryModules; +import com.cursedcauldron.wildbackport.common.utils.MobUtils; +import com.cursedcauldron.wildbackport.core.mixin.access.DamageSourceAccessor; +import com.google.common.collect.ImmutableMap; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.Mth; +import net.minecraft.util.Unit; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.damagesource.EntityDamageSource; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.ai.behavior.Behavior; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; +import net.minecraft.world.entity.ai.memory.MemoryStatus; +import net.minecraft.world.phys.Vec3; + +//<> + +public class SonicBoom extends Behavior { + private static final int TICKS_BEFORE_PLAYING_SOUND = Mth.ceil(34.0D); + private static final int DURATION = Mth.ceil(60.0F); + + public SonicBoom() { + super(ImmutableMap.of(MemoryModuleType.ATTACK_TARGET, MemoryStatus.VALUE_PRESENT, WBMemoryModules.SONIC_BOOM_COOLDOWN.get(), MemoryStatus.VALUE_ABSENT, WBMemoryModules.SONIC_BOOM_SOUND_COOLDOWN.get(), MemoryStatus.REGISTERED, WBMemoryModules.SONIC_BOOM_SOUND_DELAY.get(), MemoryStatus.REGISTERED), DURATION); + } + + @Override + protected boolean checkExtraStartConditions(ServerLevel level, Warden warden) { + return MobUtils.closerThan(warden, warden.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET).get(), 15.0D, 20.0D); + } + + @Override + protected boolean canStillUse(ServerLevel level, Warden warden, long time) { + return true; + } + + @Override + protected void start(ServerLevel level, Warden warden, long time) { + warden.getBrain().setMemoryWithExpiry(MemoryModuleType.ATTACK_COOLING_DOWN, true, DURATION); + warden.getBrain().setMemoryWithExpiry(WBMemoryModules.SONIC_BOOM_SOUND_DELAY.get(), Unit.INSTANCE, TICKS_BEFORE_PLAYING_SOUND); + level.broadcastEntityEvent(warden, (byte)62); + warden.playSound(WBSoundEvents.WARDEN_SONIC_CHARGE, 3.0F, 1.0F); + } + + @Override + protected void tick(ServerLevel level, Warden warden, long time) { + warden.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET).ifPresent(target -> warden.getLookControl().setLookAt(target.position())); + if (!warden.getBrain().hasMemoryValue(WBMemoryModules.SONIC_BOOM_SOUND_DELAY.get()) && !warden.getBrain().hasMemoryValue(WBMemoryModules.SONIC_BOOM_SOUND_COOLDOWN.get())) { + warden.getBrain().setMemoryWithExpiry(WBMemoryModules.SONIC_BOOM_SOUND_COOLDOWN.get(), Unit.INSTANCE, DURATION - TICKS_BEFORE_PLAYING_SOUND); + warden.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET).filter(warden::isValidTarget).filter(target -> MobUtils.closerThan(warden, target, 15.0D, 20.0D)).ifPresent(target -> { + Vec3 wardenPos = warden.position().add(0.0D, 1.6F, 0.0D); + Vec3 distance = target.getEyePosition().subtract(wardenPos); + Vec3 position = distance.normalize(); + + for (int i = 1; i < Mth.floor(distance.length()) + 7; i++) { + Vec3 rayCharge = wardenPos.add(position.scale(i)); + level.sendParticles(WBParticleTypes.SONIC_BOOM.get(), rayCharge.x, rayCharge.y, rayCharge.z, 1, 0.0D, 0.0D, 0.0D, 0.0D); + } + + warden.playSound(WBSoundEvents.WARDEN_SONIC_BOOM, 3.0F, 1.0F); + target.hurt(sonicBoom(warden), 10.0F); + double yForce = 0.5D * (1.0D - target.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE)); + double xzForce = 2.5D * (1.0D - target.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE)); + target.push(position.x * xzForce, position.y * yForce, position.z * xzForce); + }); + } + } + + @Override + protected void stop(ServerLevel level, Warden warden, long time) { + setCooldown(warden, 40); + } + + public static void setCooldown(LivingEntity entity, int cooldown) { + entity.getBrain().setMemoryWithExpiry(WBMemoryModules.SONIC_BOOM_COOLDOWN.get(), Unit.INSTANCE, cooldown); + } + + public static DamageSource sonicBoom(Entity entity) { + return ((DamageSourceAccessor)new EntityDamageSource("sonic_boom", entity)).callBypassArmor().setMagic(); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/TryToSniff.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/TryToSniff.java new file mode 100644 index 0000000..78c7531 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/TryToSniff.java @@ -0,0 +1,29 @@ +package com.cursedcauldron.wildbackport.common.entities.brain.warden; + +import com.cursedcauldron.wildbackport.common.entities.access.api.Poses; +import com.cursedcauldron.wildbackport.common.entities.Warden; +import com.cursedcauldron.wildbackport.common.registry.entity.WBMemoryModules; +import com.google.common.collect.ImmutableMap; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.Unit; +import net.minecraft.util.valueproviders.IntProvider; +import net.minecraft.util.valueproviders.UniformInt; +import net.minecraft.world.entity.ai.behavior.Behavior; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; +import net.minecraft.world.entity.ai.memory.MemoryStatus; + +public class TryToSniff extends Behavior { + private static final IntProvider SNIFF_COOLDOWN = UniformInt.of(100, 200); + + public TryToSniff() { + super(ImmutableMap.of(WBMemoryModules.SNIFF_COOLDOWN.get(), MemoryStatus.VALUE_ABSENT, MemoryModuleType.NEAREST_ATTACKABLE, MemoryStatus.VALUE_PRESENT, WBMemoryModules.DISTURBANCE_LOCATION.get(), MemoryStatus.VALUE_ABSENT)); + } + + @Override + protected void start(ServerLevel level, Warden warden, long time) { + warden.getBrain().setMemory(WBMemoryModules.IS_SNIFFING.get(), Unit.INSTANCE); + warden.getBrain().setMemoryWithExpiry(WBMemoryModules.SNIFF_COOLDOWN.get(), Unit.INSTANCE, SNIFF_COOLDOWN.sample(level.getRandom())); + warden.getBrain().eraseMemory(MemoryModuleType.WALK_TARGET); + warden.setPose(Poses.SNIFFING.get()); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/WardenEntitySensor.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/WardenEntitySensor.java new file mode 100644 index 0000000..e28e97e --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/warden/WardenEntitySensor.java @@ -0,0 +1,52 @@ +package com.cursedcauldron.wildbackport.common.entities.brain.warden; + +import com.cursedcauldron.wildbackport.common.entities.Warden; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; + +import java.util.Collection; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.function.Predicate; + +public class WardenEntitySensor extends NearestLivingEntitySensor { + @Override + public Set> requires() { + return ImmutableSet.copyOf(Iterables.concat(super.requires(), List.of(MemoryModuleType.NEAREST_ATTACKABLE))); + } + + @Override + protected void doTick(ServerLevel level, Warden warden) { + super.doTick(level, warden); + getClosest(warden, target -> { + return target.getType() == EntityType.PLAYER; + }).or(() -> { + return getClosest(warden, target -> { + return target.getType() != EntityType.PLAYER; + }); + }).ifPresentOrElse(target -> { + warden.getBrain().setMemory(MemoryModuleType.NEAREST_ATTACKABLE, target); + }, () -> { + warden.getBrain().eraseMemory(MemoryModuleType.NEAREST_ATTACKABLE); + }); + } + + private static Optional getClosest(Warden warden, Predicate targetFilter) { + return warden.getBrain().getMemory(MemoryModuleType.NEAREST_LIVING_ENTITIES).stream().flatMap(Collection::stream).filter(warden::isValidTarget).filter(targetFilter).findFirst(); + } + + @Override + protected int radiusXZ() { + return 24; + } + + @Override + protected int radiusY() { + return 24; + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/warden/Angriness.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/warden/Angriness.java new file mode 100644 index 0000000..a6062db --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/warden/Angriness.java @@ -0,0 +1,52 @@ +package com.cursedcauldron.wildbackport.common.entities.warden; + +import com.cursedcauldron.wildbackport.client.registry.WBSoundEvents; +import net.minecraft.Util; +import net.minecraft.sounds.SoundEvent; + +import java.util.Arrays; + +//<> + +public enum Angriness { + CALM(0, WBSoundEvents.WARDEN_AMBIENT, WBSoundEvents.WARDEN_LISTENING), + AGITATED(40, WBSoundEvents.WARDEN_AGITATED, WBSoundEvents.WARDEN_LISTENING_ANGRY), + ANGRY(80, WBSoundEvents.WARDEN_ANGRY, WBSoundEvents.WARDEN_LISTENING_ANGRY); + + private static final Angriness[] VALUES = Util.make(Angriness.values(), values -> Arrays.sort(values, (a, b) -> Integer.compare(b.threshold, a.threshold))); + private final int threshold; + private final SoundEvent sound; + private final SoundEvent listeningSound; + + Angriness(int threshold, SoundEvent sound, SoundEvent listeningSound) { + this.threshold = threshold; + this.sound = sound; + this.listeningSound = listeningSound; + } + + public int getThreshold() { + return this.threshold; + } + + public SoundEvent getSound() { + return this.sound; + } + + public SoundEvent getListeningSound() { + return this.listeningSound; + } + + public static Angriness getForAnger(int anger) { + for (Angriness angriness : VALUES) { + if (anger >= angriness.threshold) { + return angriness; + } + } + + return CALM; + } + + public boolean isAngry() { + return this == ANGRY; + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/warden/MobPositionSource.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/warden/MobPositionSource.java new file mode 100644 index 0000000..fa80bb9 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/warden/MobPositionSource.java @@ -0,0 +1,90 @@ +package com.cursedcauldron.wildbackport.common.entities.warden; + +import com.cursedcauldron.wildbackport.common.registry.WBPositionSources; +import com.mojang.datafixers.util.Either; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.core.BlockPos; +import net.minecraft.core.SerializableUUID; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.gameevent.PositionSource; +import net.minecraft.world.level.gameevent.PositionSourceType; + +import java.util.Optional; +import java.util.UUID; +import java.util.function.Function; + +public class MobPositionSource implements PositionSource { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group((SerializableUUID.CODEC.fieldOf("source_entity")).forGetter(MobPositionSource::getUuid), (Codec.FLOAT.fieldOf("y_offset")).orElse(0.0f).forGetter(entityPositionSource -> entityPositionSource.yOffset)).apply(instance, (uUID, float_) -> new MobPositionSource(Either.right(Either.left(uUID)), float_.floatValue()))); + private Either> source; + final float yOffset; + + public MobPositionSource(Entity entity, float yOffset) { + this(Either.left(entity), yOffset); + } + + public MobPositionSource(Either> sourceEntityId, float yOffset) { + this.source = sourceEntityId; + this.yOffset = yOffset; + } + + @Override + public Optional getPosition(Level world) { + if (this.source.left().isEmpty()) { + this.findEntityInWorld(world); + } + return this.source.left().map(entity -> entity.blockPosition().offset(0.0, this.yOffset, 0.0)); + } + + private void findEntityInWorld(Level world) { + this.source.map(Optional::of, either -> Optional.ofNullable(either.map(uuid -> { + Entity entity; + if (world instanceof ServerLevel serverLevel) { + entity = serverLevel.getEntity(uuid); + } else { + entity = null; + } + return entity; + }, world::getEntity))).ifPresent(entity -> { + this.source = Either.left(entity); + }); + } + + @Override + public PositionSourceType getType() { + return WBPositionSources.MOB.get(); + } + + private UUID getUuid() { + return this.source.map(Entity::getUUID, either -> either.map(Function.identity(), integer -> { + throw new RuntimeException("Unable to get entityId from uuid"); + })); + } + + int getEntityId() { + return this.source.map(Entity::getId, either -> either.map(uUID -> { + throw new IllegalStateException("Unable to get entityId from uuid"); + }, Function.identity())); + } + + public static class Type implements PositionSourceType { + @Override + public MobPositionSource read(FriendlyByteBuf buf) { + return new MobPositionSource(Either.right(Either.right(buf.readVarInt())), buf.readFloat()); + } + + @Override + public void write(FriendlyByteBuf buf, MobPositionSource source) { + buf.writeVarInt(source.getEntityId()); + buf.writeFloat(source.yOffset); + } + + @Override + public Codec codec() { + return CODEC; + } + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/warden/VibrationListenerSource.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/warden/VibrationListenerSource.java new file mode 100644 index 0000000..347924d --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/warden/VibrationListenerSource.java @@ -0,0 +1,226 @@ +package com.cursedcauldron.wildbackport.common.entities.warden; + +import com.cursedcauldron.wildbackport.client.registry.WBCriteriaTriggers; +import com.cursedcauldron.wildbackport.common.utils.PositionUtils; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Registry; +import net.minecraft.core.SerializableUUID; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.tags.BlockTags; +import net.minecraft.tags.GameEventTags; +import net.minecraft.tags.TagKey; +import net.minecraft.util.ExtraCodecs; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.projectile.Projectile; +import net.minecraft.world.level.ClipBlockStateContext; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.gameevent.GameEvent; +import net.minecraft.world.level.gameevent.GameEventListener; +import net.minecraft.world.level.gameevent.PositionSource; +import net.minecraft.world.level.gameevent.vibrations.VibrationPath; +import net.minecraft.world.phys.HitResult; +import net.minecraft.world.phys.Vec3; +import org.jetbrains.annotations.Nullable; + +import java.util.Optional; +import java.util.UUID; + +//<> + +public class VibrationListenerSource implements GameEventListener { + protected final PositionSource source; + protected final int range; + protected final VibrationConfig config; + @Nullable protected Vibration event; + protected float distance; + protected int delay; + + public static Codec codec(VibrationConfig config) { + return RecordCodecBuilder.create(instance -> { + return instance.group(PositionSource.CODEC.fieldOf("source").forGetter(listener -> { + return listener.source; + }), ExtraCodecs.NON_NEGATIVE_INT.fieldOf("range").forGetter(listener -> { + return listener.range; + }), Vibration.CODEC.optionalFieldOf("event").forGetter(listener -> { + return Optional.ofNullable(listener.event); + }), Codec.floatRange(0.0F, Float.MAX_VALUE).fieldOf("event_distance").orElse(0.0F).forGetter(listener -> { + return listener.distance; + }), ExtraCodecs.NON_NEGATIVE_INT.fieldOf("event_delay").orElse(0).forGetter(listener -> { + return listener.delay; + })).apply(instance, (source, range, event, distance, delay) -> { + return new VibrationListenerSource(source, range, config, event.orElse(null), distance, delay); + }); + }); + } + + public VibrationListenerSource(PositionSource source, int range, VibrationConfig config, @Nullable Vibration event, float distance, int delay) { + this.source = source; + this.range = range; + this.config = config; + this.event = event; + this.distance = distance; + this.delay = delay; + } + + public void tick(Level level) { + if (level instanceof ServerLevel server) { + if (this.event != null) { + --this.delay; + if (this.delay <= 0) { + this.delay = 0; + this.config.onSignalReceive(server, this, new BlockPos(this.event.pos), this.event.event, this.event.getEntity(server).orElse(null), this.event.getProjectileOwner(server).orElse(null), this.distance); + this.event = null; + } + } + } + } + + @Override + public PositionSource getListenerSource() { + return this.source; + } + + @Override + public int getListenerRadius() { + return this.range; + } + + @Override + public boolean handleGameEvent(Level level, GameEvent event, @Nullable Entity entity, BlockPos pos) { + if (this.event != null) { + return false; + } else { + Optional optional = this.source.getPosition(level); + if (!this.config.isValidVibration(event, entity)) { + return false; + } else { + Vec3 source = PositionUtils.toVec(pos); + Vec3 target = PositionUtils.toVec(optional.get()); + if (!this.config.shouldListen((ServerLevel)level, this, new BlockPos(source), event, entity)) { + return false; + } else if (isOccluded(level, source, target)) { + return false; + } else { + this.scheduleSignal(level, event, entity, source, target); + return true; + } + } + } + } + + private void scheduleSignal(Level level, GameEvent event, @Nullable Entity entity, Vec3 source, Vec3 target) { + this.distance = (float)source.distanceTo(target); + this.event = new Vibration(event, this.distance, source, entity); + this.delay = Mth.floor(this.distance); + ((ServerLevel)level).sendVibrationParticle(new VibrationPath(PositionUtils.toBlockPos(source), this.source, this.delay)); + this.config.onSignalSchedule(); + } + + private static boolean isOccluded(Level level, Vec3 source, Vec3 target) { + Vec3 sourceVec = new Vec3((double)Mth.floor(source.x) + 0.5D, (double)Mth.floor(source.y) + 0.5D, (double)Mth.floor(source.z) + 0.5D); + Vec3 targetVec = new Vec3((double)Mth.floor(target.x) + 0.5D, (double)Mth.floor(target.y) + 0.5D, (double)Mth.floor(target.z) + 0.5D); + + for (Direction direction : Direction.values()) { + Vec3 offsetVec = PositionUtils.relative(sourceVec, direction, 1.0E-5F); + if (level.isBlockInLine(new ClipBlockStateContext(offsetVec, targetVec, state -> { + return state.is(BlockTags.OCCLUDES_VIBRATION_SIGNALS); + })).getType() != HitResult.Type.BLOCK) { + return false; + } + } + + return true; + } + + public record Vibration(GameEvent event, float distance, Vec3 pos, @Nullable UUID source, @Nullable UUID projectileOwner, @Nullable Entity entity) { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> { + return instance.group(Registry.GAME_EVENT.byNameCodec().fieldOf("game_event").forGetter(Vibration::event), Codec.floatRange(0.0F, Float.MAX_VALUE).fieldOf("distance").forGetter(Vibration::distance), PositionUtils.VEC_CODEC.fieldOf("pos").forGetter(Vibration::pos), SerializableUUID.CODEC.optionalFieldOf("source").forGetter(entity -> { + return Optional.ofNullable(entity.source()); + }), SerializableUUID.CODEC.optionalFieldOf("projectile_owner").forGetter(entity -> { + return Optional.ofNullable(entity.projectileOwner()); + })).apply(instance, (event, distance, pos, source, projectileOwner) -> { + return new Vibration(event, distance, pos, source.orElse(null), projectileOwner.orElse(null)); + }); + }); + + public Vibration(GameEvent event, float distance, Vec3 pos, @Nullable UUID source, @Nullable UUID projectileOwner) { + this(event, distance, pos, source, projectileOwner, null); + } + + public Vibration(GameEvent event, float distance, Vec3 pos, @Nullable Entity entity) { + this(event, distance, pos, entity == null ? null : entity.getUUID(), getProjectileOwner(entity), entity); + } + + @Nullable + private static UUID getProjectileOwner(@Nullable Entity entity) { + if (entity instanceof Projectile projectile) { + if (projectile.getOwner() != null) { + return projectile.getOwner().getUUID(); + } + } + + return null; + } + + public Optional getEntity(ServerLevel level) { + return Optional.ofNullable(this.entity).or(() -> { + return Optional.ofNullable(this.source).map(level::getEntity); + }); + } + + public Optional getProjectileOwner(ServerLevel level) { + return this.getEntity(level).filter(entity -> { + return entity instanceof Projectile; + }).map(entity -> { + return (Projectile)entity; + }).map(Projectile::getOwner).or(() -> { + return Optional.ofNullable(this.projectileOwner).map(level::getEntity); + }); + } + } + + public interface VibrationConfig { + default TagKey getListenableEvents() { + return GameEventTags.VIBRATIONS; + } + + default boolean canTriggerAvoidVibration() { + return false; + } + + default boolean isValidVibration(GameEvent event, @Nullable Entity entity) { + if (!event.is(this.getListenableEvents())) { + return false; + } else { + if (entity != null) { + if (entity.isSpectator()) { + return false; + } + + if (entity.isSteppingCarefully() && event.is(GameEventTags.IGNORE_VIBRATIONS_SNEAKING)) { + if (this.canTriggerAvoidVibration() && entity instanceof ServerPlayer player) { + WBCriteriaTriggers.AVOID_VIBRATION.trigger(player); + } + + return false; + } + + return !entity.occludesVibrations(); + } + + return true; + } + } + + boolean shouldListen(ServerLevel level, GameEventListener listener, BlockPos pos, GameEvent event, @Nullable Entity entity); + + void onSignalReceive(ServerLevel level, GameEventListener listener, BlockPos pos, GameEvent event, @Nullable Entity entity, @Nullable Entity source, float distance); + + default void onSignalSchedule() {} + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/warden/WardenAngerManager.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/warden/WardenAngerManager.java new file mode 100644 index 0000000..5b5119e --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/warden/WardenAngerManager.java @@ -0,0 +1,165 @@ +package com.cursedcauldron.wildbackport.common.entities.warden; + +import com.google.common.collect.Streams; +import com.mojang.datafixers.util.Pair; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import net.minecraft.core.SerializableUUID; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.ExtraCodecs; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.Optional; +import java.util.Random; +import java.util.UUID; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +//<> + +public class WardenAngerManager { + private int updateTimer = Mth.randomBetweenInclusive(new Random(System.nanoTime()), 0, 2); + private static final Codec> SUSPECT_CODEC = RecordCodecBuilder.create(instance -> instance.group(SerializableUUID.CODEC.fieldOf("uuid").forGetter(Pair::getFirst), ExtraCodecs.NON_NEGATIVE_INT.fieldOf("anger").forGetter(Pair::getSecond)).apply(instance, Pair::of)); + private final Predicate validTarget; + protected final ArrayList suspects; + private final SuspectComparator suspectComparator; + protected final Object2IntMap suspectsToAngerLevel; + protected final Object2IntMap suspectUuidsToAngerLevel; + + public static Codec createCodec(Predicate validTarget) { + return RecordCodecBuilder.create(instance -> instance.group(SUSPECT_CODEC.listOf().fieldOf("suspects").orElse(Collections.emptyList()).forGetter(WardenAngerManager::getSuspects)).apply(instance, suspects -> new WardenAngerManager(validTarget, suspects))); + } + + public WardenAngerManager(Predicate validTarget, List> suspects) { + this.validTarget = validTarget; + this.suspects = new ArrayList<>(); + this.suspectComparator = new SuspectComparator(this); + this.suspectsToAngerLevel = new Object2IntOpenHashMap<>(); + this.suspectUuidsToAngerLevel = new Object2IntOpenHashMap<>(suspects.size()); + suspects.forEach(pair -> this.suspectUuidsToAngerLevel.put(pair.getFirst(), pair.getSecond())); + } + + private List> getSuspects() { + return Streams.concat(this.suspects.stream().map(suspect -> Pair.of(suspect.getUUID(), this.suspectsToAngerLevel.getInt(suspect))), this.suspectUuidsToAngerLevel.object2IntEntrySet().stream().map(entry -> Pair.of(entry.getKey(), entry.getIntValue()))).collect(Collectors.toList()); + } + + public void tick(ServerLevel world, Predicate suspectPredicate) { + --this.updateTimer; + if (this.updateTimer <= 0) { + this.updateSuspectsMap(world); + this.updateTimer = 2; + } + + Iterator> uuidAngerLevels = this.suspectUuidsToAngerLevel.object2IntEntrySet().iterator(); + while (uuidAngerLevels.hasNext()) { + Object2IntMap.Entry entry = uuidAngerLevels.next(); + int level = entry.getIntValue(); + if (level <= 1) { + uuidAngerLevels.remove(); + } else { + entry.setValue(level - 1); + } + } + + Iterator> angerLevels = this.suspectsToAngerLevel.object2IntEntrySet().iterator(); + while (angerLevels.hasNext()) { + Object2IntMap.Entry entry = angerLevels.next(); + int level = entry.getIntValue(); + Entity entity = entry.getKey(); + Entity.RemovalReason reason = entity.getRemovalReason(); + if (level > 1 && suspectPredicate.test(entity) && reason == null) { + entry.setValue(level - 1); + } else { + this.suspects.remove(entity); + angerLevels.remove(); + if (level > 1 && reason != null) { + switch (reason) { + case CHANGED_DIMENSION, UNLOADED_TO_CHUNK, UNLOADED_WITH_PLAYER -> this.suspectUuidsToAngerLevel.put(entity.getUUID(), level - 1); + } + } + } + } + + this.suspects.sort(this.suspectComparator); + } + + private void updateSuspectsMap(ServerLevel world) { + Iterator> angerLevels = this.suspectUuidsToAngerLevel.object2IntEntrySet().iterator(); + + while (angerLevels.hasNext()) { + Object2IntMap.Entry entry = angerLevels.next(); + int level = entry.getIntValue(); + Entity entity = world.getEntity(entry.getKey()); + if (entity != null) { + this.suspectsToAngerLevel.put(entity, level); + this.suspects.add(entity); + angerLevels.remove(); + } + } + + this.suspects.sort(this.suspectComparator); + } + + public int increaseAngerAt(Entity entity, int amount) { + boolean canAffectAnger = !this.suspectsToAngerLevel.containsKey(entity); + int angerValue = this.suspectsToAngerLevel.computeInt(entity, (suspect, anger) -> Math.min(150, (anger == null ? 0 : anger) + amount)); + if (canAffectAnger) { + int anger = this.suspectUuidsToAngerLevel.removeInt(entity.getUUID()); + this.suspectsToAngerLevel.put(entity, angerValue += anger); + this.suspects.add(entity); + } + + this.suspects.sort(this.suspectComparator); + return angerValue; + } + + public void removeSuspect(Entity entity) { + this.suspectsToAngerLevel.removeInt(entity); + this.suspects.remove(entity); + } + + @Nullable + private Entity getSuspect() { + return this.suspects.stream().filter(this.validTarget).findFirst().orElse(null); + } + + public int getPrimeSuspectAnger() { + return this.suspectsToAngerLevel.getInt(this.getSuspect()); + } + + public Optional getPrimeSuspect() { + return Optional.ofNullable(this.getSuspect()).filter(suspect -> suspect instanceof LivingEntity).map(suspect -> (LivingEntity)suspect); + } + + protected record SuspectComparator(WardenAngerManager angerManagement) implements Comparator { + @Override + public int compare(Entity first, Entity second) { + if (first.equals(second)) { + return 0; + } else { + int firstAngerLevel = this.angerManagement.suspectsToAngerLevel.getOrDefault(first, 0); + int secondAngerLevel = this.angerManagement.suspectsToAngerLevel.getOrDefault(second, 0); + boolean angryTowardsFirst = Angriness.getForAnger(firstAngerLevel).isAngry(); + boolean angryTowardsSecond = Angriness.getForAnger(secondAngerLevel).isAngry(); + if (angryTowardsFirst != angryTowardsSecond) { + return angryTowardsFirst ? -1 : 1; + } else if (angryTowardsFirst && first instanceof Player != second instanceof Player) { + return first instanceof Player ? -1 : 1; + } else { + return firstAngerLevel > secondAngerLevel ? -1 : 1; + } + } + } + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/warden/WardenSpawnHelper.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/warden/WardenSpawnHelper.java new file mode 100644 index 0000000..b865caa --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/warden/WardenSpawnHelper.java @@ -0,0 +1,61 @@ +package com.cursedcauldron.wildbackport.common.entities.warden; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.MobSpawnType; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; + +import java.util.Optional; + +public class WardenSpawnHelper { + public static Optional trySpawnMob(EntityType type, MobSpawnType spawnType, ServerLevel level, BlockPos pos, int tries, int xzRange, int yRange) { + BlockPos.MutableBlockPos mutable = pos.mutable(); + + for(int i = 0; i < tries; ++i) { + int x = Mth.randomBetweenInclusive(level.random, -xzRange, xzRange); + int z = Mth.randomBetweenInclusive(level.random, -xzRange, xzRange); + mutable.setWithOffset(pos, x, yRange, z); + if (level.getWorldBorder().isWithinBounds(mutable) && moveToPossibleSpawnPosition(level, yRange, mutable)) { + T mob = type.create(level, null, null, null, mutable, spawnType, false, false); + if (mob != null) { + if (mob.checkSpawnRules(level, spawnType) && mob.checkSpawnObstruction(level)) { + level.addFreshEntityWithPassengers(mob); + return Optional.of(mob); + } + + mob.discard(); + } + } + } + + return Optional.empty(); + } + + private static boolean moveToPossibleSpawnPosition(ServerLevel level, int yRange, BlockPos.MutableBlockPos pos) { + BlockPos.MutableBlockPos toPos = (new BlockPos.MutableBlockPos()).set(pos); + BlockState toState = level.getBlockState(toPos); + + for(int i = yRange; i >= -yRange; --i) { + pos.move(Direction.DOWN); + toPos.setWithOffset(pos, Direction.UP); + BlockState state = level.getBlockState(pos); + if (canSpawnOn(level, pos, state, toPos, toState)) { + pos.move(Direction.UP); + return true; + } + + toState = state; + } + + return false; + } + + public static boolean canSpawnOn(ServerLevel level, BlockPos pos, BlockState state, BlockPos toPos, BlockState toState) { + return toState.getCollisionShape(level, toPos).isEmpty() && Block.isFaceFull(state.getCollisionShape(level, pos), Direction.UP); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/warden/WardenSpawnTracker.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/warden/WardenSpawnTracker.java new file mode 100644 index 0000000..0d3d7df --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/warden/WardenSpawnTracker.java @@ -0,0 +1,141 @@ +package com.cursedcauldron.wildbackport.common.entities.warden; + +import com.cursedcauldron.wildbackport.common.entities.Warden; +import com.cursedcauldron.wildbackport.common.entities.access.WardenTracker; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.util.ExtraCodecs; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.EntitySelector; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; + +import java.util.Comparator; +import java.util.List; +import java.util.Optional; +import java.util.OptionalInt; +import java.util.function.Predicate; + +//<> + +public class WardenSpawnTracker { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> { + return instance.group(ExtraCodecs.NON_NEGATIVE_INT.fieldOf("ticks_since_last_warning").orElse(0).forGetter(tracker -> { + return tracker.ticksSinceLastWarning; + }), ExtraCodecs.NON_NEGATIVE_INT.fieldOf("warning_level").orElse(0).forGetter(tracker -> { + return tracker.warningLevel; + }), ExtraCodecs.NON_NEGATIVE_INT.fieldOf("cooldown_ticks").orElse(0).forGetter(tracker -> { + return tracker.cooldownTicks; + })).apply(instance, WardenSpawnTracker::new); + }); + + private int ticksSinceLastWarning; + private int warningLevel; + private int cooldownTicks; + + public WardenSpawnTracker(int ticksSinceLastWarning, int warningLevel, int cooldownTicks) { + this.ticksSinceLastWarning = ticksSinceLastWarning; + this.warningLevel = warningLevel; + this.cooldownTicks = cooldownTicks; + } + + public void tick() { + if (this.ticksSinceLastWarning >= 12000) { + this.decreaseWarningCount(); + this.ticksSinceLastWarning = 0; + } else { + ++this.ticksSinceLastWarning; + } + + if (this.cooldownTicks > 0) { + --this.cooldownTicks; + } + } + + public void reset() { + this.ticksSinceLastWarning = 0; + this.warningLevel = 0; + this.cooldownTicks = 0; + } + + private boolean onCooldown() { + return this.cooldownTicks > 0; + } + + public static OptionalInt tryWarn(ServerLevel level, BlockPos pos, ServerPlayer player) { + if (!hasNearbyWarden(level, pos)) { + List players = getNearbyPlayers(level, pos); + if (!players.contains(player)) { + players.add(player); + } + + if (players.stream().anyMatch(playerIn -> ((WardenTracker)playerIn).getWardenSpawnTracker().onCooldown())) { + return OptionalInt.empty(); + } + + Optional optional = players.stream().map(WardenTracker::getWardenSpawnTracker).max(Comparator.comparingInt(tracker -> tracker.warningLevel)); + WardenSpawnTracker tracker = optional.get(); + tracker.increaseWarningLevel(); + players.forEach(playerIn -> ((WardenTracker)playerIn).getWardenSpawnTracker().copyData(tracker)); + return OptionalInt.of(tracker.warningLevel); + } else { + return OptionalInt.empty(); + } + } + + private static boolean hasNearbyWarden(ServerLevel level, BlockPos pos) { + AABB box = AABB.ofSize(Vec3.atCenterOf(pos), 48.0D, 48.0D, 48.0D); + return !level.getEntitiesOfClass(Warden.class, box).isEmpty(); + } + + private static List getNearbyPlayers(ServerLevel level, BlockPos pos) { + Vec3 center = Vec3.atCenterOf(pos); + Predicate predicate = player -> player.position().closerThan(center, 16.0D); + return level.getPlayers(predicate.and(LivingEntity::isAlive).and(EntitySelector.NO_SPECTATORS)); + } + + private void increaseWarningLevel() { + if (!this.onCooldown()) { + this.ticksSinceLastWarning = 0; + this.cooldownTicks = 200; + this.setWarningLevel(this.getWarningLevel() + 1); + } + } + + private void decreaseWarningCount() { + this.setWarningLevel(this.getWarningLevel() - 1); + } + + public void setWarningLevel(int warningLevel) { + this.warningLevel = Mth.clamp(warningLevel, 0, 4); + } + + public int getWarningLevel() { + return this.warningLevel; + } + + private void copyData(WardenSpawnTracker tracker) { + this.ticksSinceLastWarning = tracker.ticksSinceLastWarning; + this.warningLevel = tracker.warningLevel; + this.cooldownTicks = tracker.cooldownTicks; + } + + public void readTag(CompoundTag tag) { + if (tag.contains("ticksSinceLastWarning", 99)) { + this.ticksSinceLastWarning = tag.getInt("ticksSinceLastWarning"); + this.warningLevel = tag.getInt("warningCount"); + this.cooldownTicks = tag.getInt("shriekerCooldownTicks"); + } + } + + public void writeTag(CompoundTag tag) { + tag.putInt("ticksSinceLastWarning", this.ticksSinceLastWarning); + tag.putInt("warningCount", this.warningLevel); + tag.putInt("shriekerCooldownTicks", this.cooldownTicks); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/events/StructureEvent.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/events/StructureEvent.java new file mode 100644 index 0000000..2d31f73 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/events/StructureEvent.java @@ -0,0 +1,47 @@ +package com.cursedcauldron.wildbackport.common.events; + +import com.cursedcauldron.wildbackport.core.mixin.access.StructureTemplatePoolAccessor; +import com.mojang.datafixers.util.Pair; +import net.minecraft.core.Holder; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.levelgen.structure.pools.SinglePoolElement; +import net.minecraft.world.level.levelgen.structure.pools.StructurePoolElement; +import net.minecraft.world.level.levelgen.structure.pools.StructureTemplatePool; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessorList; + +import java.util.ArrayList; +import java.util.List; + +//<> + +public class StructureEvent { + private static final ResourceKey EMPTY_PROCESSOR_LIST_KEY = ResourceKey.create(Registry.PROCESSOR_LIST_REGISTRY, new ResourceLocation("minecraft", "empty")); + + private static void addBuildingToPool(Registry templatePoolRegistry, + Registry processorListRegistry, + ResourceLocation poolRL, + String nbtPieceRL, + int weight) { + Holder emptyProcessorList = processorListRegistry.getHolderOrThrow(EMPTY_PROCESSOR_LIST_KEY); + StructureTemplatePool pool = templatePoolRegistry.get(poolRL); + if (pool == null) return; + + SinglePoolElement piece = SinglePoolElement.legacy(nbtPieceRL, emptyProcessorList).apply(StructureTemplatePool.Projection.RIGID); + + StructureTemplatePoolAccessor pools = (StructureTemplatePoolAccessor)pool; + for (int i = 0; i < weight; i++) pools.getTemplates().add(piece); + + List> listOfPieceEntries = new ArrayList<>(pools.getRawTemplates()); + listOfPieceEntries.add(new Pair<>(piece, weight)); + pools.setRawTemplates(listOfPieceEntries); + } + + public static void bootstrap() { +// Registry templatePoolRegistry = server.registryAccess().registry(Registry.TEMPLATE_POOL_REGISTRY).orElseThrow(); +// Registry processorListRegistry = server.registryAccess().registry(Registry.PROCESSOR_LIST_REGISTRY).orElseThrow(); +// +// addBuildingToPool(templatePoolRegistry, processorListRegistry, new ResourceLocation("minecraft:pillager_outpost/features"), "wildbackport:feature_cage_with_allays", 1); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/items/ChestBoatItem.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/items/ChestBoatItem.java new file mode 100644 index 0000000..76b32fc --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/items/ChestBoatItem.java @@ -0,0 +1,84 @@ +package com.cursedcauldron.wildbackport.common.items; + +import com.cursedcauldron.wildbackport.common.entities.ChestBoat; +import com.cursedcauldron.wildbackport.common.entities.MangroveBoat; +import net.minecraft.core.BlockPos; +import net.minecraft.stats.Stats; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResultHolder; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntitySelector; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.vehicle.Boat; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.ClipContext; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.gameevent.GameEvent; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.HitResult; +import net.minecraft.world.phys.Vec3; + +import java.util.List; +import java.util.function.Predicate; + +//<> + +public class ChestBoatItem extends Item { + private static final Predicate RIDERS = EntitySelector.NO_SPECTATORS.and(Entity::isPickable); + private final Boat.Type type; + private final boolean chested; + + public ChestBoatItem(boolean chested, Boat.Type type, Properties properties) { + super(properties); + this.chested = chested; + this.type = type; + } + + @Override + public InteractionResultHolder use(Level level, Player player, InteractionHand hand) { + ItemStack stack = player.getItemInHand(hand); + HitResult hitResult = getPlayerPOVHitResult(level, player, ClipContext.Fluid.ANY); + if (hitResult.getType() == HitResult.Type.MISS) { + return InteractionResultHolder.pass(stack); + } else { + Vec3 viewVector = player.getViewVector(1.0F); + List entities = level.getEntities(player, player.getBoundingBox().expandTowards(viewVector.scale(5.0D)).inflate(1.0D), RIDERS); + if (!entities.isEmpty()) { + Vec3 eyePosition = player.getEyePosition(); + for (Entity entity : entities) { + AABB box = entity.getBoundingBox().inflate(entity.getPickRadius()); + if (box.contains(eyePosition)) return InteractionResultHolder.pass(stack); + } + } + + if (hitResult.getType() == HitResult.Type.BLOCK) { + MangroveBoat boat = this.create(level, hitResult.getLocation()); + boat.setType(this.type); + boat.setYRot(player.getYRot()); + if (!level.noCollision(boat, boat.getBoundingBox())) { + return InteractionResultHolder.fail(stack); + } else { + if (!level.isClientSide) { + level.addFreshEntity(boat); + level.gameEvent(player, GameEvent.ENTITY_PLACE, new BlockPos(hitResult.getLocation())); + if (!player.getAbilities().instabuild) stack.shrink(1); + } + + player.awardStat(Stats.ITEM_USED.get(this)); + return InteractionResultHolder.sidedSuccess(stack, level.isClientSide); + } + } else { + return InteractionResultHolder.pass(stack); + } + } + } + + public MangroveBoat create(Level level, Vec3 pos) { + if (this.chested) { + return new ChestBoat(level, pos.x, pos.y, pos.z); + } else { + return new MangroveBoat(level, pos.x, pos.y, pos.z); + } + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/items/DiscFragmentItem.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/items/DiscFragmentItem.java new file mode 100644 index 0000000..f417f6d --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/items/DiscFragmentItem.java @@ -0,0 +1,23 @@ +package com.cursedcauldron.wildbackport.common.items; + +import net.minecraft.ChatFormatting; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.TranslatableComponent; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.level.Level; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class DiscFragmentItem extends Item { + public DiscFragmentItem(Properties properties) { + super(properties); + } + + @Override + public void appendHoverText(ItemStack stack, @Nullable Level level, List components, TooltipFlag tooltip) { + components.add(new TranslatableComponent(this.getDescriptionId() + ".desc").withStyle(ChatFormatting.GRAY)); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/items/TadpoleBucketItem.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/items/TadpoleBucketItem.java new file mode 100644 index 0000000..608685b --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/items/TadpoleBucketItem.java @@ -0,0 +1,89 @@ +package com.cursedcauldron.wildbackport.common.items; + +import net.minecraft.ChatFormatting; +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.network.chat.TranslatableComponent; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.MobSpawnType; +import net.minecraft.world.entity.animal.Bucketable; +import net.minecraft.world.entity.animal.TropicalFish; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.BucketItem; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.gameevent.GameEvent; +import net.minecraft.world.level.material.Fluid; + +import javax.annotation.Nullable; +import java.util.List; +import java.util.function.Supplier; + +//<> + +public class TadpoleBucketItem extends BucketItem { + private final Supplier> entityTypeSupplier; + private final Supplier emptySoundSupplier; + + public TadpoleBucketItem(Supplier> type, Fluid fluid, Supplier sound, Item.Properties properties) { + super(fluid, properties); + this.emptySoundSupplier = sound; + this.entityTypeSupplier = type; + } + + public void checkExtraContent(@Nullable Player player, Level level, ItemStack stack, BlockPos pos) { + if (level instanceof ServerLevel server) { + this.spawn(server, stack, pos); + level.gameEvent(player, GameEvent.ENTITY_PLACE, pos); + } + } + + protected void playEmptySound(@Nullable Player player, LevelAccessor access, BlockPos pos) { + access.playSound(player, pos, this.emptySoundSupplier.get(), SoundSource.NEUTRAL, 1.0F, 1.0F); + } + + private void spawn(ServerLevel level, ItemStack stack, BlockPos pos) { + Entity entity = this.entityTypeSupplier.get().spawn(level, stack, null, pos, MobSpawnType.BUCKET, true, false); + if (entity instanceof Bucketable bucketable) { + bucketable.loadFromBucketTag(stack.getOrCreateTag()); + bucketable.setFromBucket(true); + } + } + + public void appendHoverText(ItemStack stack, @Nullable Level level, List components, TooltipFlag tooltip) { + if (this.entityTypeSupplier.get() == EntityType.TROPICAL_FISH) { + CompoundTag tag = stack.getTag(); + if (tag != null && tag.contains("BucketVariantTag", 3)) { + int variant = tag.getInt("BucketVariantTag"); + ChatFormatting[] format = new ChatFormatting[]{ChatFormatting.ITALIC, ChatFormatting.GRAY}; + String base = "color.minecraft." + TropicalFish.getBaseColor(variant); + String pattern = "color.minecraft." + TropicalFish.getPatternColor(variant); + + for(int i = 0; i < TropicalFish.COMMON_VARIANTS.length; ++i) { + if (variant == TropicalFish.COMMON_VARIANTS[i]) { + components.add((new TranslatableComponent(TropicalFish.getPredefinedName(i))).withStyle(format)); + return; + } + } + + components.add(new TranslatableComponent(TropicalFish.getFishTypeName(variant)).withStyle(format)); + MutableComponent component = new TranslatableComponent(base); + if (!base.equals(pattern)) { + component.append(", ").append(new TranslatableComponent(pattern)); + } + + component.withStyle(format); + components.add(component); + } + } + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/WBBiomes.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/WBBiomes.java new file mode 100644 index 0000000..dc32a7f --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/WBBiomes.java @@ -0,0 +1,24 @@ +package com.cursedcauldron.wildbackport.common.registry; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.core.api.CoreRegistry; +import net.minecraft.core.Registry; +import net.minecraft.data.BuiltinRegistries; +import net.minecraft.data.worldgen.biome.OverworldBiomes; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.biome.Biome; + +import java.util.function.Supplier; + +public class WBBiomes { + public static final CoreRegistry BIOMES = CoreRegistry.create(BuiltinRegistries.BIOME, WildBackport.MOD_ID); + + public static final ResourceKey MANGROVE_SWAMP = create("mangrove_swamp", OverworldBiomes::theVoid); + public static final ResourceKey DEEP_DARK = create("deep_dark", OverworldBiomes::theVoid); + + private static ResourceKey create(String key, Supplier biome) { + BIOMES.register(key, biome); + return ResourceKey.create(Registry.BIOME_REGISTRY, new ResourceLocation(WildBackport.MOD_ID, key)); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/WBBlockEntities.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/WBBlockEntities.java new file mode 100644 index 0000000..b5995e6 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/WBBlockEntities.java @@ -0,0 +1,22 @@ +package com.cursedcauldron.wildbackport.common.registry; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.common.blocks.entity.MangroveSignBlockEntity; +import com.cursedcauldron.wildbackport.common.blocks.entity.SculkCatalystBlockEntity; +import com.cursedcauldron.wildbackport.common.blocks.entity.SculkShriekerBlockEntity; +import com.cursedcauldron.wildbackport.core.api.CoreRegistry; +import net.minecraft.core.Registry; +import net.minecraft.world.level.block.entity.BlockEntityType; + +import java.util.function.Supplier; + +//<> + +public class WBBlockEntities { + public static final CoreRegistry> BLOCKS = CoreRegistry.create(Registry.BLOCK_ENTITY_TYPE, WildBackport.MOD_ID); + + public static final Supplier> SCULK_CATALYST = BLOCKS.register("sculk_catalyst", () -> BlockEntityType.Builder.of(SculkCatalystBlockEntity::new, WBBlocks.SCULK_CATALYST.get()).build(null)); + public static final Supplier> SCULK_SHRIEKER = BLOCKS.register("sculk_shrieker", () -> BlockEntityType.Builder.of(SculkShriekerBlockEntity::new, WBBlocks.SCULK_SHRIEKER.get()).build(null)); +// public static final Supplier> MANGROVE_SIGN = BLOCKS.register("mangrove_sign", () -> BlockEntityType.Builder.of(MangroveSignBlockEntity::new, WBBlocks.MANGROVE_SIGN.get(), WBBlocks.MANGROVE_WALL_SIGN.get()).build(null)); +// public static final Supplier> MANGROVE_SIGN = BLOCKS.register("mangrove_sign", () -> BlockEntityType.Builder.of(MangroveSignBlockEntity::new, WBBlocks.MANGROVE_SIGN.getFirst().get(), WBBlocks.MANGROVE_SIGN.getSecond().get()).build(null)); +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/WBBlocks.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/WBBlocks.java new file mode 100644 index 0000000..5f6abb2 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/WBBlocks.java @@ -0,0 +1,126 @@ +package com.cursedcauldron.wildbackport.common.registry; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.client.registry.WBSoundTypes; +import com.cursedcauldron.wildbackport.common.blocks.BlockProperties; +import com.cursedcauldron.wildbackport.common.blocks.FrogspawnBlock; +import com.cursedcauldron.wildbackport.common.blocks.MangroveLeavesBlock; +import com.cursedcauldron.wildbackport.common.blocks.MangrovePropaguleBlock; +import com.cursedcauldron.wildbackport.common.blocks.MangroveRootsBlock; +import com.cursedcauldron.wildbackport.common.blocks.MudBlock; +import com.cursedcauldron.wildbackport.common.blocks.SculkBlock; +import com.cursedcauldron.wildbackport.common.blocks.SculkCatalystBlock; +import com.cursedcauldron.wildbackport.common.blocks.SculkShriekerBlock; +import com.cursedcauldron.wildbackport.common.blocks.SculkVeinBlock; +import com.cursedcauldron.wildbackport.core.api.CoreRegistry; +import com.cursedcauldron.wildbackport.core.api.WoodTypeRegistry; +import com.cursedcauldron.wildbackport.core.mixin.access.DoorBlockAccessor; +import com.cursedcauldron.wildbackport.core.mixin.access.PressurePlateBlockAccessor; +import com.cursedcauldron.wildbackport.core.mixin.access.StairBlockAccessor; +import com.cursedcauldron.wildbackport.core.mixin.access.TrapDoorBlockAccessor; +import com.cursedcauldron.wildbackport.core.mixin.access.WoodButtonBlockAccessor; +import com.mojang.datafixers.util.Pair; +import net.minecraft.core.Direction; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.SignItem; +import net.minecraft.world.item.WaterLilyBlockItem; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.FenceBlock; +import net.minecraft.world.level.block.FenceGateBlock; +import net.minecraft.world.level.block.FlowerPotBlock; +import net.minecraft.world.level.block.PressurePlateBlock; +import net.minecraft.world.level.block.RotatedPillarBlock; +import net.minecraft.world.level.block.SlabBlock; +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.block.StandingSignBlock; +import net.minecraft.world.level.block.WallBlock; +import net.minecraft.world.level.block.WallSignBlock; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.properties.WoodType; +import net.minecraft.world.level.material.Material; +import net.minecraft.world.level.material.MaterialColor; + +import java.util.function.Function; +import java.util.function.Supplier; + +//<> + +public class WBBlocks { + public static final CoreRegistry BLOCKS = CoreRegistry.create(Registry.BLOCK, WildBackport.MOD_ID); + + // Sculk + public static final Supplier SCULK = create("sculk", () -> new SculkBlock(BlockBehaviour.Properties.of(Material.SCULK).strength(0.6F).sound(WBSoundTypes.SCULK)), CreativeModeTab.TAB_DECORATIONS); + public static final Supplier SCULK_VEIN = create("sculk_vein", () -> new SculkVeinBlock(BlockBehaviour.Properties.of(Material.SCULK).noCollission().strength(0.2F).sound(WBSoundTypes.SCULK_VEIN)), CreativeModeTab.TAB_DECORATIONS); + public static final Supplier SCULK_CATALYST = create("sculk_catalyst", () -> new SculkCatalystBlock(BlockBehaviour.Properties.of(Material.SCULK).requiresCorrectToolForDrops().strength(3.0F).sound(WBSoundTypes.SCULK_CATALYST).lightLevel(value -> 6)), CreativeModeTab.TAB_REDSTONE); + public static final Supplier SCULK_SHRIEKER = create("sculk_shrieker", () -> new SculkShriekerBlock(BlockBehaviour.Properties.of(Material.SCULK, MaterialColor.COLOR_BLACK).strength(3.0F).sound(WBSoundTypes.SCULK_SHRIEKER)), CreativeModeTab.TAB_REDSTONE); + + // Frog + public static final Supplier OCHRE_FROGLIGHT = create("ochre_froglight", () -> new RotatedPillarBlock(BlockBehaviour.Properties.of(Material.DECORATION).instabreak().lightLevel(value -> 15).sound(WBSoundTypes.FROGLIGHT)), CreativeModeTab.TAB_DECORATIONS); + public static final Supplier VERDANT_FROGLIGHT = create("verdant_froglight", () -> new RotatedPillarBlock(BlockBehaviour.Properties.of(Material.DECORATION).instabreak().lightLevel(value -> 15).sound(WBSoundTypes.FROGLIGHT)), CreativeModeTab.TAB_DECORATIONS); + public static final Supplier PEARLESCENT_FROGLIGHT = create("pearlescent_froglight", () -> new RotatedPillarBlock(BlockBehaviour.Properties.of(Material.DECORATION).instabreak().lightLevel(value -> 15).sound(WBSoundTypes.FROGLIGHT)), CreativeModeTab.TAB_DECORATIONS); + public static final Supplier FROGSPAWN = create("frogspawn", () -> new FrogspawnBlock(BlockBehaviour.Properties.of(Material.BUILDABLE_GLASS).instabreak().noDrops().noOcclusion().noCollission().sound(WBSoundTypes.FROGSPAWN)), entry -> new WaterLilyBlockItem(entry.get(), new Item.Properties().tab(CreativeModeTab.TAB_MISC))); + + // Mangrove + public static final Supplier MANGROVE_LOG = create("mangrove_log", () -> new RotatedPillarBlock(BlockBehaviour.Properties.of(Material.WOOD, state -> state.getValue(RotatedPillarBlock.AXIS) == Direction.Axis.Y ? MaterialColor.COLOR_RED : MaterialColor.PODZOL).strength(2.0F).sound(SoundType.WOOD)), CreativeModeTab.TAB_BUILDING_BLOCKS); + public static final Supplier MANGROVE_WOOD = create("mangrove_wood", () -> new RotatedPillarBlock(BlockBehaviour.Properties.of(Material.WOOD, MaterialColor.COLOR_RED).strength(2.0F).sound(SoundType.WOOD)), CreativeModeTab.TAB_BUILDING_BLOCKS); + public static final Supplier STRIPPED_MANGROVE_LOG = create("stripped_mangrove_log", () -> new RotatedPillarBlock(BlockBehaviour.Properties.of(Material.WOOD, MaterialColor.COLOR_RED).strength(2.0F).sound(SoundType.WOOD)), CreativeModeTab.TAB_BUILDING_BLOCKS); + public static final Supplier STRIPPED_MANGROVE_WOOD = create("stripped_mangrove_wood", () -> new RotatedPillarBlock(BlockBehaviour.Properties.of(Material.WOOD, MaterialColor.COLOR_RED).strength(2.0F).sound(SoundType.WOOD)), CreativeModeTab.TAB_BUILDING_BLOCKS); + public static final Supplier MANGROVE_PLANKS = create("mangrove_planks", () -> new Block(BlockBehaviour.Properties.of(Material.WOOD, MaterialColor.COLOR_RED).strength(2.0F, 3.0F).sound(SoundType.WOOD)), CreativeModeTab.TAB_BUILDING_BLOCKS); + public static final Supplier MANGROVE_STAIRS = create("mangrove_stairs", () -> StairBlockAccessor.createStairBlock(MANGROVE_PLANKS.get().defaultBlockState(), BlockBehaviour.Properties.copy(MANGROVE_PLANKS.get())), CreativeModeTab.TAB_BUILDING_BLOCKS); + public static final Supplier MANGROVE_SLAB = create("mangrove_slab", () -> new SlabBlock(BlockBehaviour.Properties.of(Material.WOOD, MaterialColor.COLOR_RED).strength(2.0F, 3.0F).sound(SoundType.WOOD)), CreativeModeTab.TAB_BUILDING_BLOCKS); + public static final Supplier MANGROVE_FENCE = create("mangrove_fence", () -> new FenceBlock(BlockBehaviour.Properties.of(Material.WOOD, MANGROVE_PLANKS.get().defaultMaterialColor()).strength(2.0F, 3.0F).sound(SoundType.WOOD)), CreativeModeTab.TAB_DECORATIONS); + public static final Supplier MANGROVE_FENCE_GATE = create("mangrove_fence_gate", () -> new FenceGateBlock(BlockBehaviour.Properties.of(Material.WOOD, MANGROVE_PLANKS.get().defaultMaterialColor()).strength(2.0F, 3.0F).sound(SoundType.WOOD)), CreativeModeTab.TAB_REDSTONE); + public static final Supplier MANGROVE_DOOR = create("mangrove_door", () -> DoorBlockAccessor.createDoorBlock(BlockBehaviour.Properties.of(Material.WOOD, MANGROVE_PLANKS.get().defaultMaterialColor()).strength(3.0F).sound(SoundType.WOOD).noOcclusion()), CreativeModeTab.TAB_REDSTONE); + public static final Supplier MANGROVE_TRAPDOOR = create("mangrove_trapdoor", () -> TrapDoorBlockAccessor.createTrapDoorBlock(BlockBehaviour.Properties.of(Material.WOOD, MaterialColor.COLOR_RED).strength(3.0F).sound(SoundType.WOOD).noOcclusion().isValidSpawn(BlockProperties::never)), CreativeModeTab.TAB_REDSTONE); + public static final Supplier MANGROVE_PRESSURE_PLATE = create("mangrove_pressure_plate", () -> PressurePlateBlockAccessor.createPressurePlateBlock(PressurePlateBlock.Sensitivity.EVERYTHING, BlockBehaviour.Properties.of(Material.WOOD, MANGROVE_PLANKS.get().defaultMaterialColor()).noCollission().strength(0.5F).sound(SoundType.WOOD)), CreativeModeTab.TAB_REDSTONE); + public static final Supplier MANGROVE_BUTTON = create("mangrove_button", () -> WoodButtonBlockAccessor.createWoodButtonBlock(BlockBehaviour.Properties.of(Material.DECORATION).noCollission().strength(0.5F).sound(SoundType.WOOD)), CreativeModeTab.TAB_REDSTONE); + public static final Supplier MANGROVE_LEAVES = create("mangrove_leaves", () -> new MangroveLeavesBlock(BlockBehaviour.Properties.of(Material.LEAVES).strength(0.2F).randomTicks().sound(SoundType.GRASS).noOcclusion().isValidSpawn(BlockProperties::ocelotOrParrot).isSuffocating(BlockProperties::never).isViewBlocking(BlockProperties::never)), CreativeModeTab.TAB_DECORATIONS); + public static final Supplier MANGROVE_PROPAGULE = create("mangrove_propagule", () -> new MangrovePropaguleBlock(BlockBehaviour.Properties.of(Material.PLANT).noCollission().randomTicks().instabreak().sound(SoundType.GRASS)), CreativeModeTab.TAB_DECORATIONS); + public static final Supplier POTTED_MANGROVE_PROPAGULE = create("potted_mangrove_propagule", () -> new FlowerPotBlock(MANGROVE_PROPAGULE.get(), BlockBehaviour.Properties.of(Material.DECORATION).instabreak().noOcclusion())); + public static final Supplier MANGROVE_ROOTS = create("mangrove_roots", () -> new MangroveRootsBlock(BlockBehaviour.Properties.of(Material.WOOD).strength(0.7F).randomTicks().sound(WBSoundTypes.MANGROVE_ROOTS).noOcclusion().isValidSpawn(BlockProperties::ocelotOrParrot).isSuffocating(BlockProperties::never).isViewBlocking(BlockProperties::never)), CreativeModeTab.TAB_BUILDING_BLOCKS); + public static final Supplier MUDDY_MANGROVE_ROOTS = create("muddy_mangrove_roots", () -> new RotatedPillarBlock(BlockBehaviour.Properties.of(Material.DIRT).strength(0.7F).sound(WBSoundTypes.MUDDY_MANGROVE_ROOTS)), CreativeModeTab.TAB_BUILDING_BLOCKS); + public static final Pair, Supplier> MANGROVE_SIGN = create("mangrove", Material.WOOD, MaterialColor.COLOR_RED); + + // Mud + public static final Supplier MUD = create("mud", () -> new MudBlock(BlockBehaviour.Properties.copy(Blocks.DIRT).color(MaterialColor.TERRACOTTA_CYAN).isValidSpawn(BlockProperties::always).isRedstoneConductor(BlockProperties::always).isViewBlocking(BlockProperties::always).isSuffocating(BlockProperties::always).sound(WBSoundTypes.MUD)), CreativeModeTab.TAB_BUILDING_BLOCKS); + public static final Supplier PACKED_MUD = create("packed_mud", () -> new Block(BlockBehaviour.Properties.copy(Blocks.DIRT).strength(1.0F, 3.0F).sound(WBSoundTypes.PACKED_MUD)), CreativeModeTab.TAB_BUILDING_BLOCKS); + public static final Supplier MUD_BRICKS = create("mud_bricks", () -> new Block(BlockBehaviour.Properties.of(Material.STONE, MaterialColor.COLOR_LIGHT_GRAY).requiresCorrectToolForDrops().strength(1.5F, 3.0F).sound(WBSoundTypes.MUD_BRICKS)), CreativeModeTab.TAB_BUILDING_BLOCKS); + public static final Supplier MUD_BRICK_STAIRS = create("mud_brick_stairs", () -> StairBlockAccessor.createStairBlock(MUD_BRICKS.get().defaultBlockState(), BlockBehaviour.Properties.copy(MUD_BRICKS.get())), CreativeModeTab.TAB_BUILDING_BLOCKS); + public static final Supplier MUD_BRICK_SLAB = create("mud_brick_slab", () -> new SlabBlock(BlockBehaviour.Properties.of(Material.STONE, MaterialColor.COLOR_BROWN).requiresCorrectToolForDrops().strength(1.5F, 3.0F)), CreativeModeTab.TAB_BUILDING_BLOCKS); + public static final Supplier MUD_BRICK_WALL = create("mud_brick_wall", () -> new WallBlock(BlockBehaviour.Properties.copy(MUD_BRICKS.get())), CreativeModeTab.TAB_DECORATIONS); + + // Deepslate + public static final Supplier REINFORCED_DEEPSLATE = create("reinforced_deepslate", () -> new Block(BlockBehaviour.Properties.of(Material.STONE, MaterialColor.DEEPSLATE).sound(SoundType.DEEPSLATE).strength(55.0F, 1200.0F).noDrops()), CreativeModeTab.TAB_DECORATIONS); + + private static Supplier create(String key, Supplier block, CreativeModeTab tab) { + return create(key, block, entry -> new BlockItem(entry.get(), new Item.Properties().tab(tab))); + } + + private static Supplier create(String key, Supplier block, Function, Item> item) { + Supplier entry = create(key, block); + WBItems.ITEMS.register(key, () -> item.apply(entry)); + return entry; + } + + private static Supplier create(String key, Supplier block) { + return BLOCKS.register(key, block); + } + + // Signs + public static Pair, Supplier> create(String key, Material material, MaterialColor color) { + return create(key, BlockBehaviour.Properties.of(material, color).noCollission().strength(1.0F).sound(SoundType.WOOD), new Item.Properties().stacksTo(16).tab(CreativeModeTab.TAB_DECORATIONS)); + } + + public static Pair, Supplier> create(String key, BlockBehaviour.Properties blocks, Item.Properties items) { + WoodType woodType = WoodTypeRegistry.create(new ResourceLocation(WildBackport.MOD_ID, key)); + Supplier standing = create(key + "_sign", () -> new StandingSignBlock(blocks, woodType)); + Supplier wall = create(key + "_wall_sign", () -> new WallSignBlock(blocks.dropsLike(standing.get()), woodType)); + WBItems.ITEMS.register(key + "_sign", () -> new SignItem(items, standing.get(), wall.get())); + return Pair.of(standing, wall); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/WBEnchantments.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/WBEnchantments.java new file mode 100644 index 0000000..059b632 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/WBEnchantments.java @@ -0,0 +1,16 @@ +package com.cursedcauldron.wildbackport.common.registry; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.common.enchantments.SwiftSneakEnchantment; +import com.cursedcauldron.wildbackport.core.api.CoreRegistry; +import net.minecraft.core.Registry; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.item.enchantment.Enchantment; + +import java.util.function.Supplier; + +public class WBEnchantments { + public static final CoreRegistry ENCHANTMENTS = CoreRegistry.create(Registry.ENCHANTMENT, WildBackport.MOD_ID); + + public static final Supplier SWIFT_SNEAK = ENCHANTMENTS.register("swift_sneak", () -> new SwiftSneakEnchantment(Enchantment.Rarity.VERY_RARE, new EquipmentSlot[]{EquipmentSlot.LEGS})); +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/WBGameEvents.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/WBGameEvents.java new file mode 100644 index 0000000..9d1bf00 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/WBGameEvents.java @@ -0,0 +1,28 @@ +package com.cursedcauldron.wildbackport.common.registry; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.core.api.CoreRegistry; +import net.minecraft.core.Registry; +import net.minecraft.world.level.gameevent.GameEvent; + +import java.util.function.Supplier; + +//<> + +public class WBGameEvents { + public static final CoreRegistry EVENTS = CoreRegistry.create(Registry.GAME_EVENT, WildBackport.MOD_ID); + + public static final Supplier NOTE_BLOCK_PLAY = create("note_block_play"); + public static final Supplier SCULK_SENSOR_TENDRILS_CLICKING = create("sculk_sensor_tendrils_clicking"); + public static final Supplier ENTITY_DIE = create("entity_die"); + public static final Supplier SHRIEK = create("shriek", 32); + public static final Supplier INSTRUMENT_PLAY = create("instrument_play"); + + private static Supplier create(String key) { + return create(key, 16); + } + + private static Supplier create(String key, int maxDistance) { + return EVENTS.register(key, () -> new GameEvent(key, maxDistance)); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/WBItems.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/WBItems.java new file mode 100644 index 0000000..bdabad2 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/WBItems.java @@ -0,0 +1,66 @@ +package com.cursedcauldron.wildbackport.common.registry; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.client.registry.WBSoundEvents; +import com.cursedcauldron.wildbackport.common.entities.access.api.BoatTypes; +import com.cursedcauldron.wildbackport.common.items.ChestBoatItem; +import com.cursedcauldron.wildbackport.common.items.DiscFragmentItem; +import com.cursedcauldron.wildbackport.common.items.TadpoleBucketItem; +import com.cursedcauldron.wildbackport.common.registry.entity.WBEntities; +import com.cursedcauldron.wildbackport.core.api.CoreRegistry; +import com.cursedcauldron.wildbackport.core.mixin.access.RecordItemAccessor; +import dev.architectury.injectables.annotations.ExpectPlatform; +import net.minecraft.core.Registry; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.vehicle.Boat; +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.Rarity; +import net.minecraft.world.item.RecordItem; +import net.minecraft.world.level.material.Fluids; + +import java.util.function.Supplier; + +//<> + +public class WBItems { + public static final CoreRegistry ITEMS = CoreRegistry.create(Registry.ITEM, WildBackport.MOD_ID); + + // Spawns + public static final Supplier ALLAY_SPAWN_EGG = create("allay_spawn_egg", spawnEgg(WBEntities.ALLAY, 56063, 44543)); + public static final Supplier FROG_SPAWN_EGG = create("frog_spawn_egg", spawnEgg(WBEntities.FROG, 13661252, 16762748)); + public static final Supplier TADPOLE_SPAWN_EGG = create("tadpole_spawn_egg", spawnEgg(WBEntities.TADPOLE, 7164733, 1444352)); + public static final Supplier WARDEN_SPAWN_EGG = create("warden_spawn_egg", spawnEgg(WBEntities.WARDEN, 1001033, 3790560)); + public static final Supplier TADPOLE_BUCKET = create("tadpole_bucket", () -> new TadpoleBucketItem(WBEntities.TADPOLE, Fluids.WATER, () -> WBSoundEvents.BUCKED_EMPTY_TADPOLE, new Item.Properties().stacksTo(1).tab(CreativeModeTab.TAB_MISC))); + + // Boats + public static final Supplier MANGROVE_BOAT = create("mangrove_boat", boat(false, BoatTypes.MANGROVE.get())); + public static final Supplier OAK_CHEST_BOAT = create("oak_chest_boat", boat(true, Boat.Type.OAK)); + public static final Supplier SPRUCE_CHEST_BOAT = create("spruce_chest_boat", boat(true, Boat.Type.SPRUCE)); + public static final Supplier ACACIA_CHEST_BOAT = create("acacia_chest_boat", boat(true, Boat.Type.ACACIA)); + public static final Supplier BIRCH_CHEST_BOAT = create("birch_chest_boat", boat(true, Boat.Type.BIRCH)); + public static final Supplier JUNGLE_CHEST_BOAT = create("jungle_chest_boat", boat(true, Boat.Type.JUNGLE)); + public static final Supplier DARK_OAK_CHEST_BOAT = create("dark_oak_chest_boat", boat(true, Boat.Type.DARK_OAK)); + public static final Supplier MANGROVE_CHEST_BOAT = create("mangrove_chest_boat", boat(true, BoatTypes.MANGROVE.get())); + + // Deep Dark + public static final Supplier ECHO_SHARD = create("echo_shard", () -> new Item(new Item.Properties().tab(CreativeModeTab.TAB_MISC))); + + // Music + public static final Supplier MUSIC_DISC_5 = create("music_disc_5", () -> RecordItemAccessor.createRecordItem(15, WBSoundEvents.MUSIC_DISC_5, new Item.Properties().stacksTo(1).tab(CreativeModeTab.TAB_MISC).rarity(Rarity.RARE))); + public static final Supplier DISC_FRAGMENT_5 = create("disc_fragment_5", () -> new DiscFragmentItem(new Item.Properties().tab(CreativeModeTab.TAB_MISC))); + + private static Supplier create(String key, Supplier item) { + return ITEMS.register(key, item); + } + + @ExpectPlatform + private static Supplier spawnEgg(Supplier> mob, int background, int highlight) { + throw new AssertionError(); + } + + private static Supplier boat(boolean chested, Boat.Type type) { + return () -> new ChestBoatItem(chested, type, new Item.Properties().stacksTo(1).tab(CreativeModeTab.TAB_TRANSPORTATION)); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/WBPositionSources.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/WBPositionSources.java new file mode 100644 index 0000000..248a61a --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/WBPositionSources.java @@ -0,0 +1,15 @@ +package com.cursedcauldron.wildbackport.common.registry; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.common.entities.warden.MobPositionSource; +import com.cursedcauldron.wildbackport.core.api.CoreRegistry; +import net.minecraft.core.Registry; +import net.minecraft.world.level.gameevent.PositionSourceType; + +import java.util.function.Supplier; + +public class WBPositionSources { + public static final CoreRegistry> SOURCES = CoreRegistry.create(Registry.POSITION_SOURCE_TYPE, WildBackport.MOD_ID); + + public static final Supplier> MOB = SOURCES.register("mob", MobPositionSource.Type::new); +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/entity/WBActivities.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/entity/WBActivities.java new file mode 100644 index 0000000..66737bc --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/entity/WBActivities.java @@ -0,0 +1,28 @@ +package com.cursedcauldron.wildbackport.common.registry.entity; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.core.api.CoreRegistry; +import com.cursedcauldron.wildbackport.core.mixin.access.ActivityAccessor; +import net.minecraft.core.Registry; +import net.minecraft.world.entity.schedule.Activity; + +import java.util.function.Supplier; + +//<> + +public class WBActivities { + public static final CoreRegistry ACTIVITIES = CoreRegistry.create(Registry.ACTIVITY, WildBackport.MOD_ID); + + public static final Supplier SNIFF = create("sniff"); + public static final Supplier INVESTIGATE = create("investigate"); + public static final Supplier ROAR = create("roar"); + public static final Supplier EMERGE = create("emerge"); + public static final Supplier TONGUE = create("tongue"); + public static final Supplier DIG = create("dig"); + public static final Supplier SWIM = create("swim"); + public static final Supplier LAY_SPAWN = create("lay_spawn"); + + public static Supplier create(String key) { + return ACTIVITIES.register(key, () -> ActivityAccessor.createActivity(key)); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/entity/WBEntities.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/entity/WBEntities.java new file mode 100644 index 0000000..477f6ac --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/entity/WBEntities.java @@ -0,0 +1,33 @@ +package com.cursedcauldron.wildbackport.common.registry.entity; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.common.entities.Allay; +import com.cursedcauldron.wildbackport.common.entities.ChestBoat; +import com.cursedcauldron.wildbackport.common.entities.Frog; +import com.cursedcauldron.wildbackport.common.entities.MangroveBoat; +import com.cursedcauldron.wildbackport.common.entities.Tadpole; +import com.cursedcauldron.wildbackport.common.entities.Warden; +import com.cursedcauldron.wildbackport.core.api.CoreRegistry; +import net.minecraft.core.Registry; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.MobCategory; + +import java.util.function.Supplier; + +//<> + +public class WBEntities { + public static final CoreRegistry> ENTITIES = CoreRegistry.create(Registry.ENTITY_TYPE, WildBackport.MOD_ID); + + public static final Supplier> ALLAY = create("allay", EntityType.Builder.of(Allay::new, MobCategory.CREATURE).sized(0.35F, 0.6F).clientTrackingRange(8).updateInterval(2)); + public static final Supplier> FROG = create("frog", EntityType.Builder.of(Frog::new, MobCategory.CREATURE).sized(0.5F, 0.5F).clientTrackingRange(10)); + public static final Supplier> TADPOLE = create("tadpole", EntityType.Builder.of(Tadpole::new, MobCategory.CREATURE).sized(Tadpole.WIDTH, Tadpole.HEIGHT).clientTrackingRange(10)); + public static final Supplier> WARDEN = create("warden", EntityType.Builder.of(Warden::new, MobCategory.MONSTER).sized(0.9F, 2.9F).clientTrackingRange(16).fireImmune()); + public static final Supplier> MANGROVE_BOAT = create("mangrove_boat", EntityType.Builder.of(MangroveBoat::new, MobCategory.MISC).sized(1.375F, 0.5625F).clientTrackingRange(10)); + public static final Supplier> CHEST_BOAT = create("chest_boat", EntityType.Builder.of(ChestBoat::new, MobCategory.MISC).sized(1.375F, 0.5625F).clientTrackingRange(10)); + + private static Supplier> create(String key, EntityType.Builder builder) { + return ENTITIES.register(key, () -> builder.build(key)); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/entity/WBMemoryModules.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/entity/WBMemoryModules.java new file mode 100644 index 0000000..fc813d0 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/entity/WBMemoryModules.java @@ -0,0 +1,55 @@ +package com.cursedcauldron.wildbackport.common.registry.entity; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.core.api.CoreRegistry; +import com.cursedcauldron.wildbackport.core.mixin.access.MemoryModuleTypeAccessor; +import com.mojang.serialization.Codec; +import net.minecraft.core.BlockPos; +import net.minecraft.core.GlobalPos; +import net.minecraft.core.Registry; +import net.minecraft.core.SerializableUUID; +import net.minecraft.util.Unit; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import java.util.function.Supplier; + +//<> + +public class WBMemoryModules { + public static final CoreRegistry> MEMORIES = CoreRegistry.create(Registry.MEMORY_MODULE_TYPE, WildBackport.MOD_ID); + + + public static final Supplier> IS_IN_WATER = create("is_in_water", Codec.unit(Unit.INSTANCE)); + public static final Supplier> IS_PREGNANT = create("is_pregnant", Codec.unit(Unit.INSTANCE)); + public static final Supplier>> UNREACHABLE_TONGUE_TARGETS = create("unreachable_tongue_targets"); + public static final Supplier> ROAR_TARGET = create("roar_target"); + public static final Supplier> DISTURBANCE_LOCATION = create("disturbance_location"); + public static final Supplier> RECENT_PROJECTILE = create("recent_projectile", Codec.unit(Unit.INSTANCE)); + public static final Supplier> IS_SNIFFING = create("is_sniffing", Codec.unit(Unit.INSTANCE)); + public static final Supplier> IS_EMERGING = create("is_emerging", Codec.unit(Unit.INSTANCE)); + public static final Supplier> ROAR_SOUND_DELAY = create("roar_sound_delay", Codec.unit(Unit.INSTANCE)); + public static final Supplier> DIG_COOLDOWN = create("dig_cooldown", Codec.unit(Unit.INSTANCE)); + public static final Supplier> ROAR_SOUND_COOLDOWN = create("roar_sound_cooldown", Codec.unit(Unit.INSTANCE)); + public static final Supplier> SNIFF_COOLDOWN = create("sniff_cooldown", Codec.unit(Unit.INSTANCE)); + public static final Supplier> TOUCH_COOLDOWN = create("touch_cooldown", Codec.unit(Unit.INSTANCE)); + public static final Supplier> VIBRATION_COOLDOWN = create("vibration_cooldown", Codec.unit(Unit.INSTANCE)); + public static final Supplier> SONIC_BOOM_COOLDOWN = create("sonic_boom_cooldown", Codec.unit(Unit.INSTANCE)); + public static final Supplier> SONIC_BOOM_SOUND_COOLDOWN = create("sonic_boom_sound_cooldown", Codec.unit(Unit.INSTANCE)); + public static final Supplier> SONIC_BOOM_SOUND_DELAY = create("sonic_boom_sound_delay", Codec.unit(Unit.INSTANCE)); + public static final Supplier> LIKED_PLAYER = create("liked_player", SerializableUUID.CODEC); + public static final Supplier> LIKED_NOTEBLOCK = create("liked_noteblock", GlobalPos.CODEC); + public static final Supplier> LIKED_NOTEBLOCK_COOLDOWN_TICKS = create("liked_noteblock_cooldown_ticks", Codec.INT); + public static final Supplier> ITEM_PICKUP_COOLDOWN_TICKS = create("item_pickup_cooldown_ticks", Codec.INT); + + private static Supplier> create(String key) { + return MEMORIES.register(key, () -> MemoryModuleTypeAccessor.createMemoryModuleType(Optional.empty())); + } + + private static Supplier> create(String key, Codec codec) { + return MEMORIES.register(key, () -> MemoryModuleTypeAccessor.createMemoryModuleType(Optional.of(codec))); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/entity/WBSensorTypes.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/entity/WBSensorTypes.java new file mode 100644 index 0000000..9473c11 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/entity/WBSensorTypes.java @@ -0,0 +1,30 @@ +package com.cursedcauldron.wildbackport.common.registry.entity; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.common.entities.brain.FrogBrain; +import com.cursedcauldron.wildbackport.common.entities.brain.frog.FrogAttackablesSensor; +import com.cursedcauldron.wildbackport.common.entities.brain.frog.IsInWaterSensor; +import com.cursedcauldron.wildbackport.common.entities.brain.warden.WardenEntitySensor; +import com.cursedcauldron.wildbackport.core.api.CoreRegistry; +import com.cursedcauldron.wildbackport.core.mixin.access.SensorTypeAccessor; +import net.minecraft.core.Registry; +import net.minecraft.world.entity.ai.sensing.Sensor; +import net.minecraft.world.entity.ai.sensing.SensorType; +import net.minecraft.world.entity.ai.sensing.TemptingSensor; + +import java.util.function.Supplier; + +//<> + +public class WBSensorTypes { + public static final CoreRegistry> SENSORS = CoreRegistry.create(Registry.SENSOR_TYPE, WildBackport.MOD_ID); + + public static final Supplier> WARDEN_ENTITY_SENSOR = create("warden_entity_sensor", WardenEntitySensor::new); + public static final Supplier> FROG_TEMPTATIONS = create("frog_temptations", () -> new TemptingSensor(FrogBrain.getTemptItems())); + public static final Supplier> FROG_ATTACKABLES = create("frog_attackables", FrogAttackablesSensor::new); + public static final Supplier> IS_IN_WATER = create("is_in_water", IsInWaterSensor::new); + + private static > Supplier> create(String key, Supplier sensor) { + return SENSORS.register(key, () -> SensorTypeAccessor.createSensorType(sensor)); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/tag/WBBiomeTags.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/tag/WBBiomeTags.java new file mode 100644 index 0000000..093f4eb --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/tag/WBBiomeTags.java @@ -0,0 +1,16 @@ +package com.cursedcauldron.wildbackport.common.tag; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.core.api.TagRegistry; +import net.minecraft.core.Registry; +import net.minecraft.data.BuiltinRegistries; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.TagKey; +import net.minecraft.world.level.biome.Biome; + +public class WBBiomeTags { + public static final TagRegistry TAGS = TagRegistry.create(BuiltinRegistries.BIOME, WildBackport.MOD_ID); + + public static final TagKey SPAWNS_WARM_VARIANT_FROGS = TAGS.create("spawns_warm_variant_frogs"); + public static final TagKey SPAWNS_COLD_VARIANT_FROGS = TAGS.create("spawns_cold_variant_frogs"); +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/tag/WBBlockTags.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/tag/WBBlockTags.java new file mode 100644 index 0000000..bb1becd --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/tag/WBBlockTags.java @@ -0,0 +1,16 @@ +package com.cursedcauldron.wildbackport.common.tag; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.core.api.TagRegistry; +import net.minecraft.core.Registry; +import net.minecraft.tags.TagKey; +import net.minecraft.world.level.block.Block; + +public class WBBlockTags { + public static final TagRegistry TAGS = TagRegistry.create(Registry.BLOCK, WildBackport.MOD_ID); + + public static final TagKey FROG_PREFER_JUMP_TO = TAGS.create("frog_prefer_jump_to"); + public static final TagKey FROGS_SPAWNABLE_ON = TAGS.create("frogs_spawnable_on"); + public static final TagKey SCULK_REPLACEABLE = TAGS.create("sculk_replaceable"); + public static final TagKey SCULK_REPLACEABLE_WORLD_GEN = TAGS.create("sculk_replaceable_world_gen"); +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/tag/WBEntityTypeTags.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/tag/WBEntityTypeTags.java new file mode 100644 index 0000000..1f42789 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/tag/WBEntityTypeTags.java @@ -0,0 +1,15 @@ +package com.cursedcauldron.wildbackport.common.tag; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.core.api.TagRegistry; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.TagKey; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.item.Item; + +public class WBEntityTypeTags { + public static final TagRegistry> TAGS = TagRegistry.create(Registry.ENTITY_TYPE, WildBackport.MOD_ID); + + public static final TagKey> FROG_FOOD = TAGS.create("frog_food"); +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/tag/WBGameEventTags.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/tag/WBGameEventTags.java new file mode 100644 index 0000000..5b3a0ed --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/tag/WBGameEventTags.java @@ -0,0 +1,15 @@ +package com.cursedcauldron.wildbackport.common.tag; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.core.api.TagRegistry; +import net.minecraft.core.Registry; +import net.minecraft.tags.TagKey; +import net.minecraft.world.level.gameevent.GameEvent; + +public class WBGameEventTags { + public static final TagRegistry TAGS = TagRegistry.create(Registry.GAME_EVENT, WildBackport.MOD_ID); + + public static final TagKey SHRIEKER_CAN_LISTEN = TAGS.create("shrieker_can_listen"); + public static final TagKey WARDEN_CAN_LISTEN = TAGS.create("warden_can_listen"); + public static final TagKey ALLAY_CAN_LISTEN = TAGS.create("allay_can_listen"); +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/tag/WBItemTags.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/tag/WBItemTags.java new file mode 100644 index 0000000..854b389 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/tag/WBItemTags.java @@ -0,0 +1,10 @@ +package com.cursedcauldron.wildbackport.common.tag; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.core.api.TagRegistry; +import net.minecraft.core.Registry; +import net.minecraft.world.item.Item; + +public class WBItemTags { + public static final TagRegistry TAGS = TagRegistry.create(Registry.ITEM, WildBackport.MOD_ID); +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/utils/DirectionUtils.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/utils/DirectionUtils.java new file mode 100644 index 0000000..bd221b9 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/utils/DirectionUtils.java @@ -0,0 +1,35 @@ +package com.cursedcauldron.wildbackport.common.utils; + +import net.minecraft.core.Direction; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class DirectionUtils { + public static Collection shuffle(Random random) { + List directions = Arrays.stream(Direction.values()).collect(Collectors.toList()); + Collections.shuffle(directions, random); + return directions; + } + + public static Stream stream() { + return Stream.of(Direction.values()); + } + + public static Collection unpack(byte faces) { + ArrayList directions = new ArrayList<>(6); + for (Direction direction : Direction.values()) { + if ((faces & (byte)(2 << direction.ordinal() >> 1)) > 0) { + directions.add(direction); + } + } + + return directions; + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/utils/MathUtils.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/utils/MathUtils.java new file mode 100644 index 0000000..43661b7 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/utils/MathUtils.java @@ -0,0 +1,7 @@ +package com.cursedcauldron.wildbackport.common.utils; + +public class MathUtils { + public static float catmullrom(float delta, float startPoint, float start, float end, float endPoint) { + return 0.5F * (2.0F * start + (end - startPoint) * delta + (2.0F * startPoint - 5.0F * start + 4.0F * end - endPoint) * delta * delta + (3.0F * start - startPoint - 3.0F * end + endPoint) * delta * delta * delta); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/utils/MobUtils.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/utils/MobUtils.java new file mode 100644 index 0000000..0bd9500 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/utils/MobUtils.java @@ -0,0 +1,50 @@ +package com.cursedcauldron.wildbackport.common.utils; + +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.util.Mth; +import net.minecraft.world.effect.MobEffect; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.behavior.PositionTracker; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; +import net.minecraft.world.entity.ai.memory.WalkTarget; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.phys.Vec3; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class MobUtils { + public static void addEffectToPlayersWithinDistance(ServerLevel level, @Nullable Entity entity, Vec3 position, double distance, MobEffectInstance instance, int duration) { + MobEffect mobeffect = instance.getEffect(); + List players = level.getPlayers(player -> player.gameMode.isSurvival() && (entity == null || !entity.isAlliedTo(player)) && position.closerThan(player.position(), distance) && (!player.hasEffect(mobeffect) || player.getEffect(mobeffect).getAmplifier() < instance.getAmplifier() || player.getEffect(mobeffect).getDuration() < duration)); + players.forEach(player -> player.addEffect(new MobEffectInstance(instance), entity)); + } + + public static boolean closerThan(Entity source, Entity entity, double xzRange, double yRange) { + double x = entity.getX() - source.getX(); + double y = entity.getY() - source.getY(); + double z = entity.getZ() - source.getZ(); + return Mth.lengthSquared(x, z) < Mth.square(xzRange) && Mth.square(y) < Mth.square(yRange); + } + + public static void setWalkAndLookTargetMemories(LivingEntity entity, PositionTracker tracker, float speedModifier, int closeEnough) { + WalkTarget target = new WalkTarget(tracker, speedModifier, closeEnough); + entity.getBrain().setMemory(MemoryModuleType.LOOK_TARGET, tracker); + entity.getBrain().setMemory(MemoryModuleType.WALK_TARGET, target); + } + + public static void throwItem(LivingEntity entity, ItemStack stack, Vec3 source, Vec3 target, float p_217138_) { + double y = entity.getEyeY() - (double)p_217138_; + ItemEntity itemEntity = new ItemEntity(entity.level, entity.getX(), y, entity.getZ(), stack); + itemEntity.setThrower(entity.getUUID()); + Vec3 distance = source.subtract(entity.position()); + distance = distance.normalize().multiply(target.x, target.y, target.z); + itemEntity.setDeltaMovement(distance); + itemEntity.setDefaultPickUpDelay(); + entity.level.addFreshEntity(itemEntity); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/utils/ModUtils.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/utils/ModUtils.java new file mode 100644 index 0000000..9e1dfe0 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/utils/ModUtils.java @@ -0,0 +1,27 @@ +package com.cursedcauldron.wildbackport.common.utils; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +import java.util.List; +import java.util.Random; + +public class ModUtils { + public static void shuffle(List entries, Random random) { + int size = entries.size(); + for (int i = size; i > 1; --i) { + entries.set(i - 1, entries.set(random.nextInt(i), entries.get(i - 1))); + } + } + + public static List copyShuffled(T[] entries, Random random) { + ObjectArrayList objects = new ObjectArrayList<>(entries); + shuffle(objects, random); + return objects; + } + + public static List copyShuffled(ObjectArrayList entries, Random random) { + ObjectArrayList objects = new ObjectArrayList<>(entries); + shuffle(objects, random); + return objects; + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/utils/ParticleUtils.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/utils/ParticleUtils.java new file mode 100644 index 0000000..b65a5a4 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/utils/ParticleUtils.java @@ -0,0 +1,36 @@ +package com.cursedcauldron.wildbackport.common.utils; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.particles.ParticleOptions; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.Mth; +import net.minecraft.util.valueproviders.IntProvider; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.Vec3; + +import java.util.function.Supplier; + +public class ParticleUtils { + public static void spawnParticles(Level world, BlockPos pos, ParticleOptions effect, IntProvider count, Direction direction, Supplier velocity, double offset) { + int sample = count.sample(world.getRandom()); + for (int i = 0; i < sample; ++i) { + spawnParticle(world, pos, direction, effect, velocity.get(), offset); + } + } + + public static void spawnParticle(Level level, BlockPos pos, Direction direction, ParticleOptions effect, Vec3 velocity, double offset) { + Vec3 center = Vec3.atCenterOf(pos); + int xStep = direction.getStepX(); + int yStep = direction.getStepY(); + int zStep = direction.getStepZ(); + double x = center.x + (xStep == 0 ? Mth.nextDouble(level.getRandom(), -0.5D, 0.5D) : (double)xStep * offset); + double y = center.y + (yStep == 0 ? Mth.nextDouble(level.getRandom(), -0.5D, 0.5D) : (double)yStep * offset); + double z = center.z + (zStep == 0 ? Mth.nextDouble(level.getRandom(), -0.5D, 0.5D) : (double)zStep * offset); + double xVelocity = xStep == 0 ? velocity.x() : 0.0D; + double yVelocity = yStep == 0 ? velocity.y() : 0.0D; + double zVelocity = zStep == 0 ? velocity.z() : 0.0D; + ServerLevel server = level instanceof ServerLevel side ? side : null; + if (server != null) server.sendParticles(effect, x, y, z, 1, xVelocity, yVelocity, zVelocity, 0.0D); + } +} diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/utils/PositionUtils.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/utils/PositionUtils.java new file mode 100644 index 0000000..21aa135 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/utils/PositionUtils.java @@ -0,0 +1,33 @@ +package com.cursedcauldron.wildbackport.common.utils; + +import com.mojang.serialization.Codec; +import net.minecraft.Util; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Vec3i; +import net.minecraft.world.phys.Vec3; + +import java.util.List; + +public class PositionUtils { + public static final Codec VEC_CODEC = Codec.DOUBLE.listOf().comapFlatMap(values -> { + return Util.fixedSize(values, 3).map(pos -> { + return new Vec3(pos.get(0), pos.get(1), pos.get(2)); + }); + }, pos -> { + return List.of(pos.x(), pos.y(), pos.z()); + }); + + public static BlockPos toBlockPos(Vec3 pos) { + return new BlockPos(pos.x, pos.y, pos.z); + } + + public static Vec3 toVec(BlockPos pos) { + return new Vec3(pos.getX(), pos.getY(), pos.getZ()); + } + + public static Vec3 relative(Vec3 pos, Direction direction, double offset) { + Vec3i normal = direction.getNormal(); + return new Vec3(pos.x + offset * (double)normal.getX(), pos.y + offset * (double)normal.getY(), pos.z + offset * (double)normal.getZ()); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/worldgen/VeinGrower.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/worldgen/VeinGrower.java new file mode 100644 index 0000000..7a9f2fb --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/worldgen/VeinGrower.java @@ -0,0 +1,162 @@ +package com.cursedcauldron.wildbackport.common.worldgen; + +import com.cursedcauldron.wildbackport.common.blocks.SculkVeinBlock; +import com.cursedcauldron.wildbackport.common.utils.DirectionUtils; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.MultifaceBlock; +import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.Nullable; + +import java.util.Optional; +import java.util.Random; + +public class VeinGrower { + public static final GrowType[] GROW_TYPES = new GrowType[]{GrowType.SAME_POSITION, GrowType.SAME_PLANE, GrowType.WRAP_AROUND}; + private final GrowChecker growChecker; + + public VeinGrower(MultifaceBlock lichen) { + this(new VeinGrowChecker(lichen)); + } + + public VeinGrower(GrowChecker growChecker) { + this.growChecker = growChecker; + } + + public boolean canGrow(BlockState state, BlockGetter getter, BlockPos pos, Direction direction) { + return DirectionUtils.stream().anyMatch(newDirection -> this.getGrowPos(state, getter, pos, direction, newDirection, this.growChecker::canGrow).isPresent()); + } + + public Optional grow(BlockState state, LevelAccessor level, BlockPos pos, Random random) { + return DirectionUtils.shuffle(random).stream().filter(direction -> this.growChecker.canGrow(state, direction)).map(direction -> this.grow(state, level, pos, direction, random, false)).filter(Optional::isPresent).findFirst().orElse(Optional.empty()); + } + + public long grow(BlockState state, LevelAccessor level, BlockPos pos, boolean postProcess) { + return DirectionUtils.stream().filter(direction -> this.growChecker.canGrow(state, direction)).map(direction -> this.grow(state, level, pos, direction, postProcess)).reduce(0L, Long::sum); + } + + public Optional grow(BlockState state, LevelAccessor level, BlockPos pos, Direction direction, Random random, boolean postProcess) { + return DirectionUtils.shuffle(random).stream().map(newDirection -> this.grow(state, level, pos, direction, newDirection, postProcess)).filter(Optional::isPresent).findFirst().orElse(Optional.empty()); + } + + private long grow(BlockState state, LevelAccessor level, BlockPos pos, Direction direction, boolean postProcess) { + return DirectionUtils.stream().map(newDirection -> this.grow(state, level, pos, direction, newDirection, postProcess)).filter(Optional::isPresent).count(); + } + + public Optional grow(BlockState state, LevelAccessor world, BlockPos pos, Direction oldDirection, Direction newDirection, boolean postProcess) { + return this.getGrowPos(state, world, pos, oldDirection, newDirection, this.growChecker::canGrow).flatMap(growPos -> this.place(world, growPos, postProcess)); + } + + public Optional getGrowPos(BlockState state, BlockGetter world, BlockPos pos, Direction oldDirection, Direction newDirection, GrowPosPredicate predicate) { + if (newDirection.getAxis() == oldDirection.getAxis()) { + return Optional.empty(); + } + + if (!(this.growChecker.canGrow(state) || this.growChecker.hasDirection(state, oldDirection) && !this.growChecker.hasDirection(state, newDirection))) { + return Optional.empty(); + } + + for (GrowType growType : this.growChecker.getGrowTypes()) { + GrowPos growPos = growType.getGrowPos(pos, newDirection, oldDirection); + if (!predicate.test(world, pos, growPos)) continue; + return Optional.of(growPos); + } + return Optional.empty(); + } + + public Optional place(LevelAccessor world, GrowPos pos, boolean markForPostProcessing) { + BlockState state = world.getBlockState(pos.pos()); + if (this.growChecker.place(world, pos, state, markForPostProcessing)) { + return Optional.of(pos); + } + return Optional.empty(); + } + + public static class VeinGrowChecker implements GrowChecker { + protected MultifaceBlock multifaceBlock; + + public VeinGrowChecker(MultifaceBlock multifaceBlock) { + this.multifaceBlock = multifaceBlock; + } + + @Override @Nullable + public BlockState getStateWithDirection(BlockState state, BlockGetter getter, BlockPos pos, Direction face) { + return this.multifaceBlock.getStateForPlacement(state, getter, pos, face); + } + + protected boolean canGrow(BlockGetter getter, BlockPos pos, BlockPos growPos, Direction direction, BlockState state) { + return state.isAir() || state.is(this.multifaceBlock) || state.is(Blocks.WATER) && state.getFluidState().isSource(); + } + + @Override + public boolean canGrow(BlockGetter getter, BlockPos pos, GrowPos growPos) { + BlockState state = getter.getBlockState(growPos.pos()); + return this.canGrow(getter, pos, growPos.pos(), growPos.face(), state) && ((SculkVeinBlock)this.multifaceBlock).canGrowWithDirection(getter, state, growPos.pos(), growPos.face()); + } + } + + public interface GrowChecker { + @Nullable BlockState getStateWithDirection(BlockState state, BlockGetter getter, BlockPos pos, Direction face); + + boolean canGrow(BlockGetter getter, BlockPos pos, GrowPos growPos); + + default GrowType[] getGrowTypes() { + return GROW_TYPES; + } + + default boolean hasDirection(BlockState state, Direction direction) { + return SculkVeinBlock.hasFace(state, direction); + } + + default boolean canGrow(BlockState state) { + return false; + } + + default boolean canGrow(BlockState state, Direction direction) { + return this.canGrow(state) || this.hasDirection(state, direction); + } + + default boolean place(LevelAccessor world, GrowPos growPos, BlockState state, boolean postProcess) { + BlockState blockState = this.getStateWithDirection(state, world, growPos.pos(), growPos.face()); + if (blockState != null) { + if (postProcess) { + world.getChunk(growPos.pos()).markPosForPostprocessing(growPos.pos()); + } + return world.setBlock(growPos.pos(), blockState, 2); + } + return false; + } + } + + public interface GrowPosPredicate { + boolean test(BlockGetter getter, BlockPos pos, GrowPos growPos); + } + + public enum GrowType { + SAME_POSITION { + @Override + public GrowPos getGrowPos(BlockPos pos, Direction newDirection, Direction oldDirection) { + return new GrowPos(pos, newDirection); + } + }, + SAME_PLANE { + @Override + public GrowPos getGrowPos(BlockPos pos, Direction newDirection, Direction oldDirection) { + return new GrowPos(pos.relative(newDirection), oldDirection); + } + }, + WRAP_AROUND { + @Override + public GrowPos getGrowPos(BlockPos pos, Direction newDirection, Direction oldDirection) { + return new GrowPos(pos.relative(newDirection).relative(oldDirection), newDirection.getOpposite()); + } + }; + + public abstract GrowPos getGrowPos(BlockPos pos, Direction newDirection, Direction oldDirection); + } + + public record GrowPos(BlockPos pos, Direction face) {} +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/api/ColorRegistry.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/api/ColorRegistry.java new file mode 100644 index 0000000..6d29e0d --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/api/ColorRegistry.java @@ -0,0 +1,25 @@ +package com.cursedcauldron.wildbackport.core.api; + +import dev.architectury.injectables.annotations.ExpectPlatform; +import net.minecraft.client.color.block.BlockColor; +import net.minecraft.client.color.item.ItemColor; +import net.minecraft.world.level.ItemLike; +import net.minecraft.world.level.block.Block; + +import java.util.function.Supplier; + +//<> + +public class ColorRegistry { + @SafeVarargs + @ExpectPlatform + public static void register(ItemColor itemColor, Supplier... items) { + throw new AssertionError(); + } + + @SafeVarargs + @ExpectPlatform + public static void register(BlockColor blockColor, Supplier... blocks) { + throw new AssertionError(); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/api/CoreRegistry.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/api/CoreRegistry.java new file mode 100644 index 0000000..eed3994 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/api/CoreRegistry.java @@ -0,0 +1,52 @@ +package com.cursedcauldron.wildbackport.core.api; + +import dev.architectury.injectables.annotations.ExpectPlatform; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceLocation; + +import java.util.function.Supplier; + +/** + * @author Trikzon & Andante + */ +public abstract class CoreRegistry { + protected final Registry registry; + protected final String modId; + protected boolean isPresent; + + protected CoreRegistry(Registry registry, String modId) { + this.registry = registry; + this.modId = modId; + this.isPresent = false; + } + + @ExpectPlatform + public static CoreRegistry create(Registry key, String modId) { + throw new AssertionError(); + } + + public abstract Supplier register(String key, Supplier entry); + + public void register() { + if (this.isPresent) throw new IllegalArgumentException("Duplication of Registry: " + this.registry); + this.isPresent = true; + this.bootstrap(); + } + + public abstract void bootstrap(); + + public static class DefaultRegistry extends CoreRegistry { + public DefaultRegistry(Registry registry, String modId) { + super(registry, modId); + } + + @Override + public Supplier register(String key, Supplier entry) { + E registry = Registry.register(this.registry, new ResourceLocation(this.modId, key), entry.get()); + return () -> registry; + } + + @Override + public void bootstrap() {} + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/api/MobRegistry.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/api/MobRegistry.java new file mode 100644 index 0000000..ca754b9 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/api/MobRegistry.java @@ -0,0 +1,15 @@ +package com.cursedcauldron.wildbackport.core.api; + +import dev.architectury.injectables.annotations.ExpectPlatform; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.attributes.AttributeSupplier; + +import java.util.function.Supplier; + +public class MobRegistry { + @ExpectPlatform + public static void registerAttributes(Supplier> type, Supplier builder) { + throw new AssertionError(); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/api/ParticleRegistry.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/api/ParticleRegistry.java new file mode 100644 index 0000000..6806a47 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/api/ParticleRegistry.java @@ -0,0 +1,26 @@ +package com.cursedcauldron.wildbackport.core.api; + +import dev.architectury.injectables.annotations.ExpectPlatform; +import net.minecraft.client.particle.ParticleProvider; +import net.minecraft.client.particle.SpriteSet; +import net.minecraft.core.particles.ParticleOptions; +import net.minecraft.core.particles.ParticleType; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Supplier; + +public class ParticleRegistry { + @ExpectPlatform + public static > void create(Supplier

type, ParticleProvider provider) { + throw new AssertionError(); + } + + @ExpectPlatform + public static > void create(Supplier

type, Factory provider) { + throw new AssertionError(); + } + + public interface Factory { + @NotNull ParticleProvider create(SpriteSet sprites); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/api/RenderRegistry.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/api/RenderRegistry.java new file mode 100644 index 0000000..7cee5e9 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/api/RenderRegistry.java @@ -0,0 +1,39 @@ +package com.cursedcauldron.wildbackport.core.api; + +import dev.architectury.injectables.annotations.ExpectPlatform; +import net.minecraft.client.model.geom.ModelLayerLocation; +import net.minecraft.client.model.geom.builders.LayerDefinition; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; + +import java.util.function.Supplier; + +//<> + +public class RenderRegistry { + @ExpectPlatform + public static void setBlockRenderType(RenderType type, Block... blocks) { + throw new AssertionError(); + } + + @ExpectPlatform + public static void setBlockEntityRender(Supplier> type, BlockEntityRendererProvider provider) { + throw new AssertionError(); + } + + @ExpectPlatform + public static void setEntityRender(Supplier> type, EntityRendererProvider provider) { + throw new AssertionError(); + } + + @ExpectPlatform + public static void setLayerDefinition(ModelLayerLocation layer, Supplier definition) { + throw new AssertionError(); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/api/TagRegistry.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/api/TagRegistry.java new file mode 100644 index 0000000..3b5c9c9 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/api/TagRegistry.java @@ -0,0 +1,22 @@ +package com.cursedcauldron.wildbackport.core.api; + +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.TagKey; + +//<> + +public record TagRegistry(Registry registry, String modId) { + public static TagRegistry create(Registry key, String modId) { + return new TagRegistry<>(key, modId); + } + + public TagKey create(String key) { + return TagKey.create(this.registry.key(), new ResourceLocation(this.modId, key)); + } + + /** + * apparently initializing them helps a lot + */ + public void bootstrap() {} +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/api/WoodTypeRegistry.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/api/WoodTypeRegistry.java new file mode 100644 index 0000000..cae97c9 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/api/WoodTypeRegistry.java @@ -0,0 +1,12 @@ +package com.cursedcauldron.wildbackport.core.api; + +import dev.architectury.injectables.annotations.ExpectPlatform; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.block.state.properties.WoodType; + +public class WoodTypeRegistry { + @ExpectPlatform + public static WoodType create(ResourceLocation location) { + throw new AssertionError(); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/ActivityAccessor.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/ActivityAccessor.java new file mode 100644 index 0000000..0d44980 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/ActivityAccessor.java @@ -0,0 +1,13 @@ +package com.cursedcauldron.wildbackport.core.mixin.access; + +import net.minecraft.world.entity.schedule.Activity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(Activity.class) +public interface ActivityAccessor { + @Invoker("") + static Activity createActivity(String string) { + throw new UnsupportedOperationException(); + } +} diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/CriteriaTriggersAccessor.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/CriteriaTriggersAccessor.java new file mode 100644 index 0000000..d97f3ba --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/CriteriaTriggersAccessor.java @@ -0,0 +1,14 @@ +package com.cursedcauldron.wildbackport.core.mixin.access; + +import net.minecraft.advancements.CriteriaTriggers; +import net.minecraft.advancements.CriterionTrigger; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(CriteriaTriggers.class) +public interface CriteriaTriggersAccessor { + @Invoker + static > T callRegister(T criterionTrigger) { + throw new UnsupportedOperationException(); + } +} diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/DamageSourceAccessor.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/DamageSourceAccessor.java new file mode 100644 index 0000000..e38fc32 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/DamageSourceAccessor.java @@ -0,0 +1,11 @@ +package com.cursedcauldron.wildbackport.core.mixin.access; + +import net.minecraft.world.damagesource.DamageSource; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(DamageSource.class) +public interface DamageSourceAccessor { + @Invoker + DamageSource callBypassArmor(); +} diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/DoorBlockAccessor.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/DoorBlockAccessor.java new file mode 100644 index 0000000..f41a5f9 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/DoorBlockAccessor.java @@ -0,0 +1,14 @@ +package com.cursedcauldron.wildbackport.core.mixin.access; + +import net.minecraft.world.level.block.DoorBlock; +import net.minecraft.world.level.block.state.BlockBehaviour; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(DoorBlock.class) +public interface DoorBlockAccessor { + @Invoker("") + static DoorBlock createDoorBlock(BlockBehaviour.Properties properties) { + throw new UnsupportedOperationException(); + } +} diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/MemoryModuleTypeAccessor.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/MemoryModuleTypeAccessor.java new file mode 100644 index 0000000..f391d66 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/MemoryModuleTypeAccessor.java @@ -0,0 +1,16 @@ +package com.cursedcauldron.wildbackport.core.mixin.access; + +import com.mojang.serialization.Codec; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +import java.util.Optional; + +@Mixin(MemoryModuleType.class) +public interface MemoryModuleTypeAccessor { + @Invoker("") + static MemoryModuleType createMemoryModuleType(Optional> optional) { + throw new UnsupportedOperationException(); + } +} diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/MobAccessor.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/MobAccessor.java new file mode 100644 index 0000000..9604e53 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/MobAccessor.java @@ -0,0 +1,20 @@ +package com.cursedcauldron.wildbackport.core.mixin.access; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.Mob; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(Mob.class) +public interface MobAccessor { + @Accessor + Entity getLeashHolder(); + + @Accessor + CompoundTag getLeashInfoTag(); + + @Invoker + void callRestoreLeashFromSave(); +} diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/ModelPartAccessor.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/ModelPartAccessor.java new file mode 100644 index 0000000..9af7318 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/ModelPartAccessor.java @@ -0,0 +1,13 @@ +package com.cursedcauldron.wildbackport.core.mixin.access; + +import net.minecraft.client.model.geom.ModelPart; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.util.Map; + +@Mixin(ModelPart.class) +public interface ModelPartAccessor { + @Accessor + Map getChildren(); +} diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/PressurePlateBlockAccessor.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/PressurePlateBlockAccessor.java new file mode 100644 index 0000000..8948e1c --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/PressurePlateBlockAccessor.java @@ -0,0 +1,14 @@ +package com.cursedcauldron.wildbackport.core.mixin.access; + +import net.minecraft.world.level.block.PressurePlateBlock; +import net.minecraft.world.level.block.state.BlockBehaviour; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(PressurePlateBlock.class) +public interface PressurePlateBlockAccessor { + @Invoker("") + static PressurePlateBlock createPressurePlateBlock(PressurePlateBlock.Sensitivity sensitivity, BlockBehaviour.Properties properties) { + throw new UnsupportedOperationException(); + } +} diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/RecordItemAccessor.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/RecordItemAccessor.java new file mode 100644 index 0000000..f3a44d0 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/RecordItemAccessor.java @@ -0,0 +1,15 @@ +package com.cursedcauldron.wildbackport.core.mixin.access; + +import net.minecraft.sounds.SoundEvent; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.RecordItem; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(RecordItem.class) +public interface RecordItemAccessor { + @Invoker("") + static RecordItem createRecordItem(int i, SoundEvent soundEvent, Item.Properties properties) { + throw new UnsupportedOperationException(); + } +} diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/SensorTypeAccessor.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/SensorTypeAccessor.java new file mode 100644 index 0000000..83d7bde --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/SensorTypeAccessor.java @@ -0,0 +1,16 @@ +package com.cursedcauldron.wildbackport.core.mixin.access; + +import net.minecraft.world.entity.ai.sensing.Sensor; +import net.minecraft.world.entity.ai.sensing.SensorType; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +import java.util.function.Supplier; + +@Mixin(SensorType.class) +public interface SensorTypeAccessor { + @Invoker("") + static > SensorType createSensorType(Supplier supplier) { + throw new UnsupportedOperationException(); + } +} diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/SheetsAccessor.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/SheetsAccessor.java new file mode 100644 index 0000000..70a72f8 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/SheetsAccessor.java @@ -0,0 +1,15 @@ +package com.cursedcauldron.wildbackport.core.mixin.access; + +import net.minecraft.client.renderer.Sheets; +import net.minecraft.client.resources.model.Material; +import net.minecraft.world.level.block.state.properties.WoodType; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(Sheets.class) +public interface SheetsAccessor { + @Invoker + static Material callCreateSignMaterial(WoodType woodType) { + throw new UnsupportedOperationException(); + } +} diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/SimpleParticleTypeAccessor.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/SimpleParticleTypeAccessor.java new file mode 100644 index 0000000..0944bff --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/SimpleParticleTypeAccessor.java @@ -0,0 +1,13 @@ +package com.cursedcauldron.wildbackport.core.mixin.access; + +import net.minecraft.core.particles.SimpleParticleType; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(SimpleParticleType.class) +public interface SimpleParticleTypeAccessor { + @Invoker("") + static SimpleParticleType createSimpleParticleType(boolean bl) { + throw new UnsupportedOperationException(); + } +} diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/StairBlockAccessor.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/StairBlockAccessor.java new file mode 100644 index 0000000..c597157 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/StairBlockAccessor.java @@ -0,0 +1,15 @@ +package com.cursedcauldron.wildbackport.core.mixin.access; + +import net.minecraft.world.level.block.StairBlock; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(StairBlock.class) +public interface StairBlockAccessor { + @Invoker("") + static StairBlock createStairBlock(BlockState blockState, BlockBehaviour.Properties properties) { + throw new UnsupportedOperationException(); + } +} diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/StructureTemplatePoolAccessor.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/StructureTemplatePoolAccessor.java new file mode 100644 index 0000000..25ad62d --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/StructureTemplatePoolAccessor.java @@ -0,0 +1,27 @@ +package com.cursedcauldron.wildbackport.core.mixin.access; + +import com.mojang.datafixers.util.Pair; +import net.minecraft.world.level.levelgen.structure.pools.StructurePoolElement; +import net.minecraft.world.level.levelgen.structure.pools.StructureTemplatePool; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.util.List; + +@Mixin(StructureTemplatePool.class) +public interface StructureTemplatePoolAccessor { + @Accessor + List> getRawTemplates(); + + @Mutable + @Accessor + void setRawTemplates(List> rawTemplates); + + @Accessor + List getTemplates(); + + @Mutable + @Accessor + void setTemplates(List templates); +} diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/TrapDoorBlockAccessor.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/TrapDoorBlockAccessor.java new file mode 100644 index 0000000..989611f --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/TrapDoorBlockAccessor.java @@ -0,0 +1,14 @@ +package com.cursedcauldron.wildbackport.core.mixin.access; + +import net.minecraft.world.level.block.TrapDoorBlock; +import net.minecraft.world.level.block.state.BlockBehaviour; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(TrapDoorBlock.class) +public interface TrapDoorBlockAccessor { + @Invoker("") + static TrapDoorBlock createTrapDoorBlock(BlockBehaviour.Properties properties) { + throw new UnsupportedOperationException(); + } +} diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/WoodButtonBlockAccessor.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/WoodButtonBlockAccessor.java new file mode 100644 index 0000000..4139a84 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/WoodButtonBlockAccessor.java @@ -0,0 +1,14 @@ +package com.cursedcauldron.wildbackport.core.mixin.access; + +import net.minecraft.world.level.block.WoodButtonBlock; +import net.minecraft.world.level.block.state.BlockBehaviour; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(WoodButtonBlock.class) +public interface WoodButtonBlockAccessor { + @Invoker("") + static WoodButtonBlock createWoodButtonBlock(BlockBehaviour.Properties properties) { + throw new UnsupportedOperationException(); + } +} diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/WoodTypeAccessor.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/WoodTypeAccessor.java new file mode 100644 index 0000000..947d7da --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/WoodTypeAccessor.java @@ -0,0 +1,18 @@ +package com.cursedcauldron.wildbackport.core.mixin.access; + +import net.minecraft.world.level.block.state.properties.WoodType; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(WoodType.class) +public interface WoodTypeAccessor { + @Invoker("") + static WoodType createWoodType(String string) { + throw new UnsupportedOperationException(); + } + + @Invoker + static WoodType callRegister(WoodType woodType) { + throw new UnsupportedOperationException(); + } +} diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/client/LocalPlayerMixin.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/client/LocalPlayerMixin.java new file mode 100644 index 0000000..f9b7cab --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/client/LocalPlayerMixin.java @@ -0,0 +1,35 @@ +package com.cursedcauldron.wildbackport.core.mixin.client; + +import com.cursedcauldron.wildbackport.common.registry.WBEnchantments; +import net.minecraft.client.player.Input; +import net.minecraft.client.player.KeyboardInput; +import net.minecraft.client.player.LocalPlayer; +import net.minecraft.util.Mth; +import net.minecraft.world.item.enchantment.EnchantmentHelper; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +//<> + +@Mixin(LocalPlayer.class) +public class LocalPlayerMixin { + @Shadow public Input input; + + @Inject(method = "aiStep", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/tutorial/Tutorial;onInput(Lnet/minecraft/client/player/Input;)V", shift = At.Shift.AFTER)) + private void wb$aiStep(CallbackInfo ci) { + LocalPlayer player = LocalPlayer.class.cast(this); + double swiftnessModifier = EnchantmentHelper.getEnchantmentLevel(WBEnchantments.SWIFT_SNEAK.get(), player) * 0.15D; + double slownessModifier = Mth.clamp(0.3D + swiftnessModifier, 0.0D, 1.0D); + if (this.input instanceof KeyboardInput input) { + input.forwardImpulse = input.up == input.down ? 0.0F : (input.up ? 1.0F : -1.0F); + input.leftImpulse = input.left == input.right ? 0.0F : (input.left ? 1.0F : -1.0F); + if (player.isCrouching()) { + input.leftImpulse = (float)((double)input.leftImpulse * slownessModifier); + input.forwardImpulse = (float)((double)input.forwardImpulse * slownessModifier); + } + } + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/client/ModelPartMixin.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/client/ModelPartMixin.java new file mode 100644 index 0000000..f36e93b --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/client/ModelPartMixin.java @@ -0,0 +1,140 @@ +package com.cursedcauldron.wildbackport.core.mixin.client; + +import com.cursedcauldron.wildbackport.client.animation.api.Animated; +import com.cursedcauldron.wildbackport.client.render.model.Drawable; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.model.geom.PartPose; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.List; +import java.util.Map; + +//<> + +@Mixin(ModelPart.class) +public abstract class ModelPartMixin implements Animated, Drawable { + @Shadow + public boolean visible; + @Shadow @Final + private List cubes; + @Shadow @Final private Map children; + @Shadow public abstract void translateAndRotate(PoseStack pose); + + private float xScale = 1.0F; + private float yScale = 1.0F; + private float zScale = 1.0F; + private PartPose defaultPose = PartPose.ZERO; + private boolean skipDraw; + + @Override + public PartPose getDefaultPose() { + return this.defaultPose; + } + + @Override + public void setDefaultPose(PartPose pose) { + this.defaultPose = pose; + } + + @Inject(method = "loadPose", at = @At("TAIL")) + private void wb$load(PartPose pose, CallbackInfo ci) { + this.xScale = 1.0F; + this.yScale = 1.0F; + this.zScale = 1.0F; + } + + @Inject(method = "copyFrom", at = @At("TAIL")) + private void wb$copy(ModelPart part, CallbackInfo ci) { + this.setXScale(((Animated)(Object)part).xScale()); + this.setYScale(((Animated)(Object)part).yScale()); + this.setZScale(((Animated)(Object)part).zScale()); + } + + @Inject(method = "translateAndRotate", at = @At("TAIL")) + private void wb$moveAndScale(PoseStack stack, CallbackInfo ci) { + if (this.xScale != 1.0F || this.yScale != 1.0F || this.zScale != 1.0F) { + stack.scale(this.xScale, this.yScale, this.zScale); + } + } + + @Inject(method = "render(Lcom/mojang/blaze3d/vertex/PoseStack;Lcom/mojang/blaze3d/vertex/VertexConsumer;IIFFFF)V", at = @At("HEAD"), cancellable = true) + private void wb$render(PoseStack pose, VertexConsumer consumer, int light, int delta, float red, float green, float blue, float alpha, CallbackInfo ci) { + if (this.skipDraw()) { + if (this.visible) { + if (!this.cubes.isEmpty() || !this.children.isEmpty()) { + pose.pushPose(); + this.translateAndRotate(pose); + + for (ModelPart part : this.children.values()) { + part.render(pose, consumer, light, delta, red, green, blue, alpha); + } + + pose.popPose(); + } + } + ci.cancel(); + } + } + + @Override + public float xScale() { + return this.xScale; + } + + @Override + public void setXScale(float x) { + this.xScale = x; + } + + @Override + public void increaseXScale(float x) { + this.xScale += x; + } + + @Override + public float yScale() { + return this.yScale; + } + + @Override + public void setYScale(float y) { + this.yScale = y; + } + + @Override + public void increaseYScale(float y) { + this.yScale += y; + } + + @Override + public float zScale() { + return this.zScale; + } + + @Override + public void setZScale(float z) { + this.zScale = z; + } + + @Override + public void increaseZScale(float z) { + this.zScale += z; + } + + @Override + public boolean skipDraw() { + return this.skipDraw; + } + + @Override + public void setSkipDraw(boolean skipDraw) { + this.skipDraw = skipDraw; + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/client/PartDefinitionMixin.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/client/PartDefinitionMixin.java new file mode 100644 index 0000000..c503e26 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/client/PartDefinitionMixin.java @@ -0,0 +1,23 @@ +package com.cursedcauldron.wildbackport.core.mixin.client; + +import com.cursedcauldron.wildbackport.client.animation.api.Animated; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.model.geom.PartPose; +import net.minecraft.client.model.geom.builders.PartDefinition; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(PartDefinition.class) +public class PartDefinitionMixin { + @Shadow @Final private PartPose partPose; + + @Inject(method = "bake", at = @At(value = "RETURN"), cancellable = true) + private void wb$bake(int i, int j, CallbackInfoReturnable cir) { + ((Animated)(Object)cir.getReturnValue()).setDefaultPose(this.partPose); + cir.setReturnValue(cir.getReturnValue()); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/common/BeardifierMixin.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/common/BeardifierMixin.java new file mode 100644 index 0000000..7d920f1 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/common/BeardifierMixin.java @@ -0,0 +1,8 @@ +package com.cursedcauldron.wildbackport.core.mixin.common; + +import net.minecraft.world.level.levelgen.Beardifier; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(Beardifier.class) +public class BeardifierMixin { +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/common/BlockEntityTypeMixin.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/common/BlockEntityTypeMixin.java new file mode 100644 index 0000000..424a0a6 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/common/BlockEntityTypeMixin.java @@ -0,0 +1,21 @@ +package com.cursedcauldron.wildbackport.core.mixin.common; + +import net.minecraft.world.level.block.SignBlock; +import net.minecraft.world.level.block.WallSignBlock; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(BlockEntityType.class) +public class BlockEntityTypeMixin { + @SuppressWarnings("EqualsBetweenInconvertibleTypes") + @Inject(method = "isValid", at = @At("HEAD"), cancellable = true) + private void wb$isValid(BlockState state, CallbackInfoReturnable cir) { + if (BlockEntityType.SIGN.equals(this) && (state.getBlock() instanceof SignBlock || state.getBlock() instanceof WallSignBlock)) { + cir.setReturnValue(true); + } + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/common/LivingEntityMixin.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/common/LivingEntityMixin.java new file mode 100644 index 0000000..e3f6ae6 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/common/LivingEntityMixin.java @@ -0,0 +1,53 @@ +package com.cursedcauldron.wildbackport.core.mixin.common; + +import com.cursedcauldron.wildbackport.common.entities.access.EntityExperience; +import com.cursedcauldron.wildbackport.common.registry.WBGameEvents; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(LivingEntity.class) +public abstract class LivingEntityMixin extends Entity implements EntityExperience { + @Shadow @Nullable protected Player lastHurtByPlayer; + private boolean expDroppingDisabled; + + public LivingEntityMixin(EntityType type, Level level) { + super(type, level); + } + + @Shadow protected abstract int getExperienceReward(Player player); + + @Inject(method = "die", at = @At("HEAD")) + private void wb$die(DamageSource source, CallbackInfo ci) { + this.gameEvent(WBGameEvents.ENTITY_DIE.get()); + } + + @Override + public void disableExpDrop() { + this.expDroppingDisabled = true; + } + + @Override + public boolean isExpDropDisabled() { + return this.expDroppingDisabled; + } + + @Override + public int getExpToDrop() { + return this.getExperienceReward(this.lastHurtByPlayer); + } + + @Inject(method = "dropExperience", at = @At("HEAD"), cancellable = true) + private void wb$dropExp(CallbackInfo ci) { + if (this.isExpDropDisabled()) ci.cancel(); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/common/PlayerMixin.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/common/PlayerMixin.java new file mode 100644 index 0000000..88efe65 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/common/PlayerMixin.java @@ -0,0 +1,48 @@ +package com.cursedcauldron.wildbackport.core.mixin.common; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.common.entities.Warden; +import com.cursedcauldron.wildbackport.common.entities.access.WardenTracker; +import com.cursedcauldron.wildbackport.common.entities.warden.WardenSpawnTracker; +import com.mojang.serialization.Dynamic; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtOps; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +//<> + +@Mixin(Player.class) +public class PlayerMixin implements WardenTracker { + private final Player player = Player.class.cast(this); + private WardenSpawnTracker spawnTracker = new WardenSpawnTracker(0, 0, 0); + + @Inject(method = "tick", at = @At("TAIL")) + private void wb$tick(CallbackInfo ci) { + if (!player.level.isClientSide) this.spawnTracker.tick(); + } + + @Inject(method = "readAdditionalSaveData", at = @At("TAIL")) + private void wb$readData(CompoundTag tag, CallbackInfo ci) { + if (tag.contains("warden_spawn_tracker", 10)) WardenSpawnTracker.CODEC.parse(new Dynamic<>(NbtOps.INSTANCE, tag.get("warden_spawn_tracker"))).resultOrPartial(WildBackport.LOGGER::error).ifPresent(tracker -> this.spawnTracker = tracker); + } + + @Inject(method = "addAdditionalSaveData", at = @At("TAIL")) + private void wb$writeData(CompoundTag tag, CallbackInfo ci) { + WardenSpawnTracker.CODEC.encodeStart(NbtOps.INSTANCE, this.spawnTracker).resultOrPartial(WildBackport.LOGGER::error).ifPresent(tracker -> tag.put("warden_spawn_Tracker", tracker)); + } + + @Inject(method = "blockUsingShield", at = @At("HEAD")) + private void wb$blockShield(LivingEntity entity, CallbackInfo ci) { + if (entity instanceof Warden) player.disableShield(true); + } + + @Override + public WardenSpawnTracker getWardenSpawnTracker() { + return this.spawnTracker; + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/extension/BoatTypeMixin.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/extension/BoatTypeMixin.java new file mode 100644 index 0000000..d16bd0e --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/extension/BoatTypeMixin.java @@ -0,0 +1,49 @@ +package com.cursedcauldron.wildbackport.core.mixin.extension; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.common.entities.access.api.BoatTypes; +import com.cursedcauldron.wildbackport.common.registry.WBBlocks; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.vehicle.Boat; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.gen.Invoker; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +//<> + +@Mixin(Boat.Type.class) +public class BoatTypeMixin { + @Shadow @Mutable @Final private static Boat.Type[] $VALUES; + + @Invoker("") + public static Boat.Type create(String internal, int id, Block planks, String name) { + throw new AssertionError(); + } + + @Inject(method = "", at = @At(value = "FIELD", target = "Lnet/minecraft/world/entity/vehicle/Boat$Type;$VALUES:[Lnet/minecraft/world/entity/vehicle/Boat$Type;", shift = At.Shift.AFTER)) + private static void wb$addBoat(CallbackInfo ci) { + List types = new ArrayList<>(Arrays.asList($VALUES)); + Boat.Type last = types.get(types.size() - 1); + int i = 1; + +// for (BoatTypes type : BoatTypes.values()) { + types.add(create("mangrove", last.ordinal() + 1, Registry.BLOCK.get(new ResourceLocation(WildBackport.MOD_ID, "mangrove_planks")), "mangrove")); +// i++; +// } + + $VALUES = types.toArray(new Boat.Type[0]); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/extension/PoseMixin.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/extension/PoseMixin.java new file mode 100644 index 0000000..29f8230 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/extension/PoseMixin.java @@ -0,0 +1,39 @@ +package com.cursedcauldron.wildbackport.core.mixin.extension; + +import com.cursedcauldron.wildbackport.common.entities.access.api.Poses; +import net.minecraft.world.entity.Pose; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.gen.Invoker; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +@Mixin(Pose.class) +public class PoseMixin { + @Shadow @Mutable @Final private static Pose[] $VALUES; + + @Invoker("") + public static Pose create(String name, int id) { + throw new AssertionError(); + } + + @Inject(method = "", at = @At(value = "FIELD", target = "Lnet/minecraft/world/entity/Pose;$VALUES:[Lnet/minecraft/world/entity/Pose;", shift = At.Shift.AFTER)) + private static void wb$addPose(CallbackInfo ci) { + List poses = new ArrayList<>(Arrays.asList($VALUES)); + Pose last = poses.get(poses.size() - 1); + int i = 1; + for (Poses pose : Poses.values()) { + poses.add(create(pose.name(), last.ordinal() + i)); + i++; + } + + $VALUES = poses.toArray(new Pose[0]); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/network/ClientPacketListenerMixin.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/network/ClientPacketListenerMixin.java new file mode 100644 index 0000000..4d06c04 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/network/ClientPacketListenerMixin.java @@ -0,0 +1,8 @@ +package com.cursedcauldron.wildbackport.core.mixin.network; + +import net.minecraft.client.multiplayer.ClientPacketListener; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(ClientPacketListener.class) +public class ClientPacketListenerMixin { +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/network/MultiPlayerGameModeMixin.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/network/MultiPlayerGameModeMixin.java new file mode 100644 index 0000000..a15b049 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/network/MultiPlayerGameModeMixin.java @@ -0,0 +1,23 @@ +package com.cursedcauldron.wildbackport.core.mixin.network; + +import com.cursedcauldron.wildbackport.common.entities.ChestBoat; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.MultiPlayerGameMode; +import net.minecraft.client.player.LocalPlayer; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(MultiPlayerGameMode.class) +public class MultiPlayerGameModeMixin { + @Shadow @Final private Minecraft minecraft; + + @Inject(method = "isServerControlledInventory", at = @At("TAIL"), cancellable = true) + private void wb$handleInventory(CallbackInfoReturnable cir) { + LocalPlayer player = this.minecraft.player; + cir.setReturnValue(player != null && player.isPassenger() && player.getVehicle() instanceof ChestBoat || cir.getReturnValue()); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/network/ServerGamePacketListenerImplMixin.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/network/ServerGamePacketListenerImplMixin.java new file mode 100644 index 0000000..c06f7cd --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/network/ServerGamePacketListenerImplMixin.java @@ -0,0 +1,25 @@ +package com.cursedcauldron.wildbackport.core.mixin.network; + +import com.cursedcauldron.wildbackport.common.entities.ChestBoat; +import net.minecraft.network.protocol.game.ServerboundPlayerCommandPacket; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.ServerGamePacketListenerImpl; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ServerGamePacketListenerImpl.class) +public class ServerGamePacketListenerImplMixin { + @Shadow public ServerPlayer player; + + @Inject(method = "handlePlayerCommand", at = @At("HEAD")) + private void wb$handleInventory(ServerboundPlayerCommandPacket packet, CallbackInfo ci) { + if (packet.getAction() == ServerboundPlayerCommandPacket.Action.OPEN_INVENTORY) { + if (this.player.getVehicle() instanceof ChestBoat boat) { + boat.openInventory(this.player); + } + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/architectury.common.json b/common/src/main/resources/architectury.common.json new file mode 100644 index 0000000..1c7de55 --- /dev/null +++ b/common/src/main/resources/architectury.common.json @@ -0,0 +1,3 @@ +{ + "accessWidener": "wildbackport.accesswidener" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/frogspawn.json b/common/src/main/resources/assets/wildbackport/blockstates/frogspawn.json new file mode 100644 index 0000000..39d94c6 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/frogspawn.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "wildbackport:block/frogspawn" + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/mangrove_button.json b/common/src/main/resources/assets/wildbackport/blockstates/mangrove_button.json new file mode 100644 index 0000000..0102118 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/mangrove_button.json @@ -0,0 +1,118 @@ +{ + "variants": { + "face=ceiling,facing=east,powered=false": { + "model": "wildbackport:block/mangrove_button", + "y": 270, + "x": 180 + }, + "face=ceiling,facing=east,powered=true": { + "model": "wildbackport:block/mangrove_button_pressed", + "y": 270, + "x": 180 + }, + "face=ceiling,facing=north,powered=false": { + "model": "wildbackport:block/mangrove_button", + "y": 180, + "x": 180 + }, + "face=ceiling,facing=north,powered=true": { + "model": "wildbackport:block/mangrove_button_pressed", + "y": 180, + "x": 180 + }, + "face=ceiling,facing=south,powered=false": { + "model": "wildbackport:block/mangrove_button", + "x": 180 + }, + "face=ceiling,facing=south,powered=true": { + "model": "wildbackport:block/mangrove_button_pressed", + "x": 180 + }, + "face=ceiling,facing=west,powered=false": { + "model": "wildbackport:block/mangrove_button", + "y": 90, + "x": 180 + }, + "face=ceiling,facing=west,powered=true": { + "model": "wildbackport:block/mangrove_button_pressed", + "y": 90, + "x": 180 + }, + "face=floor,facing=east,powered=false": { + "model": "wildbackport:block/mangrove_button", + "y": 90 + }, + "face=floor,facing=east,powered=true": { + "model": "wildbackport:block/mangrove_button_pressed", + "y": 90 + }, + "face=floor,facing=north,powered=false": { + "model": "wildbackport:block/mangrove_button" + }, + "face=floor,facing=north,powered=true": { + "model": "wildbackport:block/mangrove_button_pressed" + }, + "face=floor,facing=south,powered=false": { + "model": "wildbackport:block/mangrove_button", + "y": 180 + }, + "face=floor,facing=south,powered=true": { + "model": "wildbackport:block/mangrove_button_pressed", + "y": 180 + }, + "face=floor,facing=west,powered=false": { + "model": "wildbackport:block/mangrove_button", + "y": 270 + }, + "face=floor,facing=west,powered=true": { + "model": "wildbackport:block/mangrove_button_pressed", + "y": 270 + }, + "face=wall,facing=east,powered=false": { + "model": "wildbackport:block/mangrove_button", + "y": 90, + "x": 90, + "uvlock": true + }, + "face=wall,facing=east,powered=true": { + "model": "wildbackport:block/mangrove_button_pressed", + "y": 90, + "x": 90, + "uvlock": true + }, + "face=wall,facing=north,powered=false": { + "model": "wildbackport:block/mangrove_button", + "x": 90, + "uvlock": true + }, + "face=wall,facing=north,powered=true": { + "model": "wildbackport:block/mangrove_button_pressed", + "x": 90, + "uvlock": true + }, + "face=wall,facing=south,powered=false": { + "model": "wildbackport:block/mangrove_button", + "y": 180, + "x": 90, + "uvlock": true + }, + "face=wall,facing=south,powered=true": { + "model": "wildbackport:block/mangrove_button_pressed", + "y": 180, + "x": 90, + "uvlock": true + }, + "face=wall,facing=west,powered=false": { + "model": "wildbackport:block/mangrove_button", + "y": 270, + "x": 90, + "uvlock": true + }, + "face=wall,facing=west,powered=true": { + "model": "wildbackport:block/mangrove_button_pressed", + "y": 270, + "x": 90, + "uvlock": true + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/mangrove_door.json b/common/src/main/resources/assets/wildbackport/blockstates/mangrove_door.json new file mode 100644 index 0000000..ab01a1e --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/mangrove_door.json @@ -0,0 +1,124 @@ +{ + "variants": { + "facing=east,half=lower,hinge=left,open=false": { + "model": "wildbackport:block/mangrove_door_bottom" + }, + "facing=east,half=lower,hinge=left,open=true": { + "model": "wildbackport:block/mangrove_door_bottom_hinge", + "y": 90 + }, + "facing=east,half=lower,hinge=right,open=false": { + "model": "wildbackport:block/mangrove_door_bottom_hinge" + }, + "facing=east,half=lower,hinge=right,open=true": { + "model": "wildbackport:block/mangrove_door_bottom", + "y": 270 + }, + "facing=east,half=upper,hinge=left,open=false": { + "model": "wildbackport:block/mangrove_door_top" + }, + "facing=east,half=upper,hinge=left,open=true": { + "model": "wildbackport:block/mangrove_door_top_hinge", + "y": 90 + }, + "facing=east,half=upper,hinge=right,open=false": { + "model": "wildbackport:block/mangrove_door_top_hinge" + }, + "facing=east,half=upper,hinge=right,open=true": { + "model": "wildbackport:block/mangrove_door_top", + "y": 270 + }, + "facing=north,half=lower,hinge=left,open=false": { + "model": "wildbackport:block/mangrove_door_bottom", + "y": 270 + }, + "facing=north,half=lower,hinge=left,open=true": { + "model": "wildbackport:block/mangrove_door_bottom_hinge" + }, + "facing=north,half=lower,hinge=right,open=false": { + "model": "wildbackport:block/mangrove_door_bottom_hinge", + "y": 270 + }, + "facing=north,half=lower,hinge=right,open=true": { + "model": "wildbackport:block/mangrove_door_bottom", + "y": 180 + }, + "facing=north,half=upper,hinge=left,open=false": { + "model": "wildbackport:block/mangrove_door_top", + "y": 270 + }, + "facing=north,half=upper,hinge=left,open=true": { + "model": "wildbackport:block/mangrove_door_top_hinge" + }, + "facing=north,half=upper,hinge=right,open=false": { + "model": "wildbackport:block/mangrove_door_top_hinge", + "y": 270 + }, + "facing=north,half=upper,hinge=right,open=true": { + "model": "wildbackport:block/mangrove_door_top", + "y": 180 + }, + "facing=south,half=lower,hinge=left,open=false": { + "model": "wildbackport:block/mangrove_door_bottom", + "y": 90 + }, + "facing=south,half=lower,hinge=left,open=true": { + "model": "wildbackport:block/mangrove_door_bottom_hinge", + "y": 180 + }, + "facing=south,half=lower,hinge=right,open=false": { + "model": "wildbackport:block/mangrove_door_bottom_hinge", + "y": 90 + }, + "facing=south,half=lower,hinge=right,open=true": { + "model": "wildbackport:block/mangrove_door_bottom" + }, + "facing=south,half=upper,hinge=left,open=false": { + "model": "wildbackport:block/mangrove_door_top", + "y": 90 + }, + "facing=south,half=upper,hinge=left,open=true": { + "model": "wildbackport:block/mangrove_door_top_hinge", + "y": 180 + }, + "facing=south,half=upper,hinge=right,open=false": { + "model": "wildbackport:block/mangrove_door_top_hinge", + "y": 90 + }, + "facing=south,half=upper,hinge=right,open=true": { + "model": "wildbackport:block/mangrove_door_top" + }, + "facing=west,half=lower,hinge=left,open=false": { + "model": "wildbackport:block/mangrove_door_bottom", + "y": 180 + }, + "facing=west,half=lower,hinge=left,open=true": { + "model": "wildbackport:block/mangrove_door_bottom_hinge", + "y": 270 + }, + "facing=west,half=lower,hinge=right,open=false": { + "model": "wildbackport:block/mangrove_door_bottom_hinge", + "y": 180 + }, + "facing=west,half=lower,hinge=right,open=true": { + "model": "wildbackport:block/mangrove_door_bottom", + "y": 90 + }, + "facing=west,half=upper,hinge=left,open=false": { + "model": "wildbackport:block/mangrove_door_top", + "y": 180 + }, + "facing=west,half=upper,hinge=left,open=true": { + "model": "wildbackport:block/mangrove_door_top_hinge", + "y": 270 + }, + "facing=west,half=upper,hinge=right,open=false": { + "model": "wildbackport:block/mangrove_door_top_hinge", + "y": 180 + }, + "facing=west,half=upper,hinge=right,open=true": { + "model": "wildbackport:block/mangrove_door_top", + "y": 90 + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/mangrove_fence.json b/common/src/main/resources/assets/wildbackport/blockstates/mangrove_fence.json new file mode 100644 index 0000000..5665bc3 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/mangrove_fence.json @@ -0,0 +1,48 @@ +{ + "multipart": [ + { + "apply": { + "model": "wildbackport:block/mangrove_fence_post" + } + }, + { + "when": { + "north": "true" + }, + "apply": { + "model": "wildbackport:block/mangrove_fence_side", + "uvlock": true + } + }, + { + "when": { + "east": "true" + }, + "apply": { + "model": "wildbackport:block/mangrove_fence_side", + "y": 90, + "uvlock": true + } + }, + { + "when": { + "south": "true" + }, + "apply": { + "model": "wildbackport:block/mangrove_fence_side", + "y": 180, + "uvlock": true + } + }, + { + "when": { + "west": "true" + }, + "apply": { + "model": "wildbackport:block/mangrove_fence_side", + "y": 270, + "uvlock": true + } + } + ] +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/mangrove_fence_gate.json b/common/src/main/resources/assets/wildbackport/blockstates/mangrove_fence_gate.json new file mode 100644 index 0000000..beb5968 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/mangrove_fence_gate.json @@ -0,0 +1,80 @@ +{ + "variants": { + "facing=east,in_wall=false,open=false": { + "uvlock": true, + "y": 270, + "model": "wildbackport:block/mangrove_fence_gate" + }, + "facing=east,in_wall=false,open=true": { + "uvlock": true, + "y": 270, + "model": "wildbackport:block/mangrove_fence_gate_open" + }, + "facing=east,in_wall=true,open=false": { + "uvlock": true, + "y": 270, + "model": "wildbackport:block/mangrove_fence_gate_wall" + }, + "facing=east,in_wall=true,open=true": { + "uvlock": true, + "y": 270, + "model": "wildbackport:block/mangrove_fence_gate_wall_open" + }, + "facing=north,in_wall=false,open=false": { + "uvlock": true, + "y": 180, + "model": "wildbackport:block/mangrove_fence_gate" + }, + "facing=north,in_wall=false,open=true": { + "uvlock": true, + "y": 180, + "model": "wildbackport:block/mangrove_fence_gate_open" + }, + "facing=north,in_wall=true,open=false": { + "uvlock": true, + "y": 180, + "model": "wildbackport:block/mangrove_fence_gate_wall" + }, + "facing=north,in_wall=true,open=true": { + "uvlock": true, + "y": 180, + "model": "wildbackport:block/mangrove_fence_gate_wall_open" + }, + "facing=south,in_wall=false,open=false": { + "uvlock": true, + "model": "wildbackport:block/mangrove_fence_gate" + }, + "facing=south,in_wall=false,open=true": { + "uvlock": true, + "model": "wildbackport:block/mangrove_fence_gate_open" + }, + "facing=south,in_wall=true,open=false": { + "uvlock": true, + "model": "wildbackport:block/mangrove_fence_gate_wall" + }, + "facing=south,in_wall=true,open=true": { + "uvlock": true, + "model": "wildbackport:block/mangrove_fence_gate_wall_open" + }, + "facing=west,in_wall=false,open=false": { + "uvlock": true, + "y": 90, + "model": "wildbackport:block/mangrove_fence_gate" + }, + "facing=west,in_wall=false,open=true": { + "uvlock": true, + "y": 90, + "model": "wildbackport:block/mangrove_fence_gate_open" + }, + "facing=west,in_wall=true,open=false": { + "uvlock": true, + "y": 90, + "model": "wildbackport:block/mangrove_fence_gate_wall" + }, + "facing=west,in_wall=true,open=true": { + "uvlock": true, + "y": 90, + "model": "wildbackport:block/mangrove_fence_gate_wall_open" + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/mangrove_leaves.json b/common/src/main/resources/assets/wildbackport/blockstates/mangrove_leaves.json new file mode 100644 index 0000000..660ebe0 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/mangrove_leaves.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "wildbackport:block/mangrove_leaves" + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/mangrove_log.json b/common/src/main/resources/assets/wildbackport/blockstates/mangrove_log.json new file mode 100644 index 0000000..f184e7c --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/mangrove_log.json @@ -0,0 +1,16 @@ +{ + "variants": { + "axis=x": { + "model": "wildbackport:block/mangrove_log_horizontal", + "x": 90, + "y": 90 + }, + "axis=y": { + "model": "wildbackport:block/mangrove_log" + }, + "axis=z": { + "model": "wildbackport:block/mangrove_log_horizontal", + "x": 90 + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/mangrove_planks.json b/common/src/main/resources/assets/wildbackport/blockstates/mangrove_planks.json new file mode 100644 index 0000000..14c8947 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/mangrove_planks.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "wildbackport:block/mangrove_planks" + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/mangrove_pressure_plate.json b/common/src/main/resources/assets/wildbackport/blockstates/mangrove_pressure_plate.json new file mode 100644 index 0000000..b45ee82 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/mangrove_pressure_plate.json @@ -0,0 +1,10 @@ +{ + "variants": { + "powered=false": { + "model": "wildbackport:block/mangrove_pressure_plate" + }, + "powered=true": { + "model": "wildbackport:block/mangrove_pressure_plate_down" + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/mangrove_propagule.json b/common/src/main/resources/assets/wildbackport/blockstates/mangrove_propagule.json new file mode 100644 index 0000000..5885fd2 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/mangrove_propagule.json @@ -0,0 +1,34 @@ +{ + "variants": { + "age=0,hanging=false": { + "model": "wildbackport:block/mangrove_propagule" + }, + "age=0,hanging=true": { + "model": "wildbackport:block/mangrove_propagule_hanging_0" + }, + "age=1,hanging=false": { + "model": "wildbackport:block/mangrove_propagule" + }, + "age=1,hanging=true": { + "model": "wildbackport:block/mangrove_propagule_hanging_1" + }, + "age=2,hanging=false": { + "model": "wildbackport:block/mangrove_propagule" + }, + "age=2,hanging=true": { + "model": "wildbackport:block/mangrove_propagule_hanging_2" + }, + "age=3,hanging=false": { + "model": "wildbackport:block/mangrove_propagule" + }, + "age=3,hanging=true": { + "model": "wildbackport:block/mangrove_propagule_hanging_3" + }, + "age=4,hanging=false": { + "model": "wildbackport:block/mangrove_propagule" + }, + "age=4,hanging=true": { + "model": "wildbackport:block/mangrove_propagule_hanging_4" + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/mangrove_roots.json b/common/src/main/resources/assets/wildbackport/blockstates/mangrove_roots.json new file mode 100644 index 0000000..196ea4a --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/mangrove_roots.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "wildbackport:block/mangrove_roots" + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/mangrove_sign.json b/common/src/main/resources/assets/wildbackport/blockstates/mangrove_sign.json new file mode 100644 index 0000000..f570404 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/mangrove_sign.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "wildbackport:block/mangrove_sign" + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/mangrove_slab.json b/common/src/main/resources/assets/wildbackport/blockstates/mangrove_slab.json new file mode 100644 index 0000000..be1075d --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/mangrove_slab.json @@ -0,0 +1,13 @@ +{ + "variants": { + "type=bottom": { + "model": "wildbackport:block/mangrove_slab" + }, + "type=double": { + "model": "wildbackport:block/mangrove_planks" + }, + "type=top": { + "model": "wildbackport:block/mangrove_slab_top" + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/mangrove_stairs.json b/common/src/main/resources/assets/wildbackport/blockstates/mangrove_stairs.json new file mode 100644 index 0000000..7cf383f --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/mangrove_stairs.json @@ -0,0 +1,209 @@ +{ + "variants": { + "facing=east,half=bottom,shape=inner_left": { + "model": "wildbackport:block/mangrove_stairs_inner", + "y": 270, + "uvlock": true + }, + "facing=east,half=bottom,shape=inner_right": { + "model": "wildbackport:block/mangrove_stairs_inner" + }, + "facing=east,half=bottom,shape=outer_left": { + "model": "wildbackport:block/mangrove_stairs_outer", + "y": 270, + "uvlock": true + }, + "facing=east,half=bottom,shape=outer_right": { + "model": "wildbackport:block/mangrove_stairs_outer" + }, + "facing=east,half=bottom,shape=straight": { + "model": "wildbackport:block/mangrove_stairs" + }, + "facing=east,half=top,shape=inner_left": { + "model": "wildbackport:block/mangrove_stairs_inner", + "x": 180, + "uvlock": true + }, + "facing=east,half=top,shape=inner_right": { + "model": "wildbackport:block/mangrove_stairs_inner", + "x": 180, + "y": 90, + "uvlock": true + }, + "facing=east,half=top,shape=outer_left": { + "model": "wildbackport:block/mangrove_stairs_outer", + "x": 180, + "uvlock": true + }, + "facing=east,half=top,shape=outer_right": { + "model": "wildbackport:block/mangrove_stairs_outer", + "x": 180, + "y": 90, + "uvlock": true + }, + "facing=east,half=top,shape=straight": { + "model": "wildbackport:block/mangrove_stairs", + "x": 180, + "uvlock": true + }, + "facing=north,half=bottom,shape=inner_left": { + "model": "wildbackport:block/mangrove_stairs_inner", + "y": 180, + "uvlock": true + }, + "facing=north,half=bottom,shape=inner_right": { + "model": "wildbackport:block/mangrove_stairs_inner", + "y": 270, + "uvlock": true + }, + "facing=north,half=bottom,shape=outer_left": { + "model": "wildbackport:block/mangrove_stairs_outer", + "y": 180, + "uvlock": true + }, + "facing=north,half=bottom,shape=outer_right": { + "model": "wildbackport:block/mangrove_stairs_outer", + "y": 270, + "uvlock": true + }, + "facing=north,half=bottom,shape=straight": { + "model": "wildbackport:block/mangrove_stairs", + "y": 270, + "uvlock": true + }, + "facing=north,half=top,shape=inner_left": { + "model": "wildbackport:block/mangrove_stairs_inner", + "x": 180, + "y": 270, + "uvlock": true + }, + "facing=north,half=top,shape=inner_right": { + "model": "wildbackport:block/mangrove_stairs_inner", + "x": 180, + "uvlock": true + }, + "facing=north,half=top,shape=outer_left": { + "model": "wildbackport:block/mangrove_stairs_outer", + "x": 180, + "y": 270, + "uvlock": true + }, + "facing=north,half=top,shape=outer_right": { + "model": "wildbackport:block/mangrove_stairs_outer", + "x": 180, + "uvlock": true + }, + "facing=north,half=top,shape=straight": { + "model": "wildbackport:block/mangrove_stairs", + "x": 180, + "y": 270, + "uvlock": true + }, + "facing=south,half=bottom,shape=inner_left": { + "model": "wildbackport:block/mangrove_stairs_inner" + }, + "facing=south,half=bottom,shape=inner_right": { + "model": "wildbackport:block/mangrove_stairs_inner", + "y": 90, + "uvlock": true + }, + "facing=south,half=bottom,shape=outer_left": { + "model": "wildbackport:block/mangrove_stairs_outer" + }, + "facing=south,half=bottom,shape=outer_right": { + "model": "wildbackport:block/mangrove_stairs_outer", + "y": 90, + "uvlock": true + }, + "facing=south,half=bottom,shape=straight": { + "model": "wildbackport:block/mangrove_stairs", + "y": 90, + "uvlock": true + }, + "facing=south,half=top,shape=inner_left": { + "model": "wildbackport:block/mangrove_stairs_inner", + "x": 180, + "y": 90, + "uvlock": true + }, + "facing=south,half=top,shape=inner_right": { + "model": "wildbackport:block/mangrove_stairs_inner", + "x": 180, + "y": 180, + "uvlock": true + }, + "facing=south,half=top,shape=outer_left": { + "model": "wildbackport:block/mangrove_stairs_outer", + "x": 180, + "y": 90, + "uvlock": true + }, + "facing=south,half=top,shape=outer_right": { + "model": "wildbackport:block/mangrove_stairs_outer", + "x": 180, + "y": 180, + "uvlock": true + }, + "facing=south,half=top,shape=straight": { + "model": "wildbackport:block/mangrove_stairs", + "x": 180, + "y": 90, + "uvlock": true + }, + "facing=west,half=bottom,shape=inner_left": { + "model": "wildbackport:block/mangrove_stairs_inner", + "y": 90, + "uvlock": true + }, + "facing=west,half=bottom,shape=inner_right": { + "model": "wildbackport:block/mangrove_stairs_inner", + "y": 180, + "uvlock": true + }, + "facing=west,half=bottom,shape=outer_left": { + "model": "wildbackport:block/mangrove_stairs_outer", + "y": 90, + "uvlock": true + }, + "facing=west,half=bottom,shape=outer_right": { + "model": "wildbackport:block/mangrove_stairs_outer", + "y": 180, + "uvlock": true + }, + "facing=west,half=bottom,shape=straight": { + "model": "wildbackport:block/mangrove_stairs", + "y": 180, + "uvlock": true + }, + "facing=west,half=top,shape=inner_left": { + "model": "wildbackport:block/mangrove_stairs_inner", + "x": 180, + "y": 180, + "uvlock": true + }, + "facing=west,half=top,shape=inner_right": { + "model": "wildbackport:block/mangrove_stairs_inner", + "x": 180, + "y": 270, + "uvlock": true + }, + "facing=west,half=top,shape=outer_left": { + "model": "wildbackport:block/mangrove_stairs_outer", + "x": 180, + "y": 180, + "uvlock": true + }, + "facing=west,half=top,shape=outer_right": { + "model": "wildbackport:block/mangrove_stairs_outer", + "x": 180, + "y": 270, + "uvlock": true + }, + "facing=west,half=top,shape=straight": { + "model": "wildbackport:block/mangrove_stairs", + "x": 180, + "y": 180, + "uvlock": true + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/mangrove_trapdoor.json b/common/src/main/resources/assets/wildbackport/blockstates/mangrove_trapdoor.json new file mode 100644 index 0000000..29c80ac --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/mangrove_trapdoor.json @@ -0,0 +1,69 @@ +{ + "variants": { + "facing=east,half=bottom,open=false": { + "model": "wildbackport:block/mangrove_trapdoor_bottom", + "y": 90 + }, + "facing=east,half=bottom,open=true": { + "model": "wildbackport:block/mangrove_trapdoor_open", + "y": 90 + }, + "facing=east,half=top,open=false": { + "model": "wildbackport:block/mangrove_trapdoor_top", + "y": 90 + }, + "facing=east,half=top,open=true": { + "model": "wildbackport:block/mangrove_trapdoor_open", + "x": 180, + "y": 270 + }, + "facing=north,half=bottom,open=false": { + "model": "wildbackport:block/mangrove_trapdoor_bottom" + }, + "facing=north,half=bottom,open=true": { + "model": "wildbackport:block/mangrove_trapdoor_open" + }, + "facing=north,half=top,open=false": { + "model": "wildbackport:block/mangrove_trapdoor_top" + }, + "facing=north,half=top,open=true": { + "model": "wildbackport:block/mangrove_trapdoor_open", + "x": 180, + "y": 180 + }, + "facing=south,half=bottom,open=false": { + "model": "wildbackport:block/mangrove_trapdoor_bottom", + "y": 180 + }, + "facing=south,half=bottom,open=true": { + "model": "wildbackport:block/mangrove_trapdoor_open", + "y": 180 + }, + "facing=south,half=top,open=false": { + "model": "wildbackport:block/mangrove_trapdoor_top", + "y": 180 + }, + "facing=south,half=top,open=true": { + "model": "wildbackport:block/mangrove_trapdoor_open", + "x": 180, + "y": 0 + }, + "facing=west,half=bottom,open=false": { + "model": "wildbackport:block/mangrove_trapdoor_bottom", + "y": 270 + }, + "facing=west,half=bottom,open=true": { + "model": "wildbackport:block/mangrove_trapdoor_open", + "y": 270 + }, + "facing=west,half=top,open=false": { + "model": "wildbackport:block/mangrove_trapdoor_top", + "y": 270 + }, + "facing=west,half=top,open=true": { + "model": "wildbackport:block/mangrove_trapdoor_open", + "x": 180, + "y": 90 + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/mangrove_wall_sign.json b/common/src/main/resources/assets/wildbackport/blockstates/mangrove_wall_sign.json new file mode 100644 index 0000000..f570404 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/mangrove_wall_sign.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "wildbackport:block/mangrove_sign" + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/mangrove_wood.json b/common/src/main/resources/assets/wildbackport/blockstates/mangrove_wood.json new file mode 100644 index 0000000..b0edcc3 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/mangrove_wood.json @@ -0,0 +1,16 @@ +{ + "variants": { + "axis=x": { + "model": "wildbackport:block/mangrove_wood", + "x": 90, + "y": 90 + }, + "axis=y": { + "model": "wildbackport:block/mangrove_wood" + }, + "axis=z": { + "model": "wildbackport:block/mangrove_wood", + "x": 90 + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/mud.json b/common/src/main/resources/assets/wildbackport/blockstates/mud.json new file mode 100644 index 0000000..623f036 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/mud.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "wildbackport:block/mud" + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/mud_brick_slab.json b/common/src/main/resources/assets/wildbackport/blockstates/mud_brick_slab.json new file mode 100644 index 0000000..7520145 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/mud_brick_slab.json @@ -0,0 +1,13 @@ +{ + "variants": { + "type=bottom": { + "model": "wildbackport:block/mud_brick_slab" + }, + "type=double": { + "model": "wildbackport:block/mud_bricks" + }, + "type=top": { + "model": "wildbackport:block/mud_brick_slab_top" + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/mud_brick_stairs.json b/common/src/main/resources/assets/wildbackport/blockstates/mud_brick_stairs.json new file mode 100644 index 0000000..59c6844 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/mud_brick_stairs.json @@ -0,0 +1,209 @@ +{ + "variants": { + "facing=east,half=bottom,shape=inner_left": { + "model": "wildbackport:block/mud_brick_stairs_inner", + "y": 270, + "uvlock": true + }, + "facing=east,half=bottom,shape=inner_right": { + "model": "wildbackport:block/mud_brick_stairs_inner" + }, + "facing=east,half=bottom,shape=outer_left": { + "model": "wildbackport:block/mud_brick_stairs_outer", + "y": 270, + "uvlock": true + }, + "facing=east,half=bottom,shape=outer_right": { + "model": "wildbackport:block/mud_brick_stairs_outer" + }, + "facing=east,half=bottom,shape=straight": { + "model": "wildbackport:block/mud_brick_stairs" + }, + "facing=east,half=top,shape=inner_left": { + "model": "wildbackport:block/mud_brick_stairs_inner", + "x": 180, + "uvlock": true + }, + "facing=east,half=top,shape=inner_right": { + "model": "wildbackport:block/mud_brick_stairs_inner", + "x": 180, + "y": 90, + "uvlock": true + }, + "facing=east,half=top,shape=outer_left": { + "model": "wildbackport:block/mud_brick_stairs_outer", + "x": 180, + "uvlock": true + }, + "facing=east,half=top,shape=outer_right": { + "model": "wildbackport:block/mud_brick_stairs_outer", + "x": 180, + "y": 90, + "uvlock": true + }, + "facing=east,half=top,shape=straight": { + "model": "wildbackport:block/mud_brick_stairs", + "x": 180, + "uvlock": true + }, + "facing=north,half=bottom,shape=inner_left": { + "model": "wildbackport:block/mud_brick_stairs_inner", + "y": 180, + "uvlock": true + }, + "facing=north,half=bottom,shape=inner_right": { + "model": "wildbackport:block/mud_brick_stairs_inner", + "y": 270, + "uvlock": true + }, + "facing=north,half=bottom,shape=outer_left": { + "model": "wildbackport:block/mud_brick_stairs_outer", + "y": 180, + "uvlock": true + }, + "facing=north,half=bottom,shape=outer_right": { + "model": "wildbackport:block/mud_brick_stairs_outer", + "y": 270, + "uvlock": true + }, + "facing=north,half=bottom,shape=straight": { + "model": "wildbackport:block/mud_brick_stairs", + "y": 270, + "uvlock": true + }, + "facing=north,half=top,shape=inner_left": { + "model": "wildbackport:block/mud_brick_stairs_inner", + "x": 180, + "y": 270, + "uvlock": true + }, + "facing=north,half=top,shape=inner_right": { + "model": "wildbackport:block/mud_brick_stairs_inner", + "x": 180, + "uvlock": true + }, + "facing=north,half=top,shape=outer_left": { + "model": "wildbackport:block/mud_brick_stairs_outer", + "x": 180, + "y": 270, + "uvlock": true + }, + "facing=north,half=top,shape=outer_right": { + "model": "wildbackport:block/mud_brick_stairs_outer", + "x": 180, + "uvlock": true + }, + "facing=north,half=top,shape=straight": { + "model": "wildbackport:block/mud_brick_stairs", + "x": 180, + "y": 270, + "uvlock": true + }, + "facing=south,half=bottom,shape=inner_left": { + "model": "wildbackport:block/mud_brick_stairs_inner" + }, + "facing=south,half=bottom,shape=inner_right": { + "model": "wildbackport:block/mud_brick_stairs_inner", + "y": 90, + "uvlock": true + }, + "facing=south,half=bottom,shape=outer_left": { + "model": "wildbackport:block/mud_brick_stairs_outer" + }, + "facing=south,half=bottom,shape=outer_right": { + "model": "wildbackport:block/mud_brick_stairs_outer", + "y": 90, + "uvlock": true + }, + "facing=south,half=bottom,shape=straight": { + "model": "wildbackport:block/mud_brick_stairs", + "y": 90, + "uvlock": true + }, + "facing=south,half=top,shape=inner_left": { + "model": "wildbackport:block/mud_brick_stairs_inner", + "x": 180, + "y": 90, + "uvlock": true + }, + "facing=south,half=top,shape=inner_right": { + "model": "wildbackport:block/mud_brick_stairs_inner", + "x": 180, + "y": 180, + "uvlock": true + }, + "facing=south,half=top,shape=outer_left": { + "model": "wildbackport:block/mud_brick_stairs_outer", + "x": 180, + "y": 90, + "uvlock": true + }, + "facing=south,half=top,shape=outer_right": { + "model": "wildbackport:block/mud_brick_stairs_outer", + "x": 180, + "y": 180, + "uvlock": true + }, + "facing=south,half=top,shape=straight": { + "model": "wildbackport:block/mud_brick_stairs", + "x": 180, + "y": 90, + "uvlock": true + }, + "facing=west,half=bottom,shape=inner_left": { + "model": "wildbackport:block/mud_brick_stairs_inner", + "y": 90, + "uvlock": true + }, + "facing=west,half=bottom,shape=inner_right": { + "model": "wildbackport:block/mud_brick_stairs_inner", + "y": 180, + "uvlock": true + }, + "facing=west,half=bottom,shape=outer_left": { + "model": "wildbackport:block/mud_brick_stairs_outer", + "y": 90, + "uvlock": true + }, + "facing=west,half=bottom,shape=outer_right": { + "model": "wildbackport:block/mud_brick_stairs_outer", + "y": 180, + "uvlock": true + }, + "facing=west,half=bottom,shape=straight": { + "model": "wildbackport:block/mud_brick_stairs", + "y": 180, + "uvlock": true + }, + "facing=west,half=top,shape=inner_left": { + "model": "wildbackport:block/mud_brick_stairs_inner", + "x": 180, + "y": 180, + "uvlock": true + }, + "facing=west,half=top,shape=inner_right": { + "model": "wildbackport:block/mud_brick_stairs_inner", + "x": 180, + "y": 270, + "uvlock": true + }, + "facing=west,half=top,shape=outer_left": { + "model": "wildbackport:block/mud_brick_stairs_outer", + "x": 180, + "y": 180, + "uvlock": true + }, + "facing=west,half=top,shape=outer_right": { + "model": "wildbackport:block/mud_brick_stairs_outer", + "x": 180, + "y": 270, + "uvlock": true + }, + "facing=west,half=top,shape=straight": { + "model": "wildbackport:block/mud_brick_stairs", + "x": 180, + "y": 180, + "uvlock": true + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/mud_brick_wall.json b/common/src/main/resources/assets/wildbackport/blockstates/mud_brick_wall.json new file mode 100644 index 0000000..084e491 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/mud_brick_wall.json @@ -0,0 +1,90 @@ +{ + "multipart": [ + { + "when": { + "up": "true" + }, + "apply": { + "model": "wildbackport:block/mud_brick_wall_post" + } + }, + { + "when": { + "north": "low" + }, + "apply": { + "model": "wildbackport:block/mud_brick_wall_side", + "uvlock": true + } + }, + { + "when": { + "east": "low" + }, + "apply": { + "model": "wildbackport:block/mud_brick_wall_side", + "y": 90, + "uvlock": true + } + }, + { + "when": { + "south": "low" + }, + "apply": { + "model": "wildbackport:block/mud_brick_wall_side", + "y": 180, + "uvlock": true + } + }, + { + "when": { + "west": "low" + }, + "apply": { + "model": "wildbackport:block/mud_brick_wall_side", + "y": 270, + "uvlock": true + } + }, + { + "when": { + "north": "tall" + }, + "apply": { + "model": "wildbackport:block/mud_brick_wall_side_tall", + "uvlock": true + } + }, + { + "when": { + "east": "tall" + }, + "apply": { + "model": "wildbackport:block/mud_brick_wall_side_tall", + "y": 90, + "uvlock": true + } + }, + { + "when": { + "south": "tall" + }, + "apply": { + "model": "wildbackport:block/mud_brick_wall_side_tall", + "y": 180, + "uvlock": true + } + }, + { + "when": { + "west": "tall" + }, + "apply": { + "model": "wildbackport:block/mud_brick_wall_side_tall", + "y": 270, + "uvlock": true + } + } + ] +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/mud_bricks.json b/common/src/main/resources/assets/wildbackport/blockstates/mud_bricks.json new file mode 100644 index 0000000..334ccb6 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/mud_bricks.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "wildbackport:block/mud_bricks" + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/muddy_mangrove_roots.json b/common/src/main/resources/assets/wildbackport/blockstates/muddy_mangrove_roots.json new file mode 100644 index 0000000..153e767 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/muddy_mangrove_roots.json @@ -0,0 +1,16 @@ +{ + "variants": { + "axis=x": { + "model": "wildbackport:block/muddy_mangrove_roots", + "x": 90, + "y": 90 + }, + "axis=y": { + "model": "wildbackport:block/muddy_mangrove_roots" + }, + "axis=z": { + "model": "wildbackport:block/muddy_mangrove_roots", + "x": 90 + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/ochre_froglight.json b/common/src/main/resources/assets/wildbackport/blockstates/ochre_froglight.json new file mode 100644 index 0000000..8d37ca0 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/ochre_froglight.json @@ -0,0 +1,16 @@ +{ + "variants": { + "axis=x": { + "model": "wildbackport:block/ochre_froglight_horizontal", + "x": 90, + "y": 90 + }, + "axis=y": { + "model": "wildbackport:block/ochre_froglight" + }, + "axis=z": { + "model": "wildbackport:block/ochre_froglight_horizontal", + "x": 90 + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/packed_mud.json b/common/src/main/resources/assets/wildbackport/blockstates/packed_mud.json new file mode 100644 index 0000000..dd17720 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/packed_mud.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "wildbackport:block/packed_mud" + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/pearlescent_froglight.json b/common/src/main/resources/assets/wildbackport/blockstates/pearlescent_froglight.json new file mode 100644 index 0000000..a8428cb --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/pearlescent_froglight.json @@ -0,0 +1,16 @@ +{ + "variants": { + "axis=x": { + "model": "wildbackport:block/pearlescent_froglight_horizontal", + "x": 90, + "y": 90 + }, + "axis=y": { + "model": "wildbackport:block/pearlescent_froglight" + }, + "axis=z": { + "model": "wildbackport:block/pearlescent_froglight_horizontal", + "x": 90 + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/potted_mangrove_propagule.json b/common/src/main/resources/assets/wildbackport/blockstates/potted_mangrove_propagule.json new file mode 100644 index 0000000..2d5b84c --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/potted_mangrove_propagule.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "wildbackport:block/potted_mangrove_propagule" + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/reinforced_deepslate.json b/common/src/main/resources/assets/wildbackport/blockstates/reinforced_deepslate.json new file mode 100644 index 0000000..1da6821 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/reinforced_deepslate.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "wildbackport:block/reinforced_deepslate" + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/sculk.json b/common/src/main/resources/assets/wildbackport/blockstates/sculk.json new file mode 100644 index 0000000..15a287e --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/sculk.json @@ -0,0 +1,20 @@ +{ + "variants": { + "": [ + { + "model": "wildbackport:block/sculk" + }, + { + "model": "wildbackport:block/sculk_mirrored" + }, + { + "model": "wildbackport:block/sculk", + "y": 180 + }, + { + "model": "wildbackport:block/sculk_mirrored", + "y": 180 + } + ] + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/sculk_catalyst.json b/common/src/main/resources/assets/wildbackport/blockstates/sculk_catalyst.json new file mode 100644 index 0000000..e4ad3f7 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/sculk_catalyst.json @@ -0,0 +1,10 @@ +{ + "variants": { + "bloom=false": { + "model": "wildbackport:block/sculk_catalyst" + }, + "bloom=true": { + "model": "wildbackport:block/sculk_catalyst_bloom" + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/sculk_shrieker.json b/common/src/main/resources/assets/wildbackport/blockstates/sculk_shrieker.json new file mode 100644 index 0000000..f2c437d --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/sculk_shrieker.json @@ -0,0 +1,10 @@ +{ + "variants": { + "shrieking=false": { + "model": "wildbackport:block/sculk_shrieker" + }, + "shrieking=true": { + "model": "wildbackport:block/sculk_shrieker" + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/sculk_vein.json b/common/src/main/resources/assets/wildbackport/blockstates/sculk_vein.json new file mode 100644 index 0000000..7c71da7 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/sculk_vein.json @@ -0,0 +1,150 @@ +{ + "multipart": [ + { + "when": { + "up": "true" + }, + "apply": { + "model": "wildbackport:block/sculk_vein", + "x": 270, + "uvlock": true + } + }, + { + "when": { + "up": "false", + "north": "false", + "west": "false", + "south": "false", + "east": "false", + "down": "false" + }, + "apply": { + "model": "wildbackport:block/sculk_vein", + "x": 270, + "uvlock": true + } + }, + { + "when": { + "north": "true" + }, + "apply": { + "model": "wildbackport:block/sculk_vein" + } + }, + { + "when": { + "up": "false", + "north": "false", + "west": "false", + "south": "false", + "east": "false", + "down": "false" + }, + "apply": { + "model": "wildbackport:block/sculk_vein" + } + }, + { + "when": { + "west": "true" + }, + "apply": { + "model": "wildbackport:block/sculk_vein", + "y": 270, + "uvlock": true + } + }, + { + "when": { + "up": "false", + "north": "false", + "west": "false", + "south": "false", + "east": "false", + "down": "false" + }, + "apply": { + "model": "wildbackport:block/sculk_vein", + "y": 270, + "uvlock": true + } + }, + { + "when": { + "south": "true" + }, + "apply": { + "model": "wildbackport:block/sculk_vein", + "y": 180, + "uvlock": true + } + }, + { + "when": { + "up": "false", + "north": "false", + "west": "false", + "south": "false", + "east": "false", + "down": "false" + }, + "apply": { + "model": "wildbackport:block/sculk_vein", + "y": 180, + "uvlock": true + } + }, + { + "when": { + "east": "true" + }, + "apply": { + "model": "wildbackport:block/sculk_vein", + "y": 90, + "uvlock": true + } + }, + { + "when": { + "up": "false", + "north": "false", + "west": "false", + "south": "false", + "east": "false", + "down": "false" + }, + "apply": { + "model": "wildbackport:block/sculk_vein", + "y": 90, + "uvlock": true + } + }, + { + "when": { + "down": "true" + }, + "apply": { + "model": "wildbackport:block/sculk_vein", + "x": 90, + "uvlock": true + } + }, + { + "when": { + "up": "false", + "north": "false", + "west": "false", + "south": "false", + "east": "false", + "down": "false" + }, + "apply": { + "model": "wildbackport:block/sculk_vein", + "x": 90, + "uvlock": true + } + } + ] +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/stripped_mangrove_log.json b/common/src/main/resources/assets/wildbackport/blockstates/stripped_mangrove_log.json new file mode 100644 index 0000000..c138199 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/stripped_mangrove_log.json @@ -0,0 +1,16 @@ +{ + "variants": { + "axis=x": { + "model": "wildbackport:block/stripped_mangrove_log_horizontal", + "x": 90, + "y": 90 + }, + "axis=y": { + "model": "wildbackport:block/stripped_mangrove_log" + }, + "axis=z": { + "model": "wildbackport:block/stripped_mangrove_log_horizontal", + "x": 90 + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/stripped_mangrove_wood.json b/common/src/main/resources/assets/wildbackport/blockstates/stripped_mangrove_wood.json new file mode 100644 index 0000000..356ecf3 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/stripped_mangrove_wood.json @@ -0,0 +1,16 @@ +{ + "variants": { + "axis=x": { + "model": "wildbackport:block/stripped_mangrove_wood", + "x": 90, + "y": 90 + }, + "axis=y": { + "model": "wildbackport:block/stripped_mangrove_wood" + }, + "axis=z": { + "model": "wildbackport:block/stripped_mangrove_wood", + "x": 90 + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/blockstates/verdant_froglight.json b/common/src/main/resources/assets/wildbackport/blockstates/verdant_froglight.json new file mode 100644 index 0000000..2ed13d9 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/blockstates/verdant_froglight.json @@ -0,0 +1,16 @@ +{ + "variants": { + "axis=x": { + "model": "wildbackport:block/verdant_froglight_horizontal", + "x": 90, + "y": 90 + }, + "axis=y": { + "model": "wildbackport:block/verdant_froglight" + }, + "axis=z": { + "model": "wildbackport:block/verdant_froglight_horizontal", + "x": 90 + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/lang/en_us.json b/common/src/main/resources/assets/wildbackport/lang/en_us.json new file mode 100644 index 0000000..185ce85 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/lang/en_us.json @@ -0,0 +1,95 @@ +{ + "biome.wildbackport.deep_dark": "Deep Dark", + "biome.wildbackport.mangrove_swamp": "Mangrove Swamp", + "block.wildbackport.sculk": "Sculk", + "block.wildbackport.sculk_vein": "Sculk Vein", + "block.wildbackport.sculk_catalyst": "Sculk Catalyst", + "block.wildbackport.sculk_shrieker": "Sculk Shrieker", + "block.wildbackport.reinforced_deepslate": "Reinforced Deepslate", + "block.wildbackport.ochre_froglight": "Ochre Froglight", + "block.wildbackport.verdant_froglight": "Verdant Froglight", + "block.wildbackport.pearlescent_froglight": "Pearlescent Froglight", + "block.wildbackport.mangrove_log": "Mangrove Log", + "block.wildbackport.mangrove_roots": "Mangrove Roots", + "block.wildbackport.muddy_mangrove_roots": "Muddy Mangrove Roots", + "block.wildbackport.stripped_mangrove_log": "Stripped Mangrove Log", + "block.wildbackport.stripped_mangrove_wood": "Stripped Mangrove Wood", + "block.wildbackport.mangrove_leaves": "Mangrove Leaves", + "block.wildbackport.mud_brick_slab": "Mud Brick Slab", + "block.wildbackport.mud": "Mud", + "block.wildbackport.packed_mud": "Packed Mud", + "block.wildbackport.mud_bricks": "Mud Bricks", + "block.wildbackport.mud_brick_stairs": "Mud Brick Stairs", + "block.wildbackport.mud_brick_wall": "Mud Brick Wall", + "block.wildbackport.frogspawn": "Frogspawn", + "block.wildbackport.mangrove_planks": "Mangrove Planks", + "block.wildbackport.mangrove_propagule": "Mangrove Propagule", + "block.wildbackport.mangrove_door": "Mangrove Door", + "block.wildbackport.mangrove_wood": "Mangrove Wood", + "block.wildbackport.mangrove_slab": "Mangrove Slab", + "block.wildbackport.mangrove_stairs": "Mangrove Stairs", + "block.wildbackport.mangrove_sign": "Mangrove Sign", + "block.wildbackport.mangrove_wall_sign": "Mangrove Wall Sign", + "block.wildbackport.mangrove_pressure_plate": "Mangrove Pressure Plate", + "block.wildbackport.mangrove_button": "Mangrove Button", + "block.wildbackport.mangrove_fence": "Mangrove Fence", + "block.wildbackport.mangrove_fence_gate": "Mangrove Fence Gate", + "block.wildbackport.mangrove_trapdoor": "Mangrove Trapdoor", + "block.wildbackport.potted_mangrove_propagule": "Potted Mangrove Propagule", + "item.wildbackport.mangrove_boat": "Mangrove Boat", + "item.wildbackport.oak_chest_boat": "Oak Boat with Chest", + "item.wildbackport.spruce_chest_boat": "Spruce Boat with Chest", + "item.wildbackport.acacia_chest_boat": "Acacia Boat with Chest", + "item.wildbackport.birch_chest_boat": "Birch Boat with Chest", + "item.wildbackport.jungle_chest_boat": "Jungle Boat with Chest", + "item.wildbackport.dark_oak_chest_boat": "Dark Oak Boat with Chest", + "item.wildbackport.mangrove_chest_boat": "Mangrove Boat with Chest", + "item.wildbackport.frog_spawn_egg": "Frog Spawn Egg", + "item.wildbackport.tadpole_spawn_egg": "Tadpole Spawn Egg", + "item.wildbackport.warden_spawn_egg": "Warden Spawn Egg", + "item.wildbackport.allay_spawn_egg": "Allay Spawn Egg", + "item.wildbackport.tadpole_bucket": "Bucket of Tadpole", + "item.wildbackport.echo_shard": "Echo Shard", + "item.wildbackport.recovery_compass": "Recovery Compass", + "item.wildbackport.disc_fragment_5": "Disc Fragment 5", + "item.wildbackport.disc_fragment_5.desc": "Music Disc - 5", + "item.wildbackport.music_disc_5": "Music Disc", + "item.wildbackport.music_disc_5.desc": "Samuel Ă…berg - 5", + "effect.wildbackport.darkness": "Darkness", + "enchantment.wildbackport.swift_sneak": "Swift Sneak", + "entity.wildbackport.warden": "Warden", + "entity.wildbackport.frog": "Frog", + "entity.wildbackport.tadpole": "Tadpole", + "entity.wildbackport.wb_boat": "Boat", + "entity.wildbackport.chest_boat": "Boat with Chest", + "subtitles.entity.warden.roar": "Warden roars", + "subtitles.entity.warden.sniff": "Warden sniffs", + "subtitles.entity.warden.emerge": "Warden emerges", + "subtitles.entity.warden.dig": "Warden digs", + "subtitles.entity.warden.hurt": "Warden hurts", + "subtitles.entity.warden.death": "Warden dies", + "subtitles.entity.warden.step": "Warden steps", + "subtitles.entity.warden.listening": "Warden takes notice", + "subtitles.entity.warden.listening_angry": "Warden takes notice angrily", + "subtitles.entity.warden.heartbeat": "Warden heart beats", + "subtitles.entity.warden.attack_impact": "Warden lands hit", + "subtitles.entity.warden.tendril_clicks": "Warden tendrils click", + "subtitles.entity.warden.angry": "Warden rages", + "subtitles.entity.warden.agitated": "Warden groans angrily", + "subtitles.entity.warden.ambient": "Warden whines", + "subtitles.entity.warden.nearby_close": "Warden approaches", + "subtitles.entity.warden.nearby_closer": "Warden advances", + "subtitles.entity.warden.nearby_closest": "Warden draws close", + "subtitles.entity.frog.ambient": "Frog croaks", + "subtitles.entity.frog.death": "Frog dies", + "subtitles.entity.frog.eat": "Frog eats", + "subtitles.entity.frog.hurt": "Frog hurts", + "subtitles.entity.frog.lay_spawn": "Frog lays spawn", + "subtitles.entity.frog.long_jump": "Frog jumps", + "commands.warden_spawn_tracker.set.success.single": "Set warnings to %s", + "commands.warden_spawn_tracker.set.success.multiple": "Set warnings to %s players", + "commands.warden_spawn_tracker.clear.success.single": "Removed warnings from %s", + "commands.warden_spawn_tracker.clear.success.multiple": "Removed warnings from %s players", + "death.attack.sonic_boom": "%1$s was obliterated by a sonically-charged shriek", + "death.attack.sonic_boom.player": "%1$s was obliterated by a sonically-charged shriek whilst trying to escape %2$s" +} diff --git a/common/src/main/resources/assets/wildbackport/models/block/frogspawn.json b/common/src/main/resources/assets/wildbackport/models/block/frogspawn.json new file mode 100644 index 0000000..44b9c4a --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/frogspawn.json @@ -0,0 +1,16 @@ +{ + "ambientocclusion": false, + "textures": { + "particle": "wildbackport:block/frogspawn", + "texture": "wildbackport:block/frogspawn" + }, + "elements": [ + { "from": [ 0, 0.25, 0 ], + "to": [ 16, 0.25, 16 ], + "faces": { + "down": { "uv": [ 0, 16, 16, 0 ], "texture": "#texture" }, + "up": { "uv": [ 0, 0, 16, 16 ], "texture": "#texture"} + } + } + ] +} diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_button.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_button.json new file mode 100644 index 0000000..de32c78 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_button.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/button", + "textures": { + "texture": "wildbackport:block/mangrove_planks" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_button_inventory.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_button_inventory.json new file mode 100644 index 0000000..36358b9 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_button_inventory.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/button_inventory", + "textures": { + "texture": "wildbackport:block/mangrove_planks" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_button_pressed.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_button_pressed.json new file mode 100644 index 0000000..a137394 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_button_pressed.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/button_pressed", + "textures": { + "texture": "wildbackport:block/mangrove_planks" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_door_bottom.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_door_bottom.json new file mode 100644 index 0000000..9be64cb --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_door_bottom.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/door_bottom", + "textures": { + "top": "wildbackport:block/mangrove_door_top", + "bottom": "wildbackport:block/mangrove_door_bottom" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_door_bottom_hinge.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_door_bottom_hinge.json new file mode 100644 index 0000000..f35bb55 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_door_bottom_hinge.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/door_bottom_rh", + "textures": { + "top": "wildbackport:block/mangrove_door_top", + "bottom": "wildbackport:block/mangrove_door_bottom" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_door_top.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_door_top.json new file mode 100644 index 0000000..34374f1 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_door_top.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/door_top", + "textures": { + "top": "wildbackport:block/mangrove_door_top", + "bottom": "wildbackport:block/mangrove_door_bottom" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_door_top_hinge.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_door_top_hinge.json new file mode 100644 index 0000000..bb37d80 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_door_top_hinge.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/door_top_rh", + "textures": { + "top": "wildbackport:block/mangrove_door_top", + "bottom": "wildbackport:block/mangrove_door_bottom" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_fence_gate.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_fence_gate.json new file mode 100644 index 0000000..46e5406 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_fence_gate.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_fence_gate", + "textures": { + "texture": "wildbackport:block/mangrove_planks" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_fence_gate_open.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_fence_gate_open.json new file mode 100644 index 0000000..bafab9e --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_fence_gate_open.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_fence_gate_open", + "textures": { + "texture": "wildbackport:block/mangrove_planks" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_fence_gate_wall.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_fence_gate_wall.json new file mode 100644 index 0000000..4f7b81f --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_fence_gate_wall.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_fence_gate_wall", + "textures": { + "texture": "wildbackport:block/mangrove_planks" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_fence_gate_wall_open.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_fence_gate_wall_open.json new file mode 100644 index 0000000..4265f82 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_fence_gate_wall_open.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_fence_gate_wall_open", + "textures": { + "texture": "wildbackport:block/mangrove_planks" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_fence_inventory.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_fence_inventory.json new file mode 100644 index 0000000..39e69ee --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_fence_inventory.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/fence_inventory", + "textures": { + "texture": "wildbackport:block/mangrove_planks" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_fence_post.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_fence_post.json new file mode 100644 index 0000000..b5865bf --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_fence_post.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/fence_post", + "textures": { + "texture": "wildbackport:block/mangrove_planks" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_fence_side.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_fence_side.json new file mode 100644 index 0000000..08e0886 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_fence_side.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/fence_side", + "textures": { + "texture": "wildbackport:block/mangrove_planks" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_leaves.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_leaves.json new file mode 100644 index 0000000..a2a745f --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_leaves.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/leaves", + "textures": { + "all": "wildbackport:block/mangrove_leaves" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_log.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_log.json new file mode 100644 index 0000000..c9466c7 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_log.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column", + "textures": { + "end": "wildbackport:block/mangrove_log_top", + "side": "wildbackport:block/mangrove_log" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_log_horizontal.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_log_horizontal.json new file mode 100644 index 0000000..9ed4147 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_log_horizontal.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column_horizontal", + "textures": { + "end": "wildbackport:block/mangrove_log_top", + "side": "wildbackport:block/mangrove_log" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_planks.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_planks.json new file mode 100644 index 0000000..7ed4d57 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_planks.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cube_all", + "textures": { + "all": "wildbackport:block/mangrove_planks" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_pressure_plate.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_pressure_plate.json new file mode 100644 index 0000000..56184d6 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_pressure_plate.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/pressure_plate_up", + "textures": { + "texture": "wildbackport:block/mangrove_planks" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_pressure_plate_down.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_pressure_plate_down.json new file mode 100644 index 0000000..2b801cc --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_pressure_plate_down.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/pressure_plate_down", + "textures": { + "texture": "wildbackport:block/mangrove_planks" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_propagule.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_propagule.json new file mode 100644 index 0000000..049d1ee --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_propagule.json @@ -0,0 +1,65 @@ +{ + "parent": "block/block", + "textures": { + "sapling": "wildbackport:block/mangrove_propagule", + "particle": "wildbackport:block/mangrove_propagule" + }, + "elements": [ + { + "name": "leaves", + "from": [4.5, 9, 8], + "to": [11.5, 15, 8], + "rotation": {"angle": -45, "axis": "y", "origin": [8, 0, 8], "rescale": true}, + "faces": { + "north": {"uv": [4, 1, 11, 7], "texture": "#sapling"}, + "east": {"uv": [11, 6, 11, 10], "texture": "#sapling"}, + "south": {"uv": [4, 1, 11, 7], "texture": "#sapling"}, + "west": {"uv": [4, 6, 4, 11], "texture": "#sapling"}, + "up": {"uv": [4, 6, 11, 6], "rotation": 180, "texture": "#sapling"}, + "down": {"uv": [4, 11, 11, 11], "rotation": 180, "texture": "#sapling"} + } + }, + { + "name": "leaves", + "from": [8, 9, 4.5], + "to": [8, 15, 11.5], + "rotation": {"angle": -45, "axis": "y", "origin": [8, 0, 8], "rescale": true}, + "faces": { + "north": {"uv": [13, 0, 13, 10], "texture": "#sapling"}, + "east": {"uv": [4, 1, 11, 7], "texture": "#sapling"}, + "south": {"uv": [11, 0, 11, 10], "texture": "#sapling"}, + "west": {"uv": [4, 1, 11, 7], "texture": "#sapling"}, + "up": {"uv": [11, 0, 13, 0], "rotation": 270, "texture": "#sapling"}, + "down": {"uv": [11, 10, 13, 10], "rotation": 90, "texture": "#sapling"} + } + }, + { + "name": "hypocotyl", + "from": [7, 0, 8], + "to": [9, 9, 8], + "rotation": {"angle": -45, "axis": "y", "origin": [8, 0, 8], "rescale": true}, + "faces": { + "north": {"uv": [7, 7, 9, 16], "texture": "#sapling"}, + "east": {"uv": [11, 0, 11, 10], "texture": "#sapling"}, + "south": {"uv": [7, 7, 9, 16], "texture": "#sapling"}, + "west": {"uv": [13, 0, 13, 10], "texture": "#sapling"}, + "up": {"uv": [11, 0, 13, 0], "rotation": 180, "texture": "#sapling"}, + "down": {"uv": [11, 10, 13, 10], "rotation": 180, "texture": "#sapling"} + } + }, + { + "name": "hypocotyl", + "from": [7, 0, 8], + "to": [9, 9, 8], + "rotation": {"angle": 45, "axis": "y", "origin": [8, 0, 8], "rescale": true}, + "faces": { + "north": {"uv": [7, 7, 9, 16], "texture": "#sapling"}, + "east": {"uv": [13, 0, 13, 10], "texture": "#sapling"}, + "south": {"uv": [7, 7, 9, 16], "texture": "#sapling"}, + "west": {"uv": [11, 0, 11, 10], "texture": "#sapling"}, + "up": {"uv": [11, 0, 13, 0], "texture": "#sapling"}, + "down": {"uv": [11, 10, 13, 10], "texture": "#sapling"} + } + } + ] +} diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_propagule_hanging_0.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_propagule_hanging_0.json new file mode 100644 index 0000000..eae8773 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_propagule_hanging_0.json @@ -0,0 +1,100 @@ +{ + "parent": "block/block", + "textures": { + "propagule": "wildbackport:block/mangrove_propagule_hanging", + "particle": "wildbackport:block/mangrove_propagule_hanging" + }, + "elements": [ + { + "from": [7, 13.61104, 10.07193], + "to": [9, 13.61104, 12.07193], + "rotation": {"angle": 22.5, "axis": "x", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "east": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "south": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "west": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "up": {"uv": [8, 3, 10, 5], "rotation": 180, "texture": "#propagule"}, + "down": {"uv": [6, 3, 8, 5], "texture": "#propagule"} + } + }, + { + "from": [10.07193, 13.61104, 7], + "to": [12.07193, 13.61104, 9], + "rotation": {"angle": -22.5, "axis": "z", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "east": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "south": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "west": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "up": {"uv": [8, 3, 10, 5], "rotation": 90, "texture": "#propagule"}, + "down": {"uv": [6, 3, 8, 5], "rotation": 90, "texture": "#propagule"} + } + }, + { + "from": [7, 13.61104, 3.92807], + "to": [9, 13.61104, 5.92807], + "rotation": {"angle": -22.5, "axis": "x", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "east": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "south": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "west": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "up": {"uv": [8, 3, 10, 5], "texture": "#propagule"}, + "down": {"uv": [6, 3, 8, 5], "rotation": 180, "texture": "#propagule"} + } + }, + { + "from": [3.92807, 13.61104, 7], + "to": [5.92807, 13.61104, 9], + "rotation": {"angle": 22.5, "axis": "z", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "east": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "south": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "west": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "up": {"uv": [8, 3, 10, 5], "rotation": 270, "texture": "#propagule"}, + "down": {"uv": [6, 3, 8, 5], "rotation": 270, "texture": "#propagule"} + } + }, + { + "from": [7, 13, 7], + "to": [9, 14, 9], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 2, 2, 3], "texture": "#propagule"}, + "east": {"uv": [0, 2, 2, 3], "texture": "#propagule"}, + "south": {"uv": [0, 2, 2, 3], "texture": "#propagule"}, + "west": {"uv": [0, 2, 2, 3], "texture": "#propagule"}, + "up": {"uv": [0, 0, 2, 2], "texture": "#propagule"}, + "down": {"uv": [0, 3, 2, 5], "texture": "#propagule"} + } + }, + { + "from": [7, 14, 8], + "to": [9, 16, 8], + "rotation": {"angle": -45, "axis": "y", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 2], "texture": "#propagule"}, + "east": {"uv": [0, 0, 0, 2], "texture": "#propagule"}, + "south": {"uv": [0, 0, 2, 2], "texture": "#propagule"}, + "west": {"uv": [0, 0, 0, 2], "texture": "#propagule"}, + "up": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "down": {"uv": [0, 0, 2, 0], "texture": "#propagule"} + } + }, + { + "from": [7, 14, 8], + "to": [9, 16, 8], + "rotation": {"angle": 45, "axis": "y", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 2], "texture": "#propagule"}, + "east": {"uv": [0, 0, 0, 2], "texture": "#propagule"}, + "south": {"uv": [0, 0, 2, 2], "texture": "#propagule"}, + "west": {"uv": [0, 0, 0, 2], "texture": "#propagule"}, + "up": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "down": {"uv": [0, 0, 2, 0], "texture": "#propagule"} + } + } + ] +} diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_propagule_hanging_1.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_propagule_hanging_1.json new file mode 100644 index 0000000..d1044da --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_propagule_hanging_1.json @@ -0,0 +1,113 @@ +{ + "parent": "block/block", + "textures": { + "propagule": "wildbackport:block/mangrove_propagule_hanging", + "particle": "wildbackport:block/mangrove_propagule_hanging" + }, + "elements": [ + { + "from": [7, 10, 7], + "to": [9, 13, 9], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 7, 2, 10], "texture": "#propagule"}, + "east": {"uv": [0, 7, 2, 10], "texture": "#propagule"}, + "south": {"uv": [0, 7, 2, 10], "texture": "#propagule"}, + "west": {"uv": [0, 7, 2, 10], "texture": "#propagule"}, + "up": {"uv": [0, 5, 2, 7], "texture": "#propagule"}, + "down": {"uv": [0, 5, 2, 7], "texture": "#propagule"} + } + }, + { + "from": [7, 13.61104, 10.07193], + "to": [9, 13.61104, 12.07193], + "rotation": {"angle": 22.5, "axis": "x", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "east": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "south": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "west": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "up": {"uv": [8, 3, 10, 5], "rotation": 180, "texture": "#propagule"}, + "down": {"uv": [6, 3, 8, 5], "texture": "#propagule"} + } + }, + { + "from": [10.07193, 13.61104, 7], + "to": [12.07193, 13.61104, 9], + "rotation": {"angle": -22.5, "axis": "z", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "east": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "south": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "west": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "up": {"uv": [8, 3, 10, 5], "rotation": 90, "texture": "#propagule"}, + "down": {"uv": [6, 3, 8, 5], "rotation": 90, "texture": "#propagule"} + } + }, + { + "from": [7, 13.61104, 3.92807], + "to": [9, 13.61104, 5.92807], + "rotation": {"angle": -22.5, "axis": "x", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "east": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "south": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "west": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "up": {"uv": [8, 3, 10, 5], "texture": "#propagule"}, + "down": {"uv": [6, 3, 8, 5], "rotation": 180, "texture": "#propagule"} + } + }, + { + "from": [3.92807, 13.61104, 7], + "to": [5.92807, 13.61104, 9], + "rotation": {"angle": 22.5, "axis": "z", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "east": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "south": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "west": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "up": {"uv": [8, 3, 10, 5], "rotation": 270, "texture": "#propagule"}, + "down": {"uv": [6, 3, 8, 5], "rotation": 270, "texture": "#propagule"} + } + }, + { + "from": [7, 13, 7], + "to": [9, 14, 9], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 2, 2, 3], "texture": "#propagule"}, + "east": {"uv": [0, 2, 2, 3], "texture": "#propagule"}, + "south": {"uv": [0, 2, 2, 3], "texture": "#propagule"}, + "west": {"uv": [0, 2, 2, 3], "texture": "#propagule"}, + "up": {"uv": [0, 0, 2, 2], "texture": "#propagule"}, + "down": {"uv": [0, 3, 2, 5], "texture": "#propagule"} + } + }, + { + "from": [7, 14, 8], + "to": [9, 16, 8], + "rotation": {"angle": -45, "axis": "y", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 2], "texture": "#propagule"}, + "east": {"uv": [0, 0, 0, 2], "texture": "#propagule"}, + "south": {"uv": [0, 0, 2, 2], "texture": "#propagule"}, + "west": {"uv": [0, 0, 0, 2], "texture": "#propagule"}, + "up": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "down": {"uv": [0, 0, 2, 0], "texture": "#propagule"} + } + }, + { + "from": [7, 14, 8], + "to": [9, 16, 8], + "rotation": {"angle": 45, "axis": "y", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 2], "texture": "#propagule"}, + "east": {"uv": [0, 0, 0, 2], "texture": "#propagule"}, + "south": {"uv": [0, 0, 2, 2], "texture": "#propagule"}, + "west": {"uv": [0, 0, 0, 2], "texture": "#propagule"}, + "up": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "down": {"uv": [0, 0, 2, 0], "texture": "#propagule"} + } + } + ] +} diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_propagule_hanging_2.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_propagule_hanging_2.json new file mode 100644 index 0000000..5fe800e --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_propagule_hanging_2.json @@ -0,0 +1,139 @@ +{ + "parent": "block/block", + "textures": { + "propagule": "wildbackport:block/mangrove_propagule_hanging", + "particle": "wildbackport:block/mangrove_propagule_hanging" + }, + "elements": [ + { + "from": [7, 10, 7], + "to": [9, 13, 9], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 7, 2, 10], "texture": "#propagule"}, + "east": {"uv": [0, 7, 2, 10], "texture": "#propagule"}, + "south": {"uv": [0, 7, 2, 10], "texture": "#propagule"}, + "west": {"uv": [0, 7, 2, 10], "texture": "#propagule"}, + "up": {"uv": [0, 5, 2, 7], "texture": "#propagule"}, + "down": {"uv": [0, 10, 2, 12], "texture": "#propagule"} + } + }, + { + "from": [7, 13.61104, 10.07193], + "to": [9, 13.61104, 12.07193], + "rotation": {"angle": 22.5, "axis": "x", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "east": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "south": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "west": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "up": {"uv": [8, 3, 10, 5], "rotation": 180, "texture": "#propagule"}, + "down": {"uv": [6, 3, 8, 5], "texture": "#propagule"} + } + }, + { + "from": [10.07193, 13.61104, 7], + "to": [12.07193, 13.61104, 9], + "rotation": {"angle": -22.5, "axis": "z", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "east": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "south": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "west": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "up": {"uv": [8, 3, 10, 5], "rotation": 90, "texture": "#propagule"}, + "down": {"uv": [6, 3, 8, 5], "rotation": 90, "texture": "#propagule"} + } + }, + { + "from": [7, 13.61104, 3.92807], + "to": [9, 13.61104, 5.92807], + "rotation": {"angle": -22.5, "axis": "x", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "east": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "south": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "west": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "up": {"uv": [8, 3, 10, 5], "texture": "#propagule"}, + "down": {"uv": [6, 3, 8, 5], "rotation": 180, "texture": "#propagule"} + } + }, + { + "from": [3.92807, 13.61104, 7], + "to": [5.92807, 13.61104, 9], + "rotation": {"angle": 22.5, "axis": "z", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "east": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "south": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "west": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "up": {"uv": [8, 3, 10, 5], "rotation": 270, "texture": "#propagule"}, + "down": {"uv": [6, 3, 8, 5], "rotation": 270, "texture": "#propagule"} + } + }, + { + "from": [7, 13, 7], + "to": [9, 14, 9], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 2, 2, 3], "texture": "#propagule"}, + "east": {"uv": [0, 2, 2, 3], "texture": "#propagule"}, + "south": {"uv": [0, 2, 2, 3], "texture": "#propagule"}, + "west": {"uv": [0, 2, 2, 3], "texture": "#propagule"}, + "up": {"uv": [0, 0, 2, 2], "texture": "#propagule"}, + "down": {"uv": [0, 3, 2, 5], "texture": "#propagule"} + } + }, + { + "from": [7, 14, 8], + "to": [9, 16, 8], + "rotation": {"angle": -45, "axis": "y", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 2], "texture": "#propagule"}, + "east": {"uv": [0, 0, 0, 2], "texture": "#propagule"}, + "south": {"uv": [0, 0, 2, 2], "texture": "#propagule"}, + "west": {"uv": [0, 0, 0, 2], "texture": "#propagule"}, + "up": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "down": {"uv": [0, 0, 2, 0], "texture": "#propagule"} + } + }, + { + "from": [7, 14, 8], + "to": [9, 16, 8], + "rotation": {"angle": 45, "axis": "y", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 2], "texture": "#propagule"}, + "east": {"uv": [0, 0, 0, 2], "texture": "#propagule"}, + "south": {"uv": [0, 0, 2, 2], "texture": "#propagule"}, + "west": {"uv": [0, 0, 0, 2], "texture": "#propagule"}, + "up": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "down": {"uv": [0, 0, 2, 0], "texture": "#propagule"} + } + }, + { + "from": [7, 7, 8], + "to": [9, 10, 8], + "rotation": {"angle": 45, "axis": "y", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [3, 7, 5, 10], "texture": "#propagule"}, + "east": {"uv": [13, 0, 13, 10], "texture": "#propagule"}, + "south": {"uv": [3, 7, 5, 10], "texture": "#propagule"}, + "west": {"uv": [11, 0, 11, 10], "texture": "#propagule"}, + "up": {"uv": [11, 0, 13, 0], "texture": "#propagule"}, + "down": {"uv": [11, 10, 13, 10], "texture": "#propagule"} + } + }, + { + "from": [7, 7, 8], + "to": [9, 10, 8], + "rotation": {"angle": -45, "axis": "y", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [3, 7, 5, 10], "texture": "#propagule"}, + "east": {"uv": [11, 0, 11, 10], "texture": "#propagule"}, + "south": {"uv": [3, 7, 5, 10], "texture": "#propagule"}, + "west": {"uv": [13, 0, 13, 10], "texture": "#propagule"}, + "up": {"uv": [11, 0, 13, 0], "rotation": 180, "texture": "#propagule"}, + "down": {"uv": [11, 10, 13, 10], "rotation": 180, "texture": "#propagule"} + } + } + ] +} diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_propagule_hanging_3.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_propagule_hanging_3.json new file mode 100644 index 0000000..c6f72f2 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_propagule_hanging_3.json @@ -0,0 +1,139 @@ +{ + "parent": "block/block", + "textures": { + "propagule": "wildbackport:block/mangrove_propagule_hanging", + "particle": "wildbackport:block/mangrove_propagule_hanging" + }, + "elements": [ + { + "from": [7, 10, 7], + "to": [9, 13, 9], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 7, 2, 10], "texture": "#propagule"}, + "east": {"uv": [0, 7, 2, 10], "texture": "#propagule"}, + "south": {"uv": [0, 7, 2, 10], "texture": "#propagule"}, + "west": {"uv": [0, 7, 2, 10], "texture": "#propagule"}, + "up": {"uv": [0, 5, 2, 7], "texture": "#propagule"}, + "down": {"uv": [0, 10, 2, 12], "texture": "#propagule"} + } + }, + { + "from": [7, 13.61104, 10.07193], + "to": [9, 13.61104, 12.07193], + "rotation": {"angle": 22.5, "axis": "x", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "east": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "south": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "west": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "up": {"uv": [8, 3, 10, 5], "rotation": 180, "texture": "#propagule"}, + "down": {"uv": [6, 3, 8, 5], "texture": "#propagule"} + } + }, + { + "from": [10.07193, 13.61104, 7], + "to": [12.07193, 13.61104, 9], + "rotation": {"angle": -22.5, "axis": "z", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "east": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "south": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "west": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "up": {"uv": [8, 3, 10, 5], "rotation": 90, "texture": "#propagule"}, + "down": {"uv": [6, 3, 8, 5], "rotation": 90, "texture": "#propagule"} + } + }, + { + "from": [7, 13.61104, 3.92807], + "to": [9, 13.61104, 5.92807], + "rotation": {"angle": -22.5, "axis": "x", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "east": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "south": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "west": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "up": {"uv": [8, 3, 10, 5], "texture": "#propagule"}, + "down": {"uv": [6, 3, 8, 5], "rotation": 180, "texture": "#propagule"} + } + }, + { + "from": [3.92807, 13.61104, 7], + "to": [5.92807, 13.61104, 9], + "rotation": {"angle": 22.5, "axis": "z", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "east": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "south": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "west": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "up": {"uv": [8, 3, 10, 5], "rotation": 270, "texture": "#propagule"}, + "down": {"uv": [6, 3, 8, 5], "rotation": 270, "texture": "#propagule"} + } + }, + { + "from": [7, 13, 7], + "to": [9, 14, 9], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 2, 2, 3], "texture": "#propagule"}, + "east": {"uv": [0, 2, 2, 3], "texture": "#propagule"}, + "south": {"uv": [0, 2, 2, 3], "texture": "#propagule"}, + "west": {"uv": [0, 2, 2, 3], "texture": "#propagule"}, + "up": {"uv": [0, 0, 2, 2], "texture": "#propagule"}, + "down": {"uv": [0, 3, 2, 5], "texture": "#propagule"} + } + }, + { + "from": [7, 14, 8], + "to": [9, 16, 8], + "rotation": {"angle": -45, "axis": "y", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 2], "texture": "#propagule"}, + "east": {"uv": [0, 0, 0, 2], "texture": "#propagule"}, + "south": {"uv": [0, 0, 2, 2], "texture": "#propagule"}, + "west": {"uv": [0, 0, 0, 2], "texture": "#propagule"}, + "up": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "down": {"uv": [0, 0, 2, 0], "texture": "#propagule"} + } + }, + { + "from": [7, 14, 8], + "to": [9, 16, 8], + "rotation": {"angle": 45, "axis": "y", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 2], "texture": "#propagule"}, + "east": {"uv": [0, 0, 0, 2], "texture": "#propagule"}, + "south": {"uv": [0, 0, 2, 2], "texture": "#propagule"}, + "west": {"uv": [0, 0, 0, 2], "texture": "#propagule"}, + "up": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "down": {"uv": [0, 0, 2, 0], "texture": "#propagule"} + } + }, + { + "from": [7, 3, 8], + "to": [9, 10, 8], + "rotation": {"angle": 45, "axis": "y", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [3, 3, 5, 10], "texture": "#propagule"}, + "east": {"uv": [13, 0, 13, 10], "texture": "#propagule"}, + "south": {"uv": [3, 3, 5, 10], "texture": "#propagule"}, + "west": {"uv": [11, 0, 11, 10], "texture": "#propagule"}, + "up": {"uv": [11, 0, 13, 0], "texture": "#propagule"}, + "down": {"uv": [11, 10, 13, 10], "texture": "#propagule"} + } + }, + { + "from": [7, 3, 8], + "to": [9, 10, 8], + "rotation": {"angle": -45, "axis": "y", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [3, 3, 5, 10], "texture": "#propagule"}, + "east": {"uv": [11, 0, 11, 10], "texture": "#propagule"}, + "south": {"uv": [3, 3, 5, 10], "texture": "#propagule"}, + "west": {"uv": [13, 0, 13, 10], "texture": "#propagule"}, + "up": {"uv": [11, 0, 13, 0], "rotation": 180, "texture": "#propagule"}, + "down": {"uv": [11, 10, 13, 10], "rotation": 180, "texture": "#propagule"} + } + } + ] +} diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_propagule_hanging_4.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_propagule_hanging_4.json new file mode 100644 index 0000000..fa193de --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_propagule_hanging_4.json @@ -0,0 +1,139 @@ +{ + "parent": "block/block", + "textures": { + "propagule": "wildbackport:block/mangrove_propagule_hanging", + "particle": "wildbackport:block/mangrove_propagule_hanging" + }, + "elements": [ + { + "from": [7, 10, 7], + "to": [9, 13, 9], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 7, 2, 10], "texture": "#propagule"}, + "east": {"uv": [0, 7, 2, 10], "texture": "#propagule"}, + "south": {"uv": [0, 7, 2, 10], "texture": "#propagule"}, + "west": {"uv": [0, 7, 2, 10], "texture": "#propagule"}, + "up": {"uv": [0, 5, 2, 7], "texture": "#propagule"}, + "down": {"uv": [0, 10, 2, 12], "texture": "#propagule"} + } + }, + { + "from": [7, 13.61104, 10.07193], + "to": [9, 13.61104, 12.07193], + "rotation": {"angle": 22.5, "axis": "x", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "east": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "south": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "west": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "up": {"uv": [8, 3, 10, 5], "rotation": 180, "texture": "#propagule"}, + "down": {"uv": [6, 3, 8, 5], "texture": "#propagule"} + } + }, + { + "from": [10.07193, 13.61104, 7], + "to": [12.07193, 13.61104, 9], + "rotation": {"angle": -22.5, "axis": "z", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "east": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "south": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "west": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "up": {"uv": [8, 3, 10, 5], "rotation": 90, "texture": "#propagule"}, + "down": {"uv": [6, 3, 8, 5], "rotation": 90, "texture": "#propagule"} + } + }, + { + "from": [7, 13.61104, 3.92807], + "to": [9, 13.61104, 5.92807], + "rotation": {"angle": -22.5, "axis": "x", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "east": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "south": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "west": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "up": {"uv": [8, 3, 10, 5], "texture": "#propagule"}, + "down": {"uv": [6, 3, 8, 5], "rotation": 180, "texture": "#propagule"} + } + }, + { + "from": [3.92807, 13.61104, 7], + "to": [5.92807, 13.61104, 9], + "rotation": {"angle": 22.5, "axis": "z", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "east": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "south": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "west": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "up": {"uv": [8, 3, 10, 5], "rotation": 270, "texture": "#propagule"}, + "down": {"uv": [6, 3, 8, 5], "rotation": 270, "texture": "#propagule"} + } + }, + { + "from": [7, 13, 7], + "to": [9, 14, 9], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 2, 2, 3], "texture": "#propagule"}, + "east": {"uv": [0, 2, 2, 3], "texture": "#propagule"}, + "south": {"uv": [0, 2, 2, 3], "texture": "#propagule"}, + "west": {"uv": [0, 2, 2, 3], "texture": "#propagule"}, + "up": {"uv": [0, 0, 2, 2], "texture": "#propagule"}, + "down": {"uv": [0, 3, 2, 5], "texture": "#propagule"} + } + }, + { + "from": [7, 14, 8], + "to": [9, 16, 8], + "rotation": {"angle": -45, "axis": "y", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 2], "texture": "#propagule"}, + "east": {"uv": [0, 0, 0, 2], "texture": "#propagule"}, + "south": {"uv": [0, 0, 2, 2], "texture": "#propagule"}, + "west": {"uv": [0, 0, 0, 2], "texture": "#propagule"}, + "up": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "down": {"uv": [0, 0, 2, 0], "texture": "#propagule"} + } + }, + { + "from": [7, 14, 8], + "to": [9, 16, 8], + "rotation": {"angle": 45, "axis": "y", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 2], "texture": "#propagule"}, + "east": {"uv": [0, 0, 0, 2], "texture": "#propagule"}, + "south": {"uv": [0, 0, 2, 2], "texture": "#propagule"}, + "west": {"uv": [0, 0, 0, 2], "texture": "#propagule"}, + "up": {"uv": [0, 0, 2, 0], "texture": "#propagule"}, + "down": {"uv": [0, 0, 2, 0], "texture": "#propagule"} + } + }, + { + "from": [7, 0, 8], + "to": [9, 10, 8], + "rotation": {"angle": 45, "axis": "y", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [3, 0, 5, 10], "texture": "#propagule"}, + "east": {"uv": [13, 0, 13, 10], "texture": "#propagule"}, + "south": {"uv": [3, 0, 5, 10], "texture": "#propagule"}, + "west": {"uv": [11, 0, 11, 10], "texture": "#propagule"}, + "up": {"uv": [11, 0, 13, 0], "texture": "#propagule"}, + "down": {"uv": [11, 10, 13, 10], "texture": "#propagule"} + } + }, + { + "from": [7, 0, 8], + "to": [9, 10, 8], + "rotation": {"angle": -45, "axis": "y", "origin": [8, 16, 8]}, + "faces": { + "north": {"uv": [3, 0, 5, 10], "texture": "#propagule"}, + "east": {"uv": [11, 0, 11, 10], "texture": "#propagule"}, + "south": {"uv": [3, 0, 5, 10], "texture": "#propagule"}, + "west": {"uv": [13, 0, 13, 10], "texture": "#propagule"}, + "up": {"uv": [11, 0, 13, 0], "rotation": 180, "texture": "#propagule"}, + "down": {"uv": [11, 10, 13, 10], "rotation": 180, "texture": "#propagule"} + } + } + ] +} diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_roots.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_roots.json new file mode 100644 index 0000000..47166f3 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_roots.json @@ -0,0 +1,76 @@ +{ + "parent": "block/block", + "textures": { + "side": "wildbackport:block/mangrove_roots_side", + "top": "wildbackport:block/mangrove_roots_top", + "particle": "#side" + }, + "elements": [ + { + "from": [ 0.8, 0, 8 ], + "to": [ 15.2, 16, 8 ], + "shade": false, + "faces": { + "north": { "uv": [ 0, 0, 16, 16 ], "texture": "#side" }, + "south": { "uv": [ 0, 0, 16, 16 ], "texture": "#side" } + } + }, + { + "from": [ 8, 0, 0.8 ], + "to": [ 8, 16, 15.2 ], + "shade": false, + "faces": { + "west": { "uv": [ 0, 0, 16, 16 ], "texture": "#side" }, + "east": { "uv": [ 0, 0, 16, 16 ], "texture": "#side" } + } + }, + { + "from": [ 0, 15.998, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "down": { "uv": [ 0, 16, 16, 0 ], "texture": "#top", "cullface": "up" }, + "up": { "uv": [ 0, 0, 16, 16 ], "texture": "#top", "cullface": "up" } + } + }, + { + "from": [ 0, 0, 0 ], + "to": [ 16, 0.002, 16 ], + "faces": { + "down": { "uv": [ 0, 0, 16, 16 ], "texture": "#top", "cullface": "down" }, + "up": { "uv": [ 0, 16, 16, 0 ], "texture": "#top", "cullface": "down" } + } + }, + { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 0.002 ], + "faces": { + "north": { "uv": [ 0, 0, 16, 16 ], "texture": "#side", "cullface": "north" }, + "south": { "uv": [ 16, 0, 0, 16 ], "texture": "#side", "cullface": "north" } + } + }, + { + "from": [ 0, 0, 15.998 ], + "to": [ 16, 16, 16 ], + "faces": { + "north": { "uv": [ 16, 0, 0, 16 ], "texture": "#side", "cullface": "south" }, + "south": { "uv": [ 0, 0, 16, 16 ], "texture": "#side", "cullface": "south" } + } + }, + { + "from": [ 0, 0, 0 ], + "to": [ 0.002, 16, 16 ], + "faces": { + "east": { "uv": [ 16, 0, 0, 16 ], "texture": "#side", "cullface": "west" }, + "west": { "uv": [ 0, 0, 16, 16 ], "texture": "#side", "cullface": "west" } + } + }, + { + "from": [ 15.998, 0, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "east": { "uv": [ 0, 0, 16, 16 ], "texture": "#side", "cullface": "east" }, + "west": { "uv": [ 16, 0, 0, 16 ], "texture": "#side", "cullface": "east" } + } + } + ] +} diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_sign.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_sign.json new file mode 100644 index 0000000..3c712eb --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_sign.json @@ -0,0 +1,5 @@ +{ + "textures": { + "particle": "wildbackport:block/mangrove_planks" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_slab.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_slab.json new file mode 100644 index 0000000..7827f28 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_slab.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/slab", + "textures": { + "bottom": "wildbackport:block/mangrove_planks", + "top": "wildbackport:block/mangrove_planks", + "side": "wildbackport:block/mangrove_planks" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_slab_top.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_slab_top.json new file mode 100644 index 0000000..ff8c10e --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_slab_top.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/slab_top", + "textures": { + "bottom": "wildbackport:block/mangrove_planks", + "top": "wildbackport:block/mangrove_planks", + "side": "wildbackport:block/mangrove_planks" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_stairs.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_stairs.json new file mode 100644 index 0000000..1ebfb07 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_stairs.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/stairs", + "textures": { + "bottom": "wildbackport:block/mangrove_planks", + "top": "wildbackport:block/mangrove_planks", + "side": "wildbackport:block/mangrove_planks" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_stairs_inner.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_stairs_inner.json new file mode 100644 index 0000000..b62ce4c --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_stairs_inner.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/inner_stairs", + "textures": { + "bottom": "wildbackport:block/mangrove_planks", + "top": "wildbackport:block/mangrove_planks", + "side": "wildbackport:block/mangrove_planks" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_stairs_outer.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_stairs_outer.json new file mode 100644 index 0000000..d36040c --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_stairs_outer.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/outer_stairs", + "textures": { + "bottom": "wildbackport:block/mangrove_planks", + "top": "wildbackport:block/mangrove_planks", + "side": "wildbackport:block/mangrove_planks" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_trapdoor_bottom.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_trapdoor_bottom.json new file mode 100644 index 0000000..63fb858 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_trapdoor_bottom.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_orientable_trapdoor_bottom", + "textures": { + "texture": "wildbackport:block/mangrove_trapdoor" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_trapdoor_open.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_trapdoor_open.json new file mode 100644 index 0000000..5bc520a --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_trapdoor_open.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_orientable_trapdoor_open", + "textures": { + "texture": "wildbackport:block/mangrove_trapdoor" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_trapdoor_top.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_trapdoor_top.json new file mode 100644 index 0000000..8411e79 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_trapdoor_top.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_orientable_trapdoor_top", + "textures": { + "texture": "wildbackport:block/mangrove_trapdoor" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mangrove_wood.json b/common/src/main/resources/assets/wildbackport/models/block/mangrove_wood.json new file mode 100644 index 0000000..83a4592 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mangrove_wood.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column", + "textures": { + "end": "wildbackport:block/mangrove_log", + "side": "wildbackport:block/mangrove_log" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mud.json b/common/src/main/resources/assets/wildbackport/models/block/mud.json new file mode 100644 index 0000000..9941f00 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mud.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cube_all", + "textures": { + "all": "wildbackport:block/mud" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mud_brick_slab.json b/common/src/main/resources/assets/wildbackport/models/block/mud_brick_slab.json new file mode 100644 index 0000000..987096c --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mud_brick_slab.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/slab", + "textures": { + "bottom": "wildbackport:block/mud_bricks", + "top": "wildbackport:block/mud_bricks", + "side": "wildbackport:block/mud_bricks" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mud_brick_slab_top.json b/common/src/main/resources/assets/wildbackport/models/block/mud_brick_slab_top.json new file mode 100644 index 0000000..c0d725c --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mud_brick_slab_top.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/slab_top", + "textures": { + "bottom": "wildbackport:block/mud_bricks", + "top": "wildbackport:block/mud_bricks", + "side": "wildbackport:block/mud_bricks" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mud_brick_stairs.json b/common/src/main/resources/assets/wildbackport/models/block/mud_brick_stairs.json new file mode 100644 index 0000000..bdac271 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mud_brick_stairs.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/stairs", + "textures": { + "bottom": "wildbackport:block/mud_bricks", + "top": "wildbackport:block/mud_bricks", + "side": "wildbackport:block/mud_bricks" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mud_brick_stairs_inner.json b/common/src/main/resources/assets/wildbackport/models/block/mud_brick_stairs_inner.json new file mode 100644 index 0000000..3d8a5e1 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mud_brick_stairs_inner.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/inner_stairs", + "textures": { + "bottom": "wildbackport:block/mud_bricks", + "top": "wildbackport:block/mud_bricks", + "side": "wildbackport:block/mud_bricks" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mud_brick_stairs_outer.json b/common/src/main/resources/assets/wildbackport/models/block/mud_brick_stairs_outer.json new file mode 100644 index 0000000..2a5cd22 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mud_brick_stairs_outer.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/outer_stairs", + "textures": { + "bottom": "wildbackport:block/mud_bricks", + "top": "wildbackport:block/mud_bricks", + "side": "wildbackport:block/mud_bricks" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mud_brick_wall_inventory.json b/common/src/main/resources/assets/wildbackport/models/block/mud_brick_wall_inventory.json new file mode 100644 index 0000000..455873b --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mud_brick_wall_inventory.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/wall_inventory", + "textures": { + "wall": "wildbackport:block/mud_bricks" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mud_brick_wall_post.json b/common/src/main/resources/assets/wildbackport/models/block/mud_brick_wall_post.json new file mode 100644 index 0000000..0881a8d --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mud_brick_wall_post.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_wall_post", + "textures": { + "wall": "wildbackport:block/mud_bricks" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mud_brick_wall_side.json b/common/src/main/resources/assets/wildbackport/models/block/mud_brick_wall_side.json new file mode 100644 index 0000000..880e0d2 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mud_brick_wall_side.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_wall_side", + "textures": { + "wall": "wildbackport:block/mud_bricks" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mud_brick_wall_side_tall.json b/common/src/main/resources/assets/wildbackport/models/block/mud_brick_wall_side_tall.json new file mode 100644 index 0000000..e273d09 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mud_brick_wall_side_tall.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_wall_side_tall", + "textures": { + "wall": "wildbackport:block/mud_bricks" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mud_bricks.json b/common/src/main/resources/assets/wildbackport/models/block/mud_bricks.json new file mode 100644 index 0000000..bb482ee --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mud_bricks.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cube_all", + "textures": { + "all": "wildbackport:block/mud_bricks" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/mud_bricks_north_west_mirrored.json b/common/src/main/resources/assets/wildbackport/models/block/mud_bricks_north_west_mirrored.json new file mode 100644 index 0000000..84815dd --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/mud_bricks_north_west_mirrored.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cube_north_west_mirrored_all", + "textures": { + "all": "minecraft:block/mud_bricks" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/muddy_mangrove_roots.json b/common/src/main/resources/assets/wildbackport/models/block/muddy_mangrove_roots.json new file mode 100644 index 0000000..5e40a42 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/muddy_mangrove_roots.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column", + "textures": { + "end": "wildbackport:block/muddy_mangrove_roots_top", + "side": "wildbackport:block/muddy_mangrove_roots_side" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/ochre_froglight.json b/common/src/main/resources/assets/wildbackport/models/block/ochre_froglight.json new file mode 100644 index 0000000..eaa8ea8 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/ochre_froglight.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column", + "textures": { + "end": "wildbackport:block/ochre_froglight_top", + "side": "wildbackport:block/ochre_froglight_side" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/ochre_froglight_horizontal.json b/common/src/main/resources/assets/wildbackport/models/block/ochre_froglight_horizontal.json new file mode 100644 index 0000000..4cec3d1 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/ochre_froglight_horizontal.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column_horizontal", + "textures": { + "end": "wildbackport:block/ochre_froglight_top", + "side": "wildbackport:block/ochre_froglight_side" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/packed_mud.json b/common/src/main/resources/assets/wildbackport/models/block/packed_mud.json new file mode 100644 index 0000000..38ea63b --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/packed_mud.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cube_all", + "textures": { + "all": "wildbackport:block/packed_mud" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/pearlescent_froglight.json b/common/src/main/resources/assets/wildbackport/models/block/pearlescent_froglight.json new file mode 100644 index 0000000..4671eff --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/pearlescent_froglight.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column", + "textures": { + "end": "wildbackport:block/pearlescent_froglight_top", + "side": "wildbackport:block/pearlescent_froglight_side" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/pearlescent_froglight_horizontal.json b/common/src/main/resources/assets/wildbackport/models/block/pearlescent_froglight_horizontal.json new file mode 100644 index 0000000..dad978d --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/pearlescent_froglight_horizontal.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column_horizontal", + "textures": { + "end": "wildbackport:block/pearlescent_froglight_top", + "side": "wildbackport:block/pearlescent_froglight_side" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/potted_mangrove_propagule.json b/common/src/main/resources/assets/wildbackport/models/block/potted_mangrove_propagule.json new file mode 100644 index 0000000..eab6298 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/potted_mangrove_propagule.json @@ -0,0 +1,119 @@ +{ + "ambientocclusion": false, + "textures": { + "particle": "block/flower_pot", + "sapling": "wildbackport:block/mangrove_propagule", + "flowerpot": "block/flower_pot", + "dirt": "block/dirt" + }, + "elements": [ + { + "name": "leaves", + "from": [4.5, 9, 8], + "to": [11.5, 15, 8], + "rotation": {"angle": -45, "axis": "y", "origin": [8, 0, 8], "rescale": true}, + "faces": { + "north": {"uv": [4, 1, 11, 7], "texture": "#sapling"}, + "east": {"uv": [11, 6, 11, 10], "texture": "#sapling"}, + "south": {"uv": [4, 1, 11, 7], "texture": "#sapling"}, + "west": {"uv": [4, 6, 4, 11], "texture": "#sapling"}, + "up": {"uv": [4, 6, 11, 6], "rotation": 180, "texture": "#sapling"}, + "down": {"uv": [4, 11, 11, 11], "rotation": 180, "texture": "#sapling"} + } + }, + { + "name": "leaves", + "from": [8, 9, 4.5], + "to": [8, 15, 11.5], + "rotation": {"angle": -45, "axis": "y", "origin": [8, 0, 8], "rescale": true}, + "faces": { + "north": {"uv": [13, 0, 13, 10], "texture": "#sapling"}, + "east": {"uv": [4, 1, 11, 7], "texture": "#sapling"}, + "south": {"uv": [11, 0, 11, 10], "texture": "#sapling"}, + "west": {"uv": [4, 1, 11, 7], "texture": "#sapling"}, + "up": {"uv": [11, 0, 13, 0], "rotation": 270, "texture": "#sapling"}, + "down": {"uv": [11, 10, 13, 10], "rotation": 90, "texture": "#sapling"} + } + }, + { + "name": "hypocotyl", + "from": [7, 0, 8], + "to": [9, 9, 8], + "rotation": {"angle": -45, "axis": "y", "origin": [8, 0, 8], "rescale": true}, + "faces": { + "north": {"uv": [7, 7, 9, 16], "texture": "#sapling"}, + "east": {"uv": [11, 0, 11, 10], "texture": "#sapling"}, + "south": {"uv": [7, 7, 9, 16], "texture": "#sapling"}, + "west": {"uv": [13, 0, 13, 10], "texture": "#sapling"}, + "up": {"uv": [11, 0, 13, 0], "rotation": 180, "texture": "#sapling"}, + "down": {"uv": [11, 10, 13, 10], "rotation": 180, "texture": "#sapling"} + } + }, + { + "name": "hypocotyl", + "from": [7, 0, 8], + "to": [9, 9, 8], + "rotation": {"angle": 45, "axis": "y", "origin": [8, 0, 8], "rescale": true}, + "faces": { + "north": {"uv": [7, 7, 9, 16], "texture": "#sapling"}, + "east": {"uv": [13, 0, 13, 10], "texture": "#sapling"}, + "south": {"uv": [7, 7, 9, 16], "texture": "#sapling"}, + "west": {"uv": [11, 0, 11, 10], "texture": "#sapling"}, + "up": {"uv": [11, 0, 13, 0], "texture": "#sapling"}, + "down": {"uv": [11, 10, 13, 10], "texture": "#sapling"} + } + }, + { + "from": [5, 0, 5], + "to": [6, 6, 11], + "faces": { + "north": {"uv": [10, 10, 11, 16], "texture": "#flowerpot"}, + "east": {"uv": [5, 10, 11, 16], "texture": "#flowerpot"}, + "south": {"uv": [5, 10, 6, 16], "texture": "#flowerpot"}, + "west": {"uv": [5, 10, 11, 16], "texture": "#flowerpot"}, + "up": {"uv": [5, 5, 6, 11], "texture": "#flowerpot"}, + "down": {"uv": [5, 5, 6, 11], "texture": "#flowerpot", "cullface": "down"} + } + }, + { + "from": [10, 0, 5], + "to": [11, 6, 11], + "faces": { + "north": {"uv": [5, 10, 6, 16], "texture": "#flowerpot"}, + "east": {"uv": [5, 10, 11, 16], "texture": "#flowerpot"}, + "south": {"uv": [10, 10, 11, 16], "texture": "#flowerpot"}, + "west": {"uv": [5, 10, 11, 16], "texture": "#flowerpot"}, + "up": {"uv": [10, 5, 11, 11], "texture": "#flowerpot"}, + "down": {"uv": [10, 5, 11, 11], "texture": "#flowerpot", "cullface": "down"} + } + }, + { + "from": [6, 0, 5], + "to": [10, 6, 6], + "faces": { + "north": {"uv": [6, 10, 10, 16], "texture": "#flowerpot"}, + "south": {"uv": [6, 10, 10, 16], "texture": "#flowerpot"}, + "up": {"uv": [6, 5, 10, 6], "texture": "#flowerpot"}, + "down": {"uv": [6, 10, 10, 11], "texture": "#flowerpot", "cullface": "down"} + } + }, + { + "from": [6, 0, 10], + "to": [10, 6, 11], + "faces": { + "north": {"uv": [6, 10, 10, 16], "texture": "#flowerpot"}, + "south": {"uv": [6, 10, 10, 16], "texture": "#flowerpot"}, + "up": {"uv": [6, 10, 10, 11], "texture": "#flowerpot"}, + "down": {"uv": [6, 5, 10, 6], "texture": "#flowerpot", "cullface": "down"} + } + }, + { + "from": [6, 0, 6], + "to": [10, 4, 10], + "faces": { + "up": {"uv": [6, 6, 10, 10], "texture": "#dirt"}, + "down": {"uv": [6, 12, 10, 16], "texture": "#flowerpot", "cullface": "down"} + } + } + ] +} diff --git a/common/src/main/resources/assets/wildbackport/models/block/reinforced_deepslate.json b/common/src/main/resources/assets/wildbackport/models/block/reinforced_deepslate.json new file mode 100644 index 0000000..cd5ec9f --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/reinforced_deepslate.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "particle": "wildbackport:block/reinforced_deepslate_top", + "north": "wildbackport:block/reinforced_deepslate_side", + "south": "wildbackport:block/reinforced_deepslate_side", + "east": "wildbackport:block/reinforced_deepslate_side", + "west": "wildbackport:block/reinforced_deepslate_side", + "up": "wildbackport:block/reinforced_deepslate_top", + "down": "wildbackport:block/reinforced_deepslate_bottom" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/sculk.json b/common/src/main/resources/assets/wildbackport/models/block/sculk.json new file mode 100644 index 0000000..25ea2d6 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/sculk.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cube_all", + "textures": { + "all": "wildbackport:block/sculk" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/sculk_catalyst.json b/common/src/main/resources/assets/wildbackport/models/block/sculk_catalyst.json new file mode 100644 index 0000000..f851cea --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/sculk_catalyst.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/cube_bottom_top", + "textures": { + "top": "wildbackport:block/sculk_catalyst_top", + "bottom": "wildbackport:block/sculk_catalyst_bottom", + "side": "wildbackport:block/sculk_catalyst_side" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/sculk_catalyst_bloom.json b/common/src/main/resources/assets/wildbackport/models/block/sculk_catalyst_bloom.json new file mode 100644 index 0000000..4b4d491 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/sculk_catalyst_bloom.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/cube_bottom_top", + "textures": { + "top": "wildbackport:block/sculk_catalyst_top_bloom", + "bottom": "wildbackport:block/sculk_catalyst_bottom", + "side": "wildbackport:block/sculk_catalyst_side_bloom" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/sculk_mirrored.json b/common/src/main/resources/assets/wildbackport/models/block/sculk_mirrored.json new file mode 100644 index 0000000..a06a70c --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/sculk_mirrored.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cube_mirrored_all", + "textures": { + "all": "wildbackport:block/sculk" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/sculk_shrieker.json b/common/src/main/resources/assets/wildbackport/models/block/sculk_shrieker.json new file mode 100644 index 0000000..aba2a71 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/sculk_shrieker.json @@ -0,0 +1,77 @@ +{ + "parent": "block/block", + "textures": { + "bottom": "wildbackport:block/sculk_shrieker_bottom", + "side": "wildbackport:block/sculk_shrieker_side", + "top": "wildbackport:block/sculk_shrieker_top", + "inner_top": "wildbackport:block/sculk_shrieker_inner_top", + "particle": "wildbackport:block/sculk_shrieker_bottom" + }, + "elements": [ + { + "name": "bottom_slab", + "from": [0, 0, 0], + "to": [16, 8, 16], + "faces": { + "north": {"uv": [0, 8, 16, 16], "texture": "#side"}, + "east": {"uv": [0, 8, 16, 16], "texture": "#side"}, + "south": {"uv": [0, 8, 16, 16], "texture": "#side"}, + "west": {"uv": [0, 8, 16, 16], "texture": "#side"}, + "up": {"uv": [0, 0, 16, 16], "texture": "#inner_top"}, + "down": {"uv": [0, 0, 16, 16], "texture": "#bottom"} + } + }, + { + "name": "top_slab", + "from": [1, 8, 1], + "to": [15, 15, 15], + "faces": { + "north": {"uv": [1, 0, 15, 8], "texture": "#side"}, + "east": {"uv": [1, 0, 15, 8], "texture": "#side"}, + "south": {"uv": [1, 0, 15, 8], "texture": "#side"}, + "west": {"uv": [1, 0, 15, 8], "texture": "#side"}, + "up": {"uv": [1, 1, 15, 15], "texture": "#top"} + } + }, + { + "name": "up", + "from": [1, 14.98, 1], + "to": [15, 14.98, 15], + "faces": { + "down": {"uv": [1, 1, 15, 15], "texture": "#top"} + } + }, + { + "name": "south", + "from": [1, 8, 14.98], + "to": [15, 15, 14.98], + "faces": { + "north": {"uv": [1, 0, 15, 8], "texture": "#side"} + } + }, + { + "name": "north", + "from": [1, 8, 1.02], + "to": [15, 15, 1.02], + "faces": { + "south": {"uv": [1, 0, 15, 8], "texture": "#side"} + } + }, + { + "name": "east", + "from": [14.98, 8, 1], + "to": [14.98, 15, 15], + "faces": { + "west": {"uv": [1, 0, 15, 8], "texture": "#side"} + } + }, + { + "name": "west", + "from": [1.02, 8, 1], + "to": [1.02, 15, 15], + "faces": { + "east": {"uv": [1, 0, 15, 8], "texture": "#side", "cullface": "east"} + } + } + ] +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/sculk_vein.json b/common/src/main/resources/assets/wildbackport/models/block/sculk_vein.json new file mode 100644 index 0000000..f845882 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/sculk_vein.json @@ -0,0 +1,16 @@ +{ + "ambientocclusion": false, + "textures": { + "particle": "wildbackport:block/sculk_vein", + "sculk_vein": "wildbackport:block/sculk_vein" + }, + "elements": [ + { "from": [ 0, 0, 0.1 ], + "to": [ 16, 16, 0.1 ], + "faces": { + "north": { "uv": [ 0, 0, 16, 16 ], "texture": "#sculk_vein" }, + "south": { "uv": [ 0, 0, 16, 16 ], "texture": "#sculk_vein" } + } + } + ] +} diff --git a/common/src/main/resources/assets/wildbackport/models/block/stripped_mangrove_log.json b/common/src/main/resources/assets/wildbackport/models/block/stripped_mangrove_log.json new file mode 100644 index 0000000..38629fb --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/stripped_mangrove_log.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column", + "textures": { + "end": "wildbackport:block/stripped_mangrove_log_top", + "side": "wildbackport:block/stripped_mangrove_log" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/stripped_mangrove_log_horizontal.json b/common/src/main/resources/assets/wildbackport/models/block/stripped_mangrove_log_horizontal.json new file mode 100644 index 0000000..391b761 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/stripped_mangrove_log_horizontal.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column_horizontal", + "textures": { + "end": "wildbackport:block/stripped_mangrove_log_top", + "side": "wildbackport:block/stripped_mangrove_log" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/stripped_mangrove_wood.json b/common/src/main/resources/assets/wildbackport/models/block/stripped_mangrove_wood.json new file mode 100644 index 0000000..4319cf2 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/stripped_mangrove_wood.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column", + "textures": { + "end": "wildbackport:block/stripped_mangrove_log", + "side": "wildbackport:block/stripped_mangrove_log" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/verdant_froglight.json b/common/src/main/resources/assets/wildbackport/models/block/verdant_froglight.json new file mode 100644 index 0000000..d01e313 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/verdant_froglight.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column", + "textures": { + "end": "wildbackport:block/verdant_froglight_top", + "side": "wildbackport:block/verdant_froglight_side" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/block/verdant_froglight_horizontal.json b/common/src/main/resources/assets/wildbackport/models/block/verdant_froglight_horizontal.json new file mode 100644 index 0000000..b700a50 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/block/verdant_froglight_horizontal.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column_horizontal", + "textures": { + "end": "wildbackport:block/verdant_froglight_top", + "side": "wildbackport:block/verdant_froglight_side" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/acacia_chest_boat.json b/common/src/main/resources/assets/wildbackport/models/item/acacia_chest_boat.json new file mode 100644 index 0000000..9c5fb4b --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/acacia_chest_boat.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/acacia_chest_boat" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/allay_spawn_egg.json b/common/src/main/resources/assets/wildbackport/models/item/allay_spawn_egg.json new file mode 100644 index 0000000..d1aaa9d --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/allay_spawn_egg.json @@ -0,0 +1,3 @@ +{ + "parent": "minecraft:item/template_spawn_egg" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/birch_chest_boat.json b/common/src/main/resources/assets/wildbackport/models/item/birch_chest_boat.json new file mode 100644 index 0000000..566d5f2 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/birch_chest_boat.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/birch_chest_boat" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/dark_oak_chest_boat.json b/common/src/main/resources/assets/wildbackport/models/item/dark_oak_chest_boat.json new file mode 100644 index 0000000..b672080 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/dark_oak_chest_boat.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/dark_oak_chest_boat" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/disc_fragment_5.json b/common/src/main/resources/assets/wildbackport/models/item/disc_fragment_5.json new file mode 100644 index 0000000..20ca986 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/disc_fragment_5.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/disc_fragment_5" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/echo_shard.json b/common/src/main/resources/assets/wildbackport/models/item/echo_shard.json new file mode 100644 index 0000000..2feadc6 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/echo_shard.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/echo_shard" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/frog_spawn_egg.json b/common/src/main/resources/assets/wildbackport/models/item/frog_spawn_egg.json new file mode 100644 index 0000000..d1aaa9d --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/frog_spawn_egg.json @@ -0,0 +1,3 @@ +{ + "parent": "minecraft:item/template_spawn_egg" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/frogspawn.json b/common/src/main/resources/assets/wildbackport/models/item/frogspawn.json new file mode 100644 index 0000000..35eb803 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/frogspawn.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:block/frogspawn" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/goat_horn.json b/common/src/main/resources/assets/wildbackport/models/item/goat_horn.json new file mode 100644 index 0000000..98d94d9 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/goat_horn.json @@ -0,0 +1,36 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "wildbackport:item/goat_horn" + }, + "display": { + "thirdperson_righthand": { + "rotation": [ 0, 180, 0 ], + "translation": [ 0, 3, 1 ], + "scale": [ 0.55, 0.55, 0.55 ] + }, + "thirdperson_lefthand": { + "rotation": [ 0, 0, 0 ], + "translation": [ 0, 3, 1 ], + "scale": [ 0.55, 0.55, 0.55 ] + }, + "firstperson_righthand": { + "rotation": [ 0, -90, 25 ], + "translation": [ 1.13, 3.2, 1.13 ], + "scale": [ 0.68, 0.68, 0.68 ] + }, + "firstperson_lefthand": { + "rotation": [ 0, 90, -25 ], + "translation": [ 1.13, 3.2, 1.13 ], + "scale": [ 0.68, 0.68, 0.68 ] + } + }, + "overrides": [ + { + "predicate": { + "tooting": 1 + }, + "model": "wildbackport:item/tooting_goat_horn" + } + ] +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/jungle_chest_boat.json b/common/src/main/resources/assets/wildbackport/models/item/jungle_chest_boat.json new file mode 100644 index 0000000..6b60ba8 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/jungle_chest_boat.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/jungle_chest_boat" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/mangrove_boat.json b/common/src/main/resources/assets/wildbackport/models/item/mangrove_boat.json new file mode 100644 index 0000000..f37b7c8 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/mangrove_boat.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/mangrove_boat" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/mangrove_button.json b/common/src/main/resources/assets/wildbackport/models/item/mangrove_button.json new file mode 100644 index 0000000..ca30570 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/mangrove_button.json @@ -0,0 +1,3 @@ +{ + "parent": "wildbackport:block/mangrove_button_inventory" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/mangrove_chest_boat.json b/common/src/main/resources/assets/wildbackport/models/item/mangrove_chest_boat.json new file mode 100644 index 0000000..bccbdb2 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/mangrove_chest_boat.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/mangrove_chest_boat" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/mangrove_door.json b/common/src/main/resources/assets/wildbackport/models/item/mangrove_door.json new file mode 100644 index 0000000..9822e99 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/mangrove_door.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/mangrove_door" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/mangrove_fence.json b/common/src/main/resources/assets/wildbackport/models/item/mangrove_fence.json new file mode 100644 index 0000000..ba6f3c5 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/mangrove_fence.json @@ -0,0 +1,3 @@ +{ + "parent": "wildbackport:block/mangrove_fence_inventory" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/mangrove_fence_gate.json b/common/src/main/resources/assets/wildbackport/models/item/mangrove_fence_gate.json new file mode 100644 index 0000000..f9dd38c --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/mangrove_fence_gate.json @@ -0,0 +1,3 @@ +{ + "parent": "wildbackport:block/mangrove_fence_gate" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/mangrove_leaves.json b/common/src/main/resources/assets/wildbackport/models/item/mangrove_leaves.json new file mode 100644 index 0000000..d7e5cdd --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/mangrove_leaves.json @@ -0,0 +1,3 @@ +{ + "parent": "wildbackport:block/mangrove_leaves" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/mangrove_log.json b/common/src/main/resources/assets/wildbackport/models/item/mangrove_log.json new file mode 100644 index 0000000..515c2a3 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/mangrove_log.json @@ -0,0 +1,3 @@ +{ + "parent": "wildbackport:block/mangrove_log" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/mangrove_planks.json b/common/src/main/resources/assets/wildbackport/models/item/mangrove_planks.json new file mode 100644 index 0000000..44df9cf --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/mangrove_planks.json @@ -0,0 +1,3 @@ +{ + "parent": "wildbackport:block/mangrove_planks" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/mangrove_pressure_plate.json b/common/src/main/resources/assets/wildbackport/models/item/mangrove_pressure_plate.json new file mode 100644 index 0000000..4d9d407 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/mangrove_pressure_plate.json @@ -0,0 +1,3 @@ +{ + "parent": "wildbackport:block/mangrove_pressure_plate" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/mangrove_propagule.json b/common/src/main/resources/assets/wildbackport/models/item/mangrove_propagule.json new file mode 100644 index 0000000..2843f49 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/mangrove_propagule.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/mangrove_propagule" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/mangrove_roots.json b/common/src/main/resources/assets/wildbackport/models/item/mangrove_roots.json new file mode 100644 index 0000000..8d05556 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/mangrove_roots.json @@ -0,0 +1,3 @@ +{ + "parent": "wildbackport:block/mangrove_roots" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/mangrove_sign.json b/common/src/main/resources/assets/wildbackport/models/item/mangrove_sign.json new file mode 100644 index 0000000..3da0965 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/mangrove_sign.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/mangrove_sign" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/mangrove_slab.json b/common/src/main/resources/assets/wildbackport/models/item/mangrove_slab.json new file mode 100644 index 0000000..5325322 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/mangrove_slab.json @@ -0,0 +1,3 @@ +{ + "parent": "wildbackport:block/mangrove_slab" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/mangrove_stairs.json b/common/src/main/resources/assets/wildbackport/models/item/mangrove_stairs.json new file mode 100644 index 0000000..c01bafd --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/mangrove_stairs.json @@ -0,0 +1,3 @@ +{ + "parent": "wildbackport:block/mangrove_stairs" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/mangrove_trapdoor.json b/common/src/main/resources/assets/wildbackport/models/item/mangrove_trapdoor.json new file mode 100644 index 0000000..15cd1eb --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/mangrove_trapdoor.json @@ -0,0 +1,3 @@ +{ + "parent": "wildbackport:block/mangrove_trapdoor_bottom" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/mangrove_wood.json b/common/src/main/resources/assets/wildbackport/models/item/mangrove_wood.json new file mode 100644 index 0000000..5bffa2b --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/mangrove_wood.json @@ -0,0 +1,3 @@ +{ + "parent": "wildbackport:block/mangrove_wood" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/mud.json b/common/src/main/resources/assets/wildbackport/models/item/mud.json new file mode 100644 index 0000000..76a8d4b --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/mud.json @@ -0,0 +1,3 @@ +{ + "parent": "wildbackport:block/mud" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/mud_brick_slab.json b/common/src/main/resources/assets/wildbackport/models/item/mud_brick_slab.json new file mode 100644 index 0000000..991d20c --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/mud_brick_slab.json @@ -0,0 +1,3 @@ +{ + "parent": "wildbackport:block/mud_brick_slab" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/mud_brick_stairs.json b/common/src/main/resources/assets/wildbackport/models/item/mud_brick_stairs.json new file mode 100644 index 0000000..3e70f1c --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/mud_brick_stairs.json @@ -0,0 +1,3 @@ +{ + "parent": "wildbackport:block/mud_brick_stairs" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/mud_brick_wall.json b/common/src/main/resources/assets/wildbackport/models/item/mud_brick_wall.json new file mode 100644 index 0000000..6d285f6 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/mud_brick_wall.json @@ -0,0 +1,3 @@ +{ + "parent": "wildbackport:block/mud_brick_wall_inventory" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/mud_bricks.json b/common/src/main/resources/assets/wildbackport/models/item/mud_bricks.json new file mode 100644 index 0000000..d42d88d --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/mud_bricks.json @@ -0,0 +1,3 @@ +{ + "parent": "wildbackport:block/mud_bricks" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/muddy_mangrove_roots.json b/common/src/main/resources/assets/wildbackport/models/item/muddy_mangrove_roots.json new file mode 100644 index 0000000..599efad --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/muddy_mangrove_roots.json @@ -0,0 +1,3 @@ +{ + "parent": "wildbackport:block/muddy_mangrove_roots" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/music_disc_5.json b/common/src/main/resources/assets/wildbackport/models/item/music_disc_5.json new file mode 100644 index 0000000..e9f890e --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/music_disc_5.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/music_disc_5" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/oak_chest_boat.json b/common/src/main/resources/assets/wildbackport/models/item/oak_chest_boat.json new file mode 100644 index 0000000..8955696 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/oak_chest_boat.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/oak_chest_boat" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/ochre_froglight.json b/common/src/main/resources/assets/wildbackport/models/item/ochre_froglight.json new file mode 100644 index 0000000..2542f9d --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/ochre_froglight.json @@ -0,0 +1,3 @@ +{ + "parent": "wildbackport:block/ochre_froglight" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/packed_mud.json b/common/src/main/resources/assets/wildbackport/models/item/packed_mud.json new file mode 100644 index 0000000..f891d0a --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/packed_mud.json @@ -0,0 +1,3 @@ +{ + "parent": "wildbackport:block/packed_mud" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/pearlescent_froglight.json b/common/src/main/resources/assets/wildbackport/models/item/pearlescent_froglight.json new file mode 100644 index 0000000..d9ac85a --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/pearlescent_froglight.json @@ -0,0 +1,3 @@ +{ + "parent": "wildbackport:block/pearlescent_froglight" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/recovery_compass.json b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass.json new file mode 100644 index 0000000..a1f488f --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass.json @@ -0,0 +1,41 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "wildbackport:item/recovery_compass_16" + }, + "overrides": [ + { "predicate": { "wildbackport:angle": 0.000000 }, "model": "wildbackport:item/recovery_compass" }, + { "predicate": { "wildbackport:angle": 0.015625 }, "model": "wildbackport:item/recovery_compass_17" }, + { "predicate": { "wildbackport:angle": 0.046875 }, "model": "wildbackport:item/recovery_compass_18" }, + { "predicate": { "wildbackport:angle": 0.078125 }, "model": "wildbackport:item/recovery_compass_19" }, + { "predicate": { "wildbackport:angle": 0.109375 }, "model": "wildbackport:item/recovery_compass_20" }, + { "predicate": { "wildbackport:angle": 0.140625 }, "model": "wildbackport:item/recovery_compass_21" }, + { "predicate": { "wildbackport:angle": 0.171875 }, "model": "wildbackport:item/recovery_compass_22" }, + { "predicate": { "wildbackport:angle": 0.203125 }, "model": "wildbackport:item/recovery_compass_23" }, + { "predicate": { "wildbackport:angle": 0.234375 }, "model": "wildbackport:item/recovery_compass_24" }, + { "predicate": { "wildbackport:angle": 0.265625 }, "model": "wildbackport:item/recovery_compass_25" }, + { "predicate": { "wildbackport:angle": 0.296875 }, "model": "wildbackport:item/recovery_compass_26" }, + { "predicate": { "wildbackport:angle": 0.328125 }, "model": "wildbackport:item/recovery_compass_27" }, + { "predicate": { "wildbackport:angle": 0.359375 }, "model": "wildbackport:item/recovery_compass_28" }, + { "predicate": { "wildbackport:angle": 0.390625 }, "model": "wildbackport:item/recovery_compass_29" }, + { "predicate": { "wildbackport:angle": 0.421875 }, "model": "wildbackport:item/recovery_compass_30" }, + { "predicate": { "wildbackport:angle": 0.453125 }, "model": "wildbackport:item/recovery_compass_31" }, + { "predicate": { "wildbackport:angle": 0.484375 }, "model": "wildbackport:item/recovery_compass_00" }, + { "predicate": { "wildbackport:angle": 0.515625 }, "model": "wildbackport:item/recovery_compass_01" }, + { "predicate": { "wildbackport:angle": 0.546875 }, "model": "wildbackport:item/recovery_compass_02" }, + { "predicate": { "wildbackport:angle": 0.578125 }, "model": "wildbackport:item/recovery_compass_03" }, + { "predicate": { "wildbackport:angle": 0.609375 }, "model": "wildbackport:item/recovery_compass_04" }, + { "predicate": { "wildbackport:angle": 0.640625 }, "model": "wildbackport:item/recovery_compass_05" }, + { "predicate": { "wildbackport:angle": 0.671875 }, "model": "wildbackport:item/recovery_compass_06" }, + { "predicate": { "wildbackport:angle": 0.703125 }, "model": "wildbackport:item/recovery_compass_07" }, + { "predicate": { "wildbackport:angle": 0.734375 }, "model": "wildbackport:item/recovery_compass_08" }, + { "predicate": { "wildbackport:angle": 0.765625 }, "model": "wildbackport:item/recovery_compass_09" }, + { "predicate": { "wildbackport:angle": 0.796875 }, "model": "wildbackport:item/recovery_compass_10" }, + { "predicate": { "wildbackport:angle": 0.828125 }, "model": "wildbackport:item/recovery_compass_11" }, + { "predicate": { "wildbackport:angle": 0.859375 }, "model": "wildbackport:item/recovery_compass_12" }, + { "predicate": { "wildbackport:angle": 0.890625 }, "model": "wildbackport:item/recovery_compass_13" }, + { "predicate": { "wildbackport:angle": 0.921875 }, "model": "wildbackport:item/recovery_compass_14" }, + { "predicate": { "wildbackport:angle": 0.953125 }, "model": "wildbackport:item/recovery_compass_15" }, + { "predicate": { "wildbackport:angle": 0.984375 }, "model": "wildbackport:item/recovery_compass" } + ] +} diff --git a/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_00.json b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_00.json new file mode 100644 index 0000000..d1d8d6a --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_00.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/recovery_compass_00" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_01.json b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_01.json new file mode 100644 index 0000000..55bd6c6 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_01.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/recovery_compass_01" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_02.json b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_02.json new file mode 100644 index 0000000..adec44e --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_02.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/recovery_compass_02" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_03.json b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_03.json new file mode 100644 index 0000000..1c16c25 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_03.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/recovery_compass_03" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_04.json b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_04.json new file mode 100644 index 0000000..363ab60 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_04.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/recovery_compass_04" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_05.json b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_05.json new file mode 100644 index 0000000..acf445c --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_05.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/recovery_compass_05" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_06.json b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_06.json new file mode 100644 index 0000000..d4149b1 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_06.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/recovery_compass_06" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_07.json b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_07.json new file mode 100644 index 0000000..821df53 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_07.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/recovery_compass_07" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_08.json b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_08.json new file mode 100644 index 0000000..f1e060a --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_08.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/recovery_compass_08" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_09.json b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_09.json new file mode 100644 index 0000000..93b7a37 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_09.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/recovery_compass_09" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_10.json b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_10.json new file mode 100644 index 0000000..17c202b --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_10.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/recovery_compass_10" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_11.json b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_11.json new file mode 100644 index 0000000..3aba1d4 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_11.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/recovery_compass_11" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_12.json b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_12.json new file mode 100644 index 0000000..3f90634 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_12.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/recovery_compass_12" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_13.json b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_13.json new file mode 100644 index 0000000..7925ce4 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_13.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/recovery_compass_13" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_14.json b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_14.json new file mode 100644 index 0000000..52ce9aa --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_14.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/recovery_compass_14" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_15.json b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_15.json new file mode 100644 index 0000000..a98bdd0 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_15.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/recovery_compass_15" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_16.json b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_16.json new file mode 100644 index 0000000..c4f8fe0 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_16.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/recovery_compass_16" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_17.json b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_17.json new file mode 100644 index 0000000..504fa9e --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_17.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/recovery_compass_17" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_18.json b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_18.json new file mode 100644 index 0000000..287a3f1 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_18.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/recovery_compass_18" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_19.json b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_19.json new file mode 100644 index 0000000..587ad35 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_19.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/recovery_compass_19" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_20.json b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_20.json new file mode 100644 index 0000000..7e7939f --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_20.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/recovery_compass_20" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_21.json b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_21.json new file mode 100644 index 0000000..6f8f80b --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_21.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/recovery_compass_21" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_22.json b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_22.json new file mode 100644 index 0000000..6d909bc --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_22.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/recovery_compass_22" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_23.json b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_23.json new file mode 100644 index 0000000..325e0cb --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_23.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/recovery_compass_23" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_24.json b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_24.json new file mode 100644 index 0000000..6b5fc46 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_24.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/recovery_compass_24" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_25.json b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_25.json new file mode 100644 index 0000000..f063a51 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_25.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/recovery_compass_25" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_26.json b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_26.json new file mode 100644 index 0000000..1c98450 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_26.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/recovery_compass_26" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_27.json b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_27.json new file mode 100644 index 0000000..90c7529 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_27.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/recovery_compass_27" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_28.json b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_28.json new file mode 100644 index 0000000..1df0cfa --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_28.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/recovery_compass_28" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_29.json b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_29.json new file mode 100644 index 0000000..028dc00 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_29.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/recovery_compass_29" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_30.json b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_30.json new file mode 100644 index 0000000..1412d03 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_30.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/recovery_compass_30" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_31.json b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_31.json new file mode 100644 index 0000000..e3cff04 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/recovery_compass_31.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/recovery_compass_31" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/reinforced_deepslate.json b/common/src/main/resources/assets/wildbackport/models/item/reinforced_deepslate.json new file mode 100644 index 0000000..9566327 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/reinforced_deepslate.json @@ -0,0 +1,3 @@ +{ + "parent": "wildbackport:block/reinforced_deepslate" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/sculk.json b/common/src/main/resources/assets/wildbackport/models/item/sculk.json new file mode 100644 index 0000000..fd47111 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/sculk.json @@ -0,0 +1,3 @@ +{ + "parent": "wildbackport:block/sculk" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/sculk_catalyst.json b/common/src/main/resources/assets/wildbackport/models/item/sculk_catalyst.json new file mode 100644 index 0000000..7701713 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/sculk_catalyst.json @@ -0,0 +1,3 @@ +{ + "parent": "wildbackport:block/sculk_catalyst" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/sculk_shrieker.json b/common/src/main/resources/assets/wildbackport/models/item/sculk_shrieker.json new file mode 100644 index 0000000..9b9a615 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/sculk_shrieker.json @@ -0,0 +1,3 @@ +{ + "parent": "wildbackport:block/sculk_shrieker" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/sculk_vein.json b/common/src/main/resources/assets/wildbackport/models/item/sculk_vein.json new file mode 100644 index 0000000..e06a8b6 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/sculk_vein.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:block/sculk_vein" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/spruce_chest_boat.json b/common/src/main/resources/assets/wildbackport/models/item/spruce_chest_boat.json new file mode 100644 index 0000000..9291a81 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/spruce_chest_boat.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/spruce_chest_boat" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/stripped_mangrove_log.json b/common/src/main/resources/assets/wildbackport/models/item/stripped_mangrove_log.json new file mode 100644 index 0000000..76e16f1 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/stripped_mangrove_log.json @@ -0,0 +1,3 @@ +{ + "parent": "wildbackport:block/stripped_mangrove_log" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/stripped_mangrove_wood.json b/common/src/main/resources/assets/wildbackport/models/item/stripped_mangrove_wood.json new file mode 100644 index 0000000..e8f1215 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/stripped_mangrove_wood.json @@ -0,0 +1,3 @@ +{ + "parent": "wildbackport:block/stripped_mangrove_wood" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/tadpole_bucket.json b/common/src/main/resources/assets/wildbackport/models/item/tadpole_bucket.json new file mode 100644 index 0000000..6001ac9 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/tadpole_bucket.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wildbackport:item/tadpole_bucket" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/tadpole_spawn_egg.json b/common/src/main/resources/assets/wildbackport/models/item/tadpole_spawn_egg.json new file mode 100644 index 0000000..d1aaa9d --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/tadpole_spawn_egg.json @@ -0,0 +1,3 @@ +{ + "parent": "minecraft:item/template_spawn_egg" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/tooting_goat_horn.json b/common/src/main/resources/assets/wildbackport/models/item/tooting_goat_horn.json new file mode 100644 index 0000000..755c454 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/tooting_goat_horn.json @@ -0,0 +1,26 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "wildbackport:item/goat_horn" + }, + "display": { + "thirdperson_righthand": { + "rotation": [ 0, -125, 0 ], + "translation": [ -1, 2, 2 ], + "scale": [ 0.5, 0.5, 0.5 ] + }, + "thirdperson_lefthand": { + "rotation": [ 0, 55, 0 ], + "translation": [ -1, 2, 2 ], + "scale": [ 0.5, 0.5, 0.5 ] + }, + "firstperson_righthand": { + "rotation": [ 0, -55, -5 ], + "translation": [ -1, -2.5, -7.5 ] + }, + "firstperson_lefthand": { + "rotation": [ 0, 115, 5 ], + "translation": [ 0 , -2.5, -7.5 ] + } + } +} diff --git a/common/src/main/resources/assets/wildbackport/models/item/verdant_froglight.json b/common/src/main/resources/assets/wildbackport/models/item/verdant_froglight.json new file mode 100644 index 0000000..2a28e58 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/verdant_froglight.json @@ -0,0 +1,3 @@ +{ + "parent": "wildbackport:block/verdant_froglight" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/models/item/warden_spawn_egg.json b/common/src/main/resources/assets/wildbackport/models/item/warden_spawn_egg.json new file mode 100644 index 0000000..d1aaa9d --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/models/item/warden_spawn_egg.json @@ -0,0 +1,3 @@ +{ + "parent": "minecraft:item/template_spawn_egg" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/particles/sculk_charge.json b/common/src/main/resources/assets/wildbackport/particles/sculk_charge.json new file mode 100644 index 0000000..3b535c9 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/particles/sculk_charge.json @@ -0,0 +1,11 @@ +{ + "textures": [ + "wildbackport:sculk_charge_0", + "wildbackport:sculk_charge_1", + "wildbackport:sculk_charge_2", + "wildbackport:sculk_charge_3", + "wildbackport:sculk_charge_4", + "wildbackport:sculk_charge_5", + "wildbackport:sculk_charge_6" + ] +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/particles/sculk_charge_pop.json b/common/src/main/resources/assets/wildbackport/particles/sculk_charge_pop.json new file mode 100644 index 0000000..15c9ba6 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/particles/sculk_charge_pop.json @@ -0,0 +1,8 @@ +{ + "textures": [ + "wildbackport:sculk_charge_pop_0", + "wildbackport:sculk_charge_pop_1", + "wildbackport:sculk_charge_pop_2", + "wildbackport:sculk_charge_pop_3" + ] +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/particles/sculk_soul.json b/common/src/main/resources/assets/wildbackport/particles/sculk_soul.json new file mode 100644 index 0000000..18df463 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/particles/sculk_soul.json @@ -0,0 +1,15 @@ +{ + "textures": [ + "wildbackport:sculk_soul_0", + "wildbackport:sculk_soul_1", + "wildbackport:sculk_soul_2", + "wildbackport:sculk_soul_3", + "wildbackport:sculk_soul_4", + "wildbackport:sculk_soul_5", + "wildbackport:sculk_soul_6", + "wildbackport:sculk_soul_7", + "wildbackport:sculk_soul_8", + "wildbackport:sculk_soul_9", + "wildbackport:sculk_soul_10" + ] +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/particles/shriek.json b/common/src/main/resources/assets/wildbackport/particles/shriek.json new file mode 100644 index 0000000..562f50c --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/particles/shriek.json @@ -0,0 +1,5 @@ +{ + "textures": [ + "wildbackport:shriek" + ] +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/particles/sonic_boom.json b/common/src/main/resources/assets/wildbackport/particles/sonic_boom.json new file mode 100644 index 0000000..cd4af5b --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/particles/sonic_boom.json @@ -0,0 +1,20 @@ +{ + "textures": [ + "wildbackport:sonic_boom_0", + "wildbackport:sonic_boom_1", + "wildbackport:sonic_boom_2", + "wildbackport:sonic_boom_3", + "wildbackport:sonic_boom_4", + "wildbackport:sonic_boom_5", + "wildbackport:sonic_boom_6", + "wildbackport:sonic_boom_7", + "wildbackport:sonic_boom_8", + "wildbackport:sonic_boom_9", + "wildbackport:sonic_boom_10", + "wildbackport:sonic_boom_11", + "wildbackport:sonic_boom_12", + "wildbackport:sonic_boom_13", + "wildbackport:sonic_boom_14", + "wildbackport:sonic_boom_15" + ] +} diff --git a/common/src/main/resources/assets/wildbackport/sounds.json b/common/src/main/resources/assets/wildbackport/sounds.json new file mode 100644 index 0000000..7b2101a --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/sounds.json @@ -0,0 +1,2525 @@ +{ + "music_disc.5": { + "sounds": [ + { + "name": "wildbackport:records/5", + "stream": true + } + ] + }, + "block.sculk.fall": { + "sounds": [ + { + "name": "wildbackport:block/sculk/step1", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step2", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step3", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step4", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step5", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step6", + "volume": 1 + } + ] + }, + "block.sculk.hit": { + "sounds": [ + { + "name": "wildbackport:block/sculk/step1", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step2", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step3", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step4", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step5", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step6", + "volume": 1 + } + ], + "subtitle": "subtitles.block.generic.hit" + }, + "block.sculk.step": { + "sounds": [ + { + "name": "wildbackport:block/sculk/step1", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step2", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step3", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step4", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step5", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step6", + "volume": 1 + } + ], + "subtitle": "subtitles.block.generic.footsteps" + }, + "block.sculk.place": { + "sounds": [ + { + "name": "wildbackport:block/sculk/place1", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/place2", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/place3", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/place4", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/place5", + "volume": 1 + } + ], + "subtitle": "subtitles.block.generic.place" + }, + "block.sculk.break": { + "sounds": [ + { + "name": "wildbackport:block/sculk/break1", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/break2", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/break3", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/break4", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/break5", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/break6", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/break7", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/break8", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/break9", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/break10", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/break11", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/break12", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/break13", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/break14", + "volume": 1 + } + ], + "subtitle": "subtitles.block.generic.break" + }, + "block.sculk.spread": { + "sounds": [ + { + "name": "wildbackport:block/sculk/spread1", + "volume": 1, + "pitch": 0.9 + }, + { + "name": "wildbackport:block/sculk/spread2", + "volume": 1, + "pitch": 0.9 + }, + { + "name": "wildbackport:block/sculk/spread3", + "volume": 1, + "pitch": 0.9 + }, + { + "name": "wildbackport:block/sculk/spread4", + "volume": 1, + "pitch": 0.9 + }, + { + "name": "wildbackport:block/sculk/spread5", + "volume": 1, + "pitch": 0.9 + } + ] + }, + "block.sculk.charge": { + "sounds": [ + { + "name": "wildbackport:block/sculk/charge1", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/charge2", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/charge3", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/charge4", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/charge5", + "volume": 1 + } + ] + }, + "block.sculk_catalyst.bloom": { + "sounds": [ + { + "attenuation_distance": 12, + "name": "enchant/soulspeed/soulspeed1", + "volume": 0.25 + }, + { + "attenuation_distance": 12, + "name": "enchant/soulspeed/soulspeed2", + "volume": 0.25 + }, + { + "attenuation_distance": 12, + "name": "enchant/soulspeed/soulspeed3", + "volume": 0.25 + }, + { + "attenuation_distance": 12, + "name": "enchant/soulspeed/soulspeed4", + "volume": 0.25 + }, + { + "attenuation_distance": 12, + "name": "enchant/soulspeed/soulspeed5", + "volume": 0.25 + }, + { + "attenuation_distance": 12, + "name": "enchant/soulspeed/soulspeed6", + "volume": 0.25 + }, + { + "attenuation_distance": 12, + "name": "enchant/soulspeed/soulspeed7", + "volume": 0.25 + }, + { + "attenuation_distance": 12, + "name": "enchant/soulspeed/soulspeed8", + "volume": 0.25 + }, + { + "attenuation_distance": 12, + "name": "enchant/soulspeed/soulspeed9", + "volume": 0.25 + }, + { + "attenuation_distance": 12, + "name": "enchant/soulspeed/soulspeed10", + "volume": 0.25 + }, + { + "attenuation_distance": 12, + "name": "enchant/soulspeed/soulspeed11", + "volume": 0.25 + }, + { + "attenuation_distance": 12, + "name": "enchant/soulspeed/soulspeed12", + "volume": 0.25 + }, + { + "attenuation_distance": 12, + "name": "enchant/soulspeed/soulspeed13", + "volume": 0.25 + } + ] + }, + "block.sculk_catalyst.fall": { + "sounds": [ + { + "name": "wildbackport:block/sculk_catalyst/step1", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk_catalyst/step2", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk_catalyst/step3", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk_catalyst/step4", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk_catalyst/step5", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk_catalyst/step6", + "volume": 1 + } + ] + }, + "block.sculk_catalyst.hit": { + "sounds": [ + { + "name": "wildbackport:block/sculk_catalyst/step1", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk_catalyst/step2", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk_catalyst/step3", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk_catalyst/step4", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk_catalyst/step5", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk_catalyst/step6", + "volume": 1 + } + ], + "subtitle": "subtitles.block.generic.hit" + }, + "block.sculk_catalyst.step": { + "sounds": [ + { + "name": "wildbackport:block/sculk_catalyst/step1", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk_catalyst/step2", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk_catalyst/step3", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk_catalyst/step4", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk_catalyst/step5", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk_catalyst/step6", + "volume": 1 + } + ], + "subtitle": "subtitles.block.generic.footsteps" + }, + "block.sculk_catalyst.place": { + "sounds": [ + { + "name": "wildbackport:block/sculk_catalyst/place1", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk_catalyst/place2", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk_catalyst/place3", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk_catalyst/place4", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk_catalyst/place5", + "volume": 1 + } + ], + "subtitle": "subtitles.block.generic.place" + }, + "block.sculk_catalyst.break": { + "sounds": [ + { + "name": "wildbackport:block/sculk_catalyst/break1", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk_catalyst/break2", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk_catalyst/break3", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk_catalyst/break4", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk_catalyst/break5", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk_catalyst/break6", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk_catalyst/break7", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk_catalyst/break8", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk_catalyst/break9", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk_catalyst/break10", + "volume": 1 + } + ], + "subtitle": "subtitles.block.generic.break" + }, + "block.sculk_vein.fall": { + "sounds": [ + { + "name": "wildbackport:block/sculk/step1", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step2", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step3", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step4", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step5", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step6", + "volume": 1 + } + ] + }, + "block.sculk_vein.hit": { + "sounds": [ + { + "name": "wildbackport:block/sculk/step1", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step2", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step3", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step4", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step5", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step6", + "volume": 1 + } + ], + "subtitle": "subtitles.block.generic.hit" + }, + "block.sculk_vein.step": { + "sounds": [ + { + "name": "wildbackport:block/sculk/step1", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step2", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step3", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step4", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step5", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step6", + "volume": 1 + } + ], + "subtitle": "subtitles.block.generic.footsteps" + }, + "block.sculk_vein.place": { + "sounds": [ + { + "name": "wildbackport:block/sculk_vein/break1", + "pitch": 1.1, + "volume": 0.8 + }, + { + "name": "wildbackport:block/sculk_vein/break2", + "pitch": 1.1, + "volume": 0.8 + }, + { + "name": "wildbackport:block/sculk_vein/break3", + "pitch": 1.1, + "volume": 0.8 + }, + { + "name": "wildbackport:block/sculk_vein/break4", + "pitch": 1.1, + "volume": 0.8 + }, + { + "name": "wildbackport:block/sculk_vein/break5", + "pitch": 1.1, + "volume": 0.8 + } + ], + "subtitle": "subtitles.block.generic.place" + }, + "block.sculk_vein.break": { + "sounds": [ + { + "name": "wildbackport:block/sculk_vein/break1", + "pitch": 1.1, + "volume": 0.8 + }, + { + "name": "wildbackport:block/sculk_vein/break2", + "pitch": 1.1, + "volume": 0.8 + }, + { + "name": "wildbackport:block/sculk_vein/break3", + "pitch": 1.1, + "volume": 0.8 + }, + { + "name": "wildbackport:block/sculk_vein/break4", + "pitch": 1.1, + "volume": 0.8 + }, + { + "name": "wildbackport:block/sculk_vein/break5", + "pitch": 1.1, + "volume": 0.8 + } + ], + "subtitle": "subtitles.block.generic.break" + }, + + "block.sculk_shrieker.fall": { + "sounds": [ + { + "name": "wildbackport:block/sculk/step1", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step2", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step3", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step4", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step5", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step6", + "volume": 1 + } + ] + }, + "block.sculk_shrieker.hit": { + "sounds": [ + { + "name": "wildbackport:block/sculk/step1", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step2", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step3", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step4", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step5", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step6", + "volume": 1 + } + ], + "subtitle": "subtitles.block.generic.hit" + }, + "block.sculk_shrieker.step": { + "sounds": [ + { + "name": "wildbackport:block/sculk/step1", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step2", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step3", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step4", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step5", + "volume": 1 + }, + { + "name": "wildbackport:block/sculk/step6", + "volume": 1 + } + ], + "subtitle": "subtitles.block.generic.footsteps" + }, + "block.sculk_shrieker.place": { + "sounds": [ + { + "name": "wildbackport:block/sculk_shrieker/place1", + "volume": 0.9 + }, + { + "name": "wildbackport:block/sculk_shrieker/place2", + "volume": 0.9 + }, + { + "name": "wildbackport:block/sculk_shrieker/place3", + "volume": 0.9 + }, + { + "name": "wildbackport:block/sculk_shrieker/place4", + "volume": 0.9 + }, + { + "name": "wildbackport:block/sculk_shrieker/place5", + "volume": 0.9 + } + ], + "subtitle": "subtitles.block.generic.place" + }, + "block.sculk_shrieker.break": { + "sounds": [ + { + "name": "wildbackport:block/sculk_shrieker/break1", + "volume": 0.9 + }, + { + "name": "wildbackport:block/sculk_shrieker/break2", + "volume": 0.9 + }, + { + "name": "wildbackport:block/sculk_shrieker/break3", + "volume": 0.9 + }, + { + "name": "wildbackport:block/sculk_shrieker/break4", + "volume": 0.9 + }, + { + "name": "wildbackport:block/sculk_shrieker/break5", + "volume": 0.9 + }, + { + "name": "wildbackport:block/sculk_shrieker/break6", + "volume": 0.9 + } + ], + "subtitle": "subtitles.block.generic.break" + }, + "block.sculk_shrieker.shriek": { + "sounds": [ + { + "name": "wildbackport:block/sculk_shrieker/shriek1", + "volume": 0.85 + }, + { + "name": "wildbackport:block/sculk_shrieker/shriek2", + "volume": 0.85 + }, + { + "name": "wildbackport:block/sculk_shrieker/shriek3", + "volume": 0.85 + }, + { + "name": "wildbackport:block/sculk_shrieker/shriek4", + "volume": 0.85 + }, + { + "name": "wildbackport:block/sculk_shrieker/shriek5", + "volume": 0.85 + } + ] + }, + "block.froglight.break": { + "sounds": [ + "wildbackport:block/froglight/break1", + "wildbackport:block/froglight/break2", + "wildbackport:block/froglight/break3", + "wildbackport:block/froglight/break4" + ], + "subtitle": "subtitles.block.generic.break" + }, + "block.froglight.fall": { + "sounds": [ + "wildbackport:block/froglight/step1", + "wildbackport:block/froglight/step2", + "wildbackport:block/froglight/step3", + "wildbackport:block/froglight/step4", + "wildbackport:block/froglight/step5", + "wildbackport:block/froglight/step6" + ] + }, + "block.froglight.hit": { + "sounds": [ + { + "name": "wildbackport:block/froglight/step1", + "pitch": 1.3, + "volume": 0.83 + }, + { + "name": "wildbackport:block/froglight/step2", + "pitch": 1.3, + "volume": 0.83 + }, + { + "name": "wildbackport:block/froglight/step3", + "pitch": 1.3, + "volume": 0.83 + }, + { + "name": "wildbackport:block/froglight/step4", + "pitch": 1.3, + "volume": 0.83 + }, + { + "name": "wildbackport:block/froglight/step5", + "pitch": 1.3, + "volume": 0.83 + }, + { + "name": "wildbackport:block/froglight/step6", + "pitch": 1.3, + "volume": 0.83 + } + ], + "subtitle": "subtitles.block.generic.hit" + }, + "block.froglight.place": { + "sounds": [ + "wildbackport:block/froglight/break1", + "wildbackport:block/froglight/break2", + "wildbackport:block/froglight/break3", + "wildbackport:block/froglight/break4" + ], + "subtitle": "subtitles.block.generic.place" + }, + "block.froglight.step": { + "sounds": [ + "wildbackport:block/froglight/step1", + "wildbackport:block/froglight/step2", + "wildbackport:block/froglight/step3", + "wildbackport:block/froglight/step4", + "wildbackport:block/froglight/step5", + "wildbackport:block/froglight/step6" + ], + "subtitle": "subtitles.block.generic.footsteps" + }, + "block.frogspawn.break": { + "sounds": [ + { + "name": "wildbackport:block/frogspawn/break1", + "pitch": 1.2, + "volume": 0.1 + }, + { + "name": "wildbackport:block/frogspawn/break2", + "pitch": 1.2, + "volume": 0.1 + }, + { + "name": "wildbackport:block/frogspawn/break3", + "pitch": 1.2, + "volume": 0.1 + }, + { + "name": "wildbackport:block/frogspawn/break4", + "pitch": 1.2, + "volume": 0.1 + } + ], + "subtitle": "subtitles.block.generic.break" + }, + "block.frogspawn.fall": { + "sounds": [ + { + "name": "wildbackport:block/frogspawn/step1", + "pitch": 1.3, + "volume": 0.3 + }, + { + "name": "wildbackport:block/frogspawn/step2", + "pitch": 1.3, + "volume": 0.3 + }, + { + "name": "wildbackport:block/frogspawn/step3", + "pitch": 1.3, + "volume": 0.3 + }, + { + "name": "wildbackport:block/frogspawn/step4", + "pitch": 1.3, + "volume": 0.3 + }, + { + "name": "wildbackport:block/frogspawn/step5", + "pitch": 1.3, + "volume": 0.3 + }, + { + "name": "wildbackport:block/frogspawn/step6", + "pitch": 1.3, + "volume": 0.3 + } + ] + }, + "block.frogspawn.hatch": { + "sounds": [ + { + "name": "wildbackport:block/frogspawn/hatch1", + "pitch": 1.2, + "volume": 0.6 + }, + { + "name": "wildbackport:block/frogspawn/hatch2", + "pitch": 1.2, + "volume": 0.6 + }, + { + "name": "wildbackport:block/frogspawn/hatch3", + "pitch": 1.2, + "volume": 0.6 + }, + { + "name": "wildbackport:block/frogspawn/hatch4", + "pitch": 1.2, + "volume": 0.6 + } + ], + "subtitle": "subtitles.block.frogspawn.hatch" + }, + "block.frogspawn.hit": { + "sounds": [ + { + "name": "wildbackport:block/frogspawn/step1", + "pitch": 1.3, + "volume": 0.3 + }, + { + "name": "wildbackport:block/frogspawn/step2", + "pitch": 1.3, + "volume": 0.3 + }, + { + "name": "wildbackport:block/frogspawn/step3", + "pitch": 1.3, + "volume": 0.3 + }, + { + "name": "wildbackport:block/frogspawn/step4", + "pitch": 1.3, + "volume": 0.3 + }, + { + "name": "wildbackport:block/frogspawn/step5", + "pitch": 1.3, + "volume": 0.3 + }, + { + "name": "wildbackport:block/frogspawn/step6", + "pitch": 1.3, + "volume": 0.3 + } + ], + "subtitle": "subtitles.block.generic.hit" + }, + "block.frogspawn.place": { + "sounds": [ + { + "name": "wildbackport:block/frogspawn/break1", + "pitch": 1.5, + "volume": 0.2 + }, + { + "name": "wildbackport:block/frogspawn/break2", + "pitch": 1.5, + "volume": 0.2 + }, + { + "name": "wildbackport:block/frogspawn/break3", + "pitch": 1.5, + "volume": 0.2 + }, + { + "name": "wildbackport:block/frogspawn/break4", + "pitch": 1.5, + "volume": 0.2 + } + ], + "subtitle": "subtitles.block.generic.place" + }, + "block.frogspawn.step": { + "sounds": [ + { + "name": "wildbackport:block/frogspawn/step1", + "volume": 0.3 + }, + { + "name": "wildbackport:block/frogspawn/step2", + "volume": 0.3 + }, + { + "name": "wildbackport:block/frogspawn/step3", + "volume": 0.3 + }, + { + "name": "wildbackport:block/frogspawn/step4", + "volume": 0.3 + }, + { + "name": "wildbackport:block/frogspawn/step5", + "volume": 0.3 + }, + { + "name": "wildbackport:block/frogspawn/step6", + "volume": 0.3 + } + ], + "subtitle": "subtitles.block.generic.footsteps" + }, + "block.mangrove_roots.break": { + "sounds": [ + { + "name": "wildbackport:block/mangrove_roots/break1", + "pitch": 1.2, + "volume": 0.25 + }, + { + "name": "wildbackport:block/mangrove_roots/break2", + "pitch": 1.2, + "volume": 0.25 + }, + { + "name": "wildbackport:block/mangrove_roots/break3", + "pitch": 1.2, + "volume": 0.25 + }, + { + "name": "wildbackport:block/mangrove_roots/break4", + "pitch": 1.2, + "volume": 0.25 + }, + { + "name": "wildbackport:block/mangrove_roots/break5", + "pitch": 1.2, + "volume": 0.25 + }, + { + "name": "wildbackport:block/mangrove_roots/break6", + "pitch": 1.2, + "volume": 0.25 + } + ], + "subtitle": "subtitles.block.generic.break" + }, + "block.mangrove_roots.fall": { + "sounds": [ + { + "name": "wildbackport:block/mangrove_roots/step1", + "volume": 0.25 + }, + { + "name": "wildbackport:block/mangrove_roots/step2", + "volume": 0.25 + }, + { + "name": "wildbackport:block/mangrove_roots/step3", + "volume": 0.25 + }, + { + "name": "wildbackport:block/mangrove_roots/step4", + "volume": 0.25 + }, + { + "name": "wildbackport:block/mangrove_roots/step5", + "volume": 0.25 + }, + { + "name": "wildbackport:block/mangrove_roots/step6", + "volume": 0.25 + } + ] + }, + "block.mangrove_roots.hit": { + "sounds": [ + { + "name": "wildbackport:block/mangrove_roots/step1", + "volume": 0.25 + }, + { + "name": "wildbackport:block/mangrove_roots/step2", + "volume": 0.25 + }, + { + "name": "wildbackport:block/mangrove_roots/step3", + "volume": 0.25 + }, + { + "name": "wildbackport:block/mangrove_roots/step4", + "volume": 0.25 + }, + { + "name": "wildbackport:block/mangrove_roots/step5", + "volume": 0.25 + }, + { + "name": "wildbackport:block/mangrove_roots/step6", + "volume": 0.25 + } + ], + "subtitle": "subtitles.block.generic.hit" + }, + "block.mangrove_roots.place": { + "sounds": [ + { + "name": "wildbackport:block/mangrove_roots/break1", + "pitch": 1.2, + "volume": 0.25 + }, + { + "name": "wildbackport:block/mangrove_roots/break2", + "pitch": 1.2, + "volume": 0.25 + }, + { + "name": "wildbackport:block/mangrove_roots/break3", + "pitch": 1.2, + "volume": 0.25 + }, + { + "name": "wildbackport:block/mangrove_roots/break4", + "pitch": 1.2, + "volume": 0.25 + }, + { + "name": "wildbackport:block/mangrove_roots/break5", + "pitch": 1.2, + "volume": 0.25 + }, + { + "name": "wildbackport:block/mangrove_roots/break6", + "pitch": 1.2, + "volume": 0.25 + } + ], + "subtitle": "subtitles.block.generic.place" + }, + "block.mangrove_roots.step": { + "sounds": [ + { + "name": "wildbackport:block/mangrove_roots/step1", + "volume": 0.25 + }, + { + "name": "wildbackport:block/mangrove_roots/step2", + "volume": 0.25 + }, + { + "name": "wildbackport:block/mangrove_roots/step3", + "volume": 0.25 + }, + { + "name": "wildbackport:block/mangrove_roots/step4", + "volume": 0.25 + }, + { + "name": "wildbackport:block/mangrove_roots/step5", + "volume": 0.25 + }, + { + "name": "wildbackport:block/mangrove_roots/step6", + "volume": 0.25 + } + ], + "subtitle": "subtitles.block.generic.footsteps" + }, + "block.mud.break": { + "sounds": [ + { + "name": "wildbackport:block/mud/break1", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud/break2", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud/break3", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud/break4", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud/break5", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud/break6", + "volume": 0.5 + } + ], + "subtitle": "subtitles.block.generic.break" + }, + "block.mud.fall": { + "sounds": [ + { + "name": "wildbackport:block/mud/step1", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud/step2", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud/step3", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud/step4", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud/step5", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud/step6", + "volume": 0.5 + } + ] + }, + "block.mud.hit": { + "sounds": [ + { + "name": "wildbackport:block/mud/step1", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud/step2", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud/step3", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud/step4", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud/step5", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud/step6", + "volume": 0.5 + } + ], + "subtitle": "subtitles.block.generic.hit" + }, + "block.mud.place": { + "sounds": [ + { + "name": "wildbackport:block/mud/break1", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud/break2", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud/break3", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud/break4", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud/break5", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud/break6", + "volume": 0.5 + } + ], + "subtitle": "subtitles.block.generic.place" + }, + "block.mud.step": { + "sounds": [ + { + "name": "wildbackport:block/mud/step1", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud/step2", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud/step3", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud/step4", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud/step5", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud/step6", + "volume": 0.5 + } + ], + "subtitle": "subtitles.block.generic.footsteps" + }, + "block.mud_bricks.break": { + "sounds": [ + { + "name": "wildbackport:block/mud_bricks/break1", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud_bricks/break2", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud_bricks/break3", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud_bricks/break4", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud_bricks/break5", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud_bricks/break6", + "volume": 0.5 + } + ], + "subtitle": "subtitles.block.generic.break" + }, + "block.mud_bricks.fall": { + "sounds": [ + { + "name": "wildbackport:block/mud_bricks/step1", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud_bricks/step2", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud_bricks/step3", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud_bricks/step4", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud_bricks/step5", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud_bricks/step6", + "volume": 0.5 + } + ] + }, + "block.mud_bricks.hit": { + "sounds": [ + { + "name": "wildbackport:block/mud_bricks/step1", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud_bricks/step2", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud_bricks/step3", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud_bricks/step4", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud_bricks/step5", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud_bricks/step6", + "volume": 0.5 + } + ], + "subtitle": "subtitles.block.generic.hit" + }, + "block.mud_bricks.place": { + "sounds": [ + { + "name": "wildbackport:block/mud_bricks/break1", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud_bricks/break2", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud_bricks/break3", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud_bricks/break4", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud_bricks/break5", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud_bricks/break6", + "volume": 0.5 + } + ], + "subtitle": "subtitles.block.generic.place" + }, + "block.mud_bricks.step": { + "sounds": [ + { + "name": "wildbackport:block/mud_bricks/step1", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud_bricks/step2", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud_bricks/step3", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud_bricks/step4", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud_bricks/step5", + "volume": 0.5 + }, + { + "name": "wildbackport:block/mud_bricks/step6", + "volume": 0.5 + } + ], + "subtitle": "subtitles.block.generic.footsteps" + }, + "block.muddy_mangrove_roots.break": { + "sounds": [ + { + "name": "wildbackport:block/muddy_mangrove_roots/break1", + "volume": 0.25 + }, + { + "name": "wildbackport:block/muddy_mangrove_roots/break2", + "volume": 0.25 + }, + { + "name": "wildbackport:block/muddy_mangrove_roots/break3", + "volume": 0.25 + }, + { + "name": "wildbackport:block/muddy_mangrove_roots/break4", + "volume": 0.25 + }, + { + "name": "wildbackport:block/muddy_mangrove_roots/break5", + "volume": 0.25 + }, + { + "name": "wildbackport:block/muddy_mangrove_roots/break6", + "volume": 0.25 + } + ], + "subtitle": "subtitles.block.generic.break" + }, + "block.muddy_mangrove_roots.fall": { + "sounds": [ + { + "name": "wildbackport:block/muddy_mangrove_roots/step1", + "volume": 0.25 + }, + { + "name": "wildbackport:block/muddy_mangrove_roots/step2", + "volume": 0.25 + }, + { + "name": "wildbackport:block/muddy_mangrove_roots/step3", + "volume": 0.25 + }, + { + "name": "wildbackport:block/muddy_mangrove_roots/step4", + "volume": 0.25 + }, + { + "name": "wildbackport:block/muddy_mangrove_roots/step5", + "volume": 0.25 + }, + { + "name": "wildbackport:block/muddy_mangrove_roots/step6", + "volume": 0.25 + } + ] + }, + "block.muddy_mangrove_roots.hit": { + "sounds": [ + { + "name": "wildbackport:block/muddy_mangrove_roots/step1", + "volume": 0.25 + }, + { + "name": "wildbackport:block/muddy_mangrove_roots/step2", + "volume": 0.25 + }, + { + "name": "wildbackport:block/muddy_mangrove_roots/step3", + "volume": 0.25 + }, + { + "name": "wildbackport:block/muddy_mangrove_roots/step4", + "volume": 0.25 + }, + { + "name": "wildbackport:block/muddy_mangrove_roots/step5", + "volume": 0.25 + }, + { + "name": "wildbackport:block/muddy_mangrove_roots/step6", + "volume": 0.25 + } + ], + "subtitle": "subtitles.block.generic.hit" + }, + "block.muddy_mangrove_roots.place": { + "sounds": [ + { + "name": "wildbackport:block/muddy_mangrove_roots/break1", + "volume": 0.25 + }, + { + "name": "wildbackport:block/muddy_mangrove_roots/break2", + "volume": 0.25 + }, + { + "name": "wildbackport:block/muddy_mangrove_roots/break3", + "volume": 0.25 + }, + { + "name": "wildbackport:block/muddy_mangrove_roots/break4", + "volume": 0.25 + }, + { + "name": "wildbackport:block/muddy_mangrove_roots/break5", + "volume": 0.25 + }, + { + "name": "wildbackport:block/muddy_mangrove_roots/break6", + "volume": 0.25 + } + ], + "subtitle": "subtitles.block.generic.place" + }, + "block.muddy_mangrove_roots.step": { + "sounds": [ + { + "name": "wildbackport:block/muddy_mangrove_roots/step1", + "volume": 0.25 + }, + { + "name": "wildbackport:block/muddy_mangrove_roots/step2", + "volume": 0.25 + }, + { + "name": "wildbackport:block/muddy_mangrove_roots/step3", + "volume": 0.25 + }, + { + "name": "wildbackport:block/muddy_mangrove_roots/step4", + "volume": 0.25 + }, + { + "name": "wildbackport:block/muddy_mangrove_roots/step5", + "volume": 0.25 + }, + { + "name": "wildbackport:block/muddy_mangrove_roots/step6", + "volume": 0.25 + } + ], + "subtitle": "subtitles.block.generic.footsteps" + }, + "block.packed_mud.break": { + "sounds": [ + { + "name": "wildbackport:block/packed_mud/break1", + "volume": 0.3 + }, + { + "name": "wildbackport:block/packed_mud/break2", + "volume": 0.3 + }, + { + "name": "wildbackport:block/packed_mud/break3", + "volume": 0.3 + }, + { + "name": "wildbackport:block/packed_mud/break4", + "volume": 0.3 + }, + { + "name": "wildbackport:block/packed_mud/break5", + "volume": 0.3 + }, + { + "name": "wildbackport:block/packed_mud/break6", + "volume": 0.3 + } + ], + "subtitle": "subtitles.block.generic.break" + }, + "block.packed_mud.fall": { + "sounds": [ + { + "name": "wildbackport:block/packed_mud/step1", + "volume": 0.3 + }, + { + "name": "wildbackport:block/packed_mud/step2", + "volume": 0.3 + }, + { + "name": "wildbackport:block/packed_mud/step3", + "volume": 0.3 + }, + { + "name": "wildbackport:block/packed_mud/step4", + "volume": 0.3 + }, + { + "name": "wildbackport:block/packed_mud/step5", + "volume": 0.3 + }, + { + "name": "wildbackport:block/packed_mud/step6", + "volume": 0.3 + } + ] + }, + "block.packed_mud.hit": { + "sounds": [ + { + "name": "wildbackport:block/packed_mud/step1", + "volume": 0.3 + }, + { + "name": "wildbackport:block/packed_mud/step2", + "volume": 0.3 + }, + { + "name": "wildbackport:block/packed_mud/step3", + "volume": 0.3 + }, + { + "name": "wildbackport:block/packed_mud/step4", + "volume": 0.3 + }, + { + "name": "wildbackport:block/packed_mud/step5", + "volume": 0.3 + }, + { + "name": "wildbackport:block/packed_mud/step6", + "volume": 0.3 + } + ], + "subtitle": "subtitles.block.generic.hit" + }, + "block.packed_mud.place": { + "sounds": [ + { + "name": "wildbackport:block/packed_mud/break1", + "volume": 0.3 + }, + { + "name": "wildbackport:block/packed_mud/break2", + "volume": 0.3 + }, + { + "name": "wildbackport:block/packed_mud/break3", + "volume": 0.3 + }, + { + "name": "wildbackport:block/packed_mud/break4", + "volume": 0.3 + }, + { + "name": "wildbackport:block/packed_mud/break5", + "volume": 0.3 + }, + { + "name": "wildbackport:block/packed_mud/break6", + "volume": 0.3 + } + ], + "subtitle": "subtitles.block.generic.place" + }, + "block.packed_mud.step": { + "sounds": [ + { + "name": "wildbackport:block/packed_mud/step1", + "pitch": 0.95, + "volume": 0.3 + }, + { + "name": "wildbackport:block/packed_mud/step2", + "pitch": 0.95, + "volume": 0.3 + }, + { + "name": "wildbackport:block/packed_mud/step3", + "pitch": 0.95, + "volume": 0.3 + }, + { + "name": "wildbackport:block/packed_mud/step4", + "pitch": 0.95, + "volume": 0.3 + }, + { + "name": "wildbackport:block/packed_mud/step5", + "pitch": 0.95, + "volume": 0.3 + }, + { + "name": "wildbackport:block/packed_mud/step6", + "pitch": 0.95, + "volume": 0.3 + } + ], + "subtitle": "subtitles.block.generic.footsteps" + }, + "item.goat_horn.sound.0": { + "sounds": [ + "wildbackport:item/goat_horn/call0" + ], + "subtitle": "subtitles.item.goat_horn.play" + }, + "item.goat_horn.sound.1": { + "sounds": [ + "wildbackport:item/goat_horn/call1" + ], + "subtitle": "subtitles.item.goat_horn.play" + }, + "item.goat_horn.sound.2": { + "sounds": [ + "wildbackport:item/goat_horn/call2" + ], + "subtitle": "subtitles.item.goat_horn.play" + }, + "item.goat_horn.sound.3": { + "sounds": [ + "wildbackport:item/goat_horn/call3" + ], + "subtitle": "subtitles.item.goat_horn.play" + }, + "item.goat_horn.sound.4": { + "sounds": [ + "wildbackport:item/goat_horn/call4" + ], + "subtitle": "subtitles.item.goat_horn.play" + }, + "item.goat_horn.sound.5": { + "sounds": [ + "wildbackport:item/goat_horn/call5" + ], + "subtitle": "subtitles.item.goat_horn.play" + }, + "item.goat_horn.sound.6": { + "sounds": [ + "wildbackport:item/goat_horn/call6" + ], + "subtitle": "subtitles.item.goat_horn.play" + }, + "item.goat_horn.sound.7": { + "sounds": [ + "wildbackport:item/goat_horn/call7" + ], + "subtitle": "subtitles.item.goat_horn.play" + }, + "entity.warden.sonic_boom": { + "sounds": [ + "wildbackport:mob/warden/sonic_boom1", + "wildbackport:mob/warden/sonic_boom2", + "wildbackport:mob/warden/sonic_boom3", + "wildbackport:mob/warden/sonic_boom4" + ] + }, + "entity.warden.sonic_charge": { + "sounds": [ + { + "name": "wildbackport:mob/warden/sonic_charge1", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/sonic_charge2", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/sonic_charge3", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/sonic_charge4", + "volume": 1 + } + ] + }, + "entity.warden.nearby_closest": { + "sounds": [ + { + "name": "wildbackport:mob/warden/nearby_closest_1", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/nearby_closest_2", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/nearby_closest_3", + "volume": 1 + } + ], + "subtitle": "subtitles.entity.warden.nearby_closest" + }, + "entity.warden.nearby_closer": { + "sounds": [ + { + "name": "wildbackport:mob/warden/nearby_closer_1", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/nearby_closer_2", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/nearby_closer_3", + "volume": 1 + } + ], + "subtitle": "subtitles.entity.warden.nearby_closer" + }, + "entity.warden.nearby_close": { + "sounds": [ + { + "name": "wildbackport:mob/warden/nearby_close_1", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/nearby_close_2", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/nearby_close_3", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/nearby_close_4", + "volume": 1 + } + ], + "subtitle": "subtitles.entity.warden.nearby_close" + }, + "entity.warden.roar": { + "sounds": [ + { + "name": "wildbackport:mob/warden/roar_1", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/roar_2", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/roar_3", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/roar_4", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/roar_5", + "volume": 1 + } + ], + "subtitle": "subtitles.entity.warden.roar" + }, + "entity.warden.sniff": { + "sounds": [ + { + "name": "wildbackport:mob/warden/sniff_1", + "volume": 0.75 + }, + { + "name": "wildbackport:mob/warden/sniff_2", + "volume": 0.75 + }, + { + "name": "wildbackport:mob/warden/sniff_3", + "volume": 0.75 + }, + { + "name": "wildbackport:mob/warden/sniff_4", + "volume": 0.75 + } + ], + "subtitle": "subtitles.entity.warden.sniff" + }, + "entity.warden.ambient": { + "sounds": [ + { + "name": "wildbackport:mob/warden/idle_1", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/idle_2", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/idle_3", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/idle_4", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/idle_5", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/idle_6", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/idle_7", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/idle_8", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/idle_9", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/idle_10", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/idle_11", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/idle_12", + "volume": 1 + } + ], + "subtitle": "subtitles.entity.warden.ambient" + }, + "entity.warden.emerge": { + "sounds": [ + { + "name": "wildbackport:mob/warden/emerge", + "volume": 1 + } + ], + "subtitle": "subtitles.entity.warden.emerge" + }, + "entity.warden.dig": { + "sounds": [ + { + "name": "wildbackport:mob/warden/dig", + "volume": 1 + } + ], + "subtitle": "subtitles.entity.warden.dig" + }, + "entity.warden.tendril_clicks": { + "sounds": [ + { + "name": "wildbackport:mob/warden/tendril_clicks_1", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/tendril_clicks_2", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/tendril_clicks_3", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/tendril_clicks_4", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/tendril_clicks_5", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/tendril_clicks_6", + "volume": 1 + } + ], + "subtitle": "subtitles.entity.warden.tendril_clicks" + }, + "entity.warden.heartbeat": { + "sounds": [ + { + "name": "wildbackport:mob/warden/heartbeat_1", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/heartbeat_2", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/heartbeat_3", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/heartbeat_4", + "volume": 1 + } + ], + "subtitle": "subtitles.entity.warden.heartbeat" + }, + "entity.warden.listening": { + "sounds": [ + { + "name": "wildbackport:mob/warden/listening_1", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/listening_2", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/listening_3", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/listening_4", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/listening_5", + "volume": 1 + } + ], + "subtitle": "subtitles.entity.warden.listening" + }, + "entity.warden.listening_angry": { + "sounds": [ + { + "name": "wildbackport:mob/warden/listening_angry_1", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/listening_angry_2", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/listening_angry_3", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/listening_angry_4", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/listening_angry_5", + "volume": 1 + } + ], + "subtitle": "subtitles.entity.warden.listening_angry" + }, + "entity.warden.step": { + "sounds": [ + { + "name": "wildbackport:mob/warden/step_1", + "volume": 0.3 + }, + { + "name": "wildbackport:mob/warden/step_2", + "volume": 0.3 + }, + { + "name": "wildbackport:mob/warden/step_3", + "volume": 0.3 + }, + { + "name": "wildbackport:mob/warden/step_4", + "volume": 0.3 + } + ], + "subtitle": "subtitles.entity.warden.step" + }, + "entity.warden.death": { + "sounds": [ + { + "name": "wildbackport:mob/warden/death_1", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/death_2", + "volume": 1 + } + ], + "subtitle": "subtitles.entity.warden.death" + }, + "entity.warden.attack_impact": { + "sounds": [ + { + "name": "wildbackport:mob/warden/attack_impact_1", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/attack_impact_2", + "volume": 1 + } + ], + "subtitle": "subtitles.entity.warden.attack_impact" + }, + "entity.warden.hurt": { + "sounds": [ + { + "name": "wildbackport:mob/warden/hurt_1", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/hurt_2", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/hurt_3", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/hurt_4", + "volume": 1 + } + ], + "subtitle": "subtitles.entity.warden.hurt" + }, + "entity.warden.agitated": { + "sounds": [ + { + "name": "wildbackport:mob/warden/agitated_1", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/agitated_2", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/agitated_3", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/agitated_4", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/agitated_5", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/agitated_6", + "volume": 1 + } + ], + "subtitle": "subtitles.entity.warden.agitated" + }, + "entity.warden.angry": { + "sounds": [ + { + "name": "wildbackport:mob/warden/angry_1", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/angry_2", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/angry_3", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/angry_4", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/angry_5", + "volume": 1 + }, + { + "name": "wildbackport:mob/warden/angry_6", + "volume": 1 + } + ], + "subtitle": "subtitles.entity.warden.angry" + }, + "entity.frog.ambient": { + "sounds": [ + { + "name": "wildbackport:mob/frog/idle1", + "pitch": 0.95, + "volume": 0.8 + }, + { + "name": "wildbackport:mob/frog/idle2", + "pitch": 0.9 + }, + { + "name": "wildbackport:mob/frog/idle3", + "pitch": 0.9, + "volume": 0.9 + }, + { + "name": "wildbackport:mob/frog/idle4", + "pitch": 0.95, + "volume": 0.8 + }, + { + "name": "wildbackport:mob/frog/idle5", + "pitch": 0.9, + "volume": 0.85 + }, + { + "name": "wildbackport:mob/frog/idle6", + "pitch": 0.9, + "volume": 0.9 + }, + { + "name": "wildbackport:mob/frog/idle7", + "pitch": 0.9, + "volume": 0.7 + }, + { + "name": "wildbackport:mob/frog/idle8", + "pitch": 0.9, + "volume": 0.3 + } + ], + "subtitle": "subtitles.entity.frog.ambient" + }, + "entity.frog.death": { + "sounds": [ + "wildbackport:mob/frog/death1", + "wildbackport:mob/frog/death2", + "wildbackport:mob/frog/death3" + ], + "subtitle": "subtitles.entity.frog.death" + }, + "entity.frog.eat": { + "sounds": [ + { + "name": "wildbackport:mob/frog/eat1", + "volume": 0.6 + }, + { + "name": "wildbackport:mob/frog/eat1", + "pitch": 0.9, + "volume": 0.6 + }, + { + "name": "wildbackport:mob/frog/eat2", + "volume": 0.6 + }, + { + "name": "wildbackport:mob/frog/eat2", + "pitch": 0.9, + "volume": 0.6 + }, + { + "name": "wildbackport:mob/frog/eat3", + "volume": 0.6 + }, + { + "name": "wildbackport:mob/frog/eat3", + "pitch": 0.9, + "volume": 0.6 + }, + { + "name": "wildbackport:mob/frog/eat4", + "volume": 0.6 + }, + { + "name": "wildbackport:mob/frog/eat4", + "pitch": 0.9, + "volume": 0.6 + } + ], + "subtitle": "subtitles.entity.frog.eat" + }, + "entity.frog.hurt": { + "sounds": [ + "wildbackport:mob/frog/hurt1", + "wildbackport:mob/frog/hurt2", + "wildbackport:mob/frog/hurt3", + "wildbackport:mob/frog/hurt4", + "wildbackport:mob/frog/hurt5" + ], + "subtitle": "subtitles.entity.frog.hurt" + }, + "entity.frog.lay_spawn": { + "sounds": [ + { + "name": "wildbackport:mob/frog/lay_spawn1", + "volume": 0.25 + }, + { + "name": "wildbackport:mob/frog/lay_spawn2", + "volume": 0.25 + } + ], + "subtitle": "subtitles.entity.frog.lay_spawn" + }, + "entity.frog.long_jump": { + "sounds": [ + { + "name": "wildbackport:mob/frog/long_jump1", + "volume": 0.12 + }, + { + "name": "wildbackport:mob/frog/long_jump1", + "pitch": 0.8, + "volume": 0.12 + }, + { + "name": "wildbackport:mob/frog/long_jump2", + "volume": 0.12 + }, + { + "name": "wildbackport:mob/frog/long_jump2", + "pitch": 0.8, + "volume": 0.12 + }, + { + "name": "wildbackport:mob/frog/long_jump3", + "volume": 0.12 + }, + { + "name": "wildbackport:mob/frog/long_jump3", + "pitch": 0.8, + "volume": 0.12 + }, + { + "name": "wildbackport:mob/frog/long_jump4", + "volume": 0.12 + }, + { + "name": "wildbackport:mob/frog/long_jump4", + "pitch": 0.8, + "volume": 0.12 + } + ], + "subtitle": "subtitles.entity.frog.long_jump" + }, + "entity.frog.step": { + "sounds": [ + "wildbackport:mob/frog/step1", + "wildbackport:mob/frog/step2", + "wildbackport:mob/frog/step3", + "wildbackport:mob/frog/step4" + ] + }, + "item.bucket.empty_tadpole": { + "sounds": [ + { + "name": "item/bucket/empty_fish1", + "pitch": 1.5, + "volume": 0.5 + }, + { + "name": "item/bucket/empty_fish2", + "pitch": 1.5, + "volume": 0.5 + }, + { + "name": "item/bucket/empty_fish3", + "pitch": 1.5, + "volume": 0.5 + } + ], + "subtitle": "subtitles.item.bucket.empty" + }, + "entity.frog.tongue": { + "sounds": [ + { + "name": "wildbackport:mob/frog/tounge1", + "volume": 0.5 + }, + { + "name": "wildbackport:mob/frog/tounge2", + "volume": 0.5 + }, + { + "name": "wildbackport:mob/frog/tounge3", + "volume": 0.5 + }, + { + "name": "wildbackport:mob/frog/tounge4", + "volume": 0.5 + } + ] + }, + "item.bucket.fill_tadpole": { + "sounds": [ + { + "name": "item/bucket/fill_fish1", + "pitch": 1.5, + "volume": 0.5 + }, + { + "name": "item/bucket/fill_fish2", + "pitch": 1.5, + "volume": 0.5 + }, + { + "name": "item/bucket/fill_fish3", + "pitch": 1.5, + "volume": 0.5 + } + ], + "subtitle": "subtitles.item.bucket.fill_tadpole" + }, + "entity.tadpole.death": { + "sounds": [ + "wildbackport:mob/tadpole/death1", + "wildbackport:mob/tadpole/death2" + ], + "subtitle": "subtitles.entity.tadpole.death" + }, + "entity.tadpole.flop": { + "sounds": [ + { + "name": "entity.tropical_fish.flop", + "type": "event" + } + ], + "subtitle": "subtitles.entity.tadpole.flop" + }, + "entity.tadpole.grow_up": { + "sounds": [ + { + "name": "wildbackport:mob/frog/idle1", + "pitch": 1.2, + "volume": 0.75 + }, + { + "name": "wildbackport:mob/frog/idle2", + "pitch": 1.2, + "volume": 0.75 + }, + { + "name": "wildbackport:mob/frog/idle3", + "pitch": 1.2, + "volume": 0.75 + }, + { + "name": "wildbackport:mob/frog/idle4", + "pitch": 1.2, + "volume": 0.75 + }, + { + "name": "wildbackport:mob/frog/idle5", + "pitch": 1.2, + "volume": 0.75 + }, + { + "name": "wildbackport:mob/frog/idle6", + "pitch": 1.2, + "volume": 0.75 + }, + { + "name": "wildbackport:mob/frog/idle7", + "pitch": 1.2, + "volume": 0.75 + }, + { + "name": "wildbackport:mob/frog/idle8", + "pitch": 1.2, + "volume": 0.75 + } + ], + "subtitle": "subtitles.entity.tadpole.grow_up" + }, + "entity.tadpole.hurt": { + "sounds": [ + "wildbackport:mob/tadpole/hurt1", + "wildbackport:mob/tadpole/hurt2", + "wildbackport:mob/tadpole/hurt3", + "wildbackport:mob/tadpole/hurt4" + ], + "subtitle": "subtitles.entity.tadpole.hurt" + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/froglight/break1.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/froglight/break1.ogg new file mode 100644 index 0000000..6c64974 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/froglight/break1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/froglight/break2.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/froglight/break2.ogg new file mode 100644 index 0000000..30722ae Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/froglight/break2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/froglight/break3.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/froglight/break3.ogg new file mode 100644 index 0000000..20b043b Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/froglight/break3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/froglight/break4.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/froglight/break4.ogg new file mode 100644 index 0000000..1bff133 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/froglight/break4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/froglight/step1.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/froglight/step1.ogg new file mode 100644 index 0000000..817b613 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/froglight/step1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/froglight/step2.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/froglight/step2.ogg new file mode 100644 index 0000000..f6c9a58 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/froglight/step2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/froglight/step3.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/froglight/step3.ogg new file mode 100644 index 0000000..f4945f1 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/froglight/step3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/froglight/step4.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/froglight/step4.ogg new file mode 100644 index 0000000..76fd667 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/froglight/step4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/froglight/step5.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/froglight/step5.ogg new file mode 100644 index 0000000..22bfff0 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/froglight/step5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/froglight/step6.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/froglight/step6.ogg new file mode 100644 index 0000000..46b9ffd Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/froglight/step6.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/break1.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/break1.ogg new file mode 100644 index 0000000..b6ab020 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/break1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/break2.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/break2.ogg new file mode 100644 index 0000000..8af68be Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/break2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/break3.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/break3.ogg new file mode 100644 index 0000000..e6d31ac Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/break3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/break4.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/break4.ogg new file mode 100644 index 0000000..2d72f11 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/break4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/hatch1.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/hatch1.ogg new file mode 100644 index 0000000..d6f972a Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/hatch1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/hatch2.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/hatch2.ogg new file mode 100644 index 0000000..0d53226 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/hatch2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/hatch3.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/hatch3.ogg new file mode 100644 index 0000000..2896c2e Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/hatch3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/hatch4.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/hatch4.ogg new file mode 100644 index 0000000..deb8406 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/hatch4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/hatch5.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/hatch5.ogg new file mode 100644 index 0000000..a6b7ec8 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/hatch5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/step1.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/step1.ogg new file mode 100644 index 0000000..2987e4b Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/step1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/step2.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/step2.ogg new file mode 100644 index 0000000..cf28189 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/step2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/step3.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/step3.ogg new file mode 100644 index 0000000..5074dd1 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/step3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/step4.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/step4.ogg new file mode 100644 index 0000000..426f2f9 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/step4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/step5.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/step5.ogg new file mode 100644 index 0000000..cd7f394 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/step5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/step6.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/step6.ogg new file mode 100644 index 0000000..4da79c8 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/frogspawn/step6.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/break1.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/break1.ogg new file mode 100644 index 0000000..d547ff7 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/break1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/break2.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/break2.ogg new file mode 100644 index 0000000..1fe5abc Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/break2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/break3.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/break3.ogg new file mode 100644 index 0000000..83912b7 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/break3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/break4.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/break4.ogg new file mode 100644 index 0000000..64cedec Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/break4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/break5.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/break5.ogg new file mode 100644 index 0000000..ff26d6e Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/break5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/break6.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/break6.ogg new file mode 100644 index 0000000..59c362c Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/break6.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/step1.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/step1.ogg new file mode 100644 index 0000000..ac78c2e Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/step1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/step2.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/step2.ogg new file mode 100644 index 0000000..05d840a Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/step2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/step3.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/step3.ogg new file mode 100644 index 0000000..f9e917b Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/step3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/step4.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/step4.ogg new file mode 100644 index 0000000..4bc68cd Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/step4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/step5.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/step5.ogg new file mode 100644 index 0000000..4b9b334 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/step5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/step6.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/step6.ogg new file mode 100644 index 0000000..95430cc Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mangrove_roots/step6.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mud/break1.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mud/break1.ogg new file mode 100644 index 0000000..bf022da Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mud/break1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mud/break2.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mud/break2.ogg new file mode 100644 index 0000000..957947c Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mud/break2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mud/break3.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mud/break3.ogg new file mode 100644 index 0000000..9eb9291 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mud/break3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mud/break4.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mud/break4.ogg new file mode 100644 index 0000000..db86441 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mud/break4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mud/break5.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mud/break5.ogg new file mode 100644 index 0000000..128b854 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mud/break5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mud/break6.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mud/break6.ogg new file mode 100644 index 0000000..eaa0367 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mud/break6.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mud/step1.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mud/step1.ogg new file mode 100644 index 0000000..6d67359 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mud/step1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mud/step2.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mud/step2.ogg new file mode 100644 index 0000000..f759762 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mud/step2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mud/step3.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mud/step3.ogg new file mode 100644 index 0000000..a67365f Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mud/step3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mud/step4.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mud/step4.ogg new file mode 100644 index 0000000..0e6e387 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mud/step4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mud/step5.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mud/step5.ogg new file mode 100644 index 0000000..1d24159 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mud/step5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mud/step6.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mud/step6.ogg new file mode 100644 index 0000000..34794f9 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mud/step6.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/break1.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/break1.ogg new file mode 100644 index 0000000..7b5c78d Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/break1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/break2.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/break2.ogg new file mode 100644 index 0000000..458a4bf Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/break2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/break3.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/break3.ogg new file mode 100644 index 0000000..d4927d5 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/break3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/break4.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/break4.ogg new file mode 100644 index 0000000..1a27f7c Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/break4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/break5.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/break5.ogg new file mode 100644 index 0000000..1f6b1e1 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/break5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/break6.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/break6.ogg new file mode 100644 index 0000000..0f6bc7b Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/break6.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/step1.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/step1.ogg new file mode 100644 index 0000000..1826ef6 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/step1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/step2.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/step2.ogg new file mode 100644 index 0000000..89d4ba3 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/step2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/step3.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/step3.ogg new file mode 100644 index 0000000..1682d76 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/step3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/step4.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/step4.ogg new file mode 100644 index 0000000..904d926 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/step4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/step5.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/step5.ogg new file mode 100644 index 0000000..37f8336 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/step5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/step6.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/step6.ogg new file mode 100644 index 0000000..8090789 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/mud_bricks/step6.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/break1.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/break1.ogg new file mode 100644 index 0000000..9b3460c Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/break1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/break2.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/break2.ogg new file mode 100644 index 0000000..7be18a3 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/break2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/break3.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/break3.ogg new file mode 100644 index 0000000..0bcee21 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/break3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/break4.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/break4.ogg new file mode 100644 index 0000000..f217aff Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/break4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/break5.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/break5.ogg new file mode 100644 index 0000000..a1118ed Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/break5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/break6.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/break6.ogg new file mode 100644 index 0000000..fbdedc6 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/break6.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/step1.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/step1.ogg new file mode 100644 index 0000000..8cd80cb Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/step1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/step2.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/step2.ogg new file mode 100644 index 0000000..1f26a4f Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/step2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/step3.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/step3.ogg new file mode 100644 index 0000000..e357722 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/step3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/step4.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/step4.ogg new file mode 100644 index 0000000..a799e5d Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/step4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/step5.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/step5.ogg new file mode 100644 index 0000000..9bcd837 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/step5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/step6.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/step6.ogg new file mode 100644 index 0000000..ed515f1 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/muddy_mangrove_roots/step6.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/break1.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/break1.ogg new file mode 100644 index 0000000..75fdb95 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/break1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/break2.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/break2.ogg new file mode 100644 index 0000000..4f45da5 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/break2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/break3.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/break3.ogg new file mode 100644 index 0000000..052fa79 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/break3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/break4.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/break4.ogg new file mode 100644 index 0000000..4224208 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/break4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/break5.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/break5.ogg new file mode 100644 index 0000000..e8a565c Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/break5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/break6.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/break6.ogg new file mode 100644 index 0000000..dad2a34 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/break6.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/step1.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/step1.ogg new file mode 100644 index 0000000..78f8f31 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/step1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/step2.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/step2.ogg new file mode 100644 index 0000000..3d06582 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/step2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/step3.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/step3.ogg new file mode 100644 index 0000000..3da7643 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/step3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/step4.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/step4.ogg new file mode 100644 index 0000000..4461c53 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/step4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/step5.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/step5.ogg new file mode 100644 index 0000000..347228f Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/step5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/step6.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/step6.ogg new file mode 100644 index 0000000..2756436 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/packed_mud/step6.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break1.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break1.ogg new file mode 100644 index 0000000..65cf24f Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break10.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break10.ogg new file mode 100644 index 0000000..d1ed33c Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break10.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break11.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break11.ogg new file mode 100644 index 0000000..1d2d095 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break11.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break12.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break12.ogg new file mode 100644 index 0000000..bc05687 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break12.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break13.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break13.ogg new file mode 100644 index 0000000..ac3af89 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break13.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break14.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break14.ogg new file mode 100644 index 0000000..acf5b97 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break14.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break2.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break2.ogg new file mode 100644 index 0000000..0e4a613 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break3.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break3.ogg new file mode 100644 index 0000000..67d3088 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break4.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break4.ogg new file mode 100644 index 0000000..fa7f942 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break5.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break5.ogg new file mode 100644 index 0000000..c80c664 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break6.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break6.ogg new file mode 100644 index 0000000..fd123f7 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break6.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break7.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break7.ogg new file mode 100644 index 0000000..0259520 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break7.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break8.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break8.ogg new file mode 100644 index 0000000..8ff76bf Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break8.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break9.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break9.ogg new file mode 100644 index 0000000..8ec00b2 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/break9.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/charge1.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/charge1.ogg new file mode 100644 index 0000000..5de51e2 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/charge1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/charge2.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/charge2.ogg new file mode 100644 index 0000000..59451c4 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/charge2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/charge3.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/charge3.ogg new file mode 100644 index 0000000..485170b Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/charge3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/charge4.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/charge4.ogg new file mode 100644 index 0000000..919567f Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/charge4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/charge5.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/charge5.ogg new file mode 100644 index 0000000..f94a450 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/charge5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/place1.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/place1.ogg new file mode 100644 index 0000000..0784d35 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/place1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/place2.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/place2.ogg new file mode 100644 index 0000000..5da6b3b Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/place2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/place3.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/place3.ogg new file mode 100644 index 0000000..5da6b3b Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/place3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/place4.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/place4.ogg new file mode 100644 index 0000000..3ed5ace Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/place4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/place5.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/place5.ogg new file mode 100644 index 0000000..feceb50 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/place5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/spread1.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/spread1.ogg new file mode 100644 index 0000000..7299984 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/spread1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/spread2.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/spread2.ogg new file mode 100644 index 0000000..75f745f Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/spread2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/spread3.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/spread3.ogg new file mode 100644 index 0000000..1dfbdf0 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/spread3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/spread4.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/spread4.ogg new file mode 100644 index 0000000..3120c42 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/spread4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/spread5.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/spread5.ogg new file mode 100644 index 0000000..8fb30b2 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/spread5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/step1.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/step1.ogg new file mode 100644 index 0000000..7345614 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/step1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/step2.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/step2.ogg new file mode 100644 index 0000000..f7be3a5 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/step2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/step3.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/step3.ogg new file mode 100644 index 0000000..331229b Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/step3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/step4.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/step4.ogg new file mode 100644 index 0000000..b6dd932 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/step4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/step5.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/step5.ogg new file mode 100644 index 0000000..77f3f0d Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/step5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk/step6.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/step6.ogg new file mode 100644 index 0000000..60a5899 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk/step6.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/break1.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/break1.ogg new file mode 100644 index 0000000..fda2cf6 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/break1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/break10.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/break10.ogg new file mode 100644 index 0000000..2311f3f Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/break10.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/break2.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/break2.ogg new file mode 100644 index 0000000..db822da Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/break2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/break3.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/break3.ogg new file mode 100644 index 0000000..edaf34c Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/break3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/break4.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/break4.ogg new file mode 100644 index 0000000..6c57b28 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/break4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/break5.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/break5.ogg new file mode 100644 index 0000000..1d8499a Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/break5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/break6.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/break6.ogg new file mode 100644 index 0000000..46fd311 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/break6.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/break7.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/break7.ogg new file mode 100644 index 0000000..816340c Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/break7.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/break8.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/break8.ogg new file mode 100644 index 0000000..dc0504e Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/break8.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/break9.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/break9.ogg new file mode 100644 index 0000000..84c4f4b Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/break9.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/place1.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/place1.ogg new file mode 100644 index 0000000..6117c8c Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/place1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/place2.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/place2.ogg new file mode 100644 index 0000000..e18922c Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/place2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/place3.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/place3.ogg new file mode 100644 index 0000000..52d256d Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/place3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/place4.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/place4.ogg new file mode 100644 index 0000000..e8de95f Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/place4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/place5.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/place5.ogg new file mode 100644 index 0000000..dfde459 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/place5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/step1.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/step1.ogg new file mode 100644 index 0000000..17da67b Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/step1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/step2.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/step2.ogg new file mode 100644 index 0000000..5067a6e Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/step2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/step3.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/step3.ogg new file mode 100644 index 0000000..df290bc Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/step3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/step4.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/step4.ogg new file mode 100644 index 0000000..845da73 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/step4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/step5.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/step5.ogg new file mode 100644 index 0000000..20b39d3 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/step5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/step6.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/step6.ogg new file mode 100644 index 0000000..eb299a9 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_catalyst/step6.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/break1.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/break1.ogg new file mode 100644 index 0000000..619335e Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/break1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/break2.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/break2.ogg new file mode 100644 index 0000000..95b3f22 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/break2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/break3.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/break3.ogg new file mode 100644 index 0000000..d8a69e5 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/break3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/break4.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/break4.ogg new file mode 100644 index 0000000..d62a20a Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/break4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/break5.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/break5.ogg new file mode 100644 index 0000000..25227c9 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/break5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/break6.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/break6.ogg new file mode 100644 index 0000000..bfa2d05 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/break6.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/place1.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/place1.ogg new file mode 100644 index 0000000..ebf3d4d Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/place1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/place2.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/place2.ogg new file mode 100644 index 0000000..d882e66 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/place2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/place3.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/place3.ogg new file mode 100644 index 0000000..22c5b99 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/place3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/place4.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/place4.ogg new file mode 100644 index 0000000..a8388b8 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/place4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/place5.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/place5.ogg new file mode 100644 index 0000000..0fff86b Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/place5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/shriek1.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/shriek1.ogg new file mode 100644 index 0000000..70ec79f Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/shriek1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/shriek2.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/shriek2.ogg new file mode 100644 index 0000000..1c73793 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/shriek2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/shriek3.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/shriek3.ogg new file mode 100644 index 0000000..ab1ad64 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/shriek3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/shriek4.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/shriek4.ogg new file mode 100644 index 0000000..949a5d4 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/shriek4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/shriek5.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/shriek5.ogg new file mode 100644 index 0000000..6b4bb6c Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_shrieker/shriek5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_vein/break1.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_vein/break1.ogg new file mode 100644 index 0000000..f2d7ad8 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_vein/break1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_vein/break2.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_vein/break2.ogg new file mode 100644 index 0000000..a129439 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_vein/break2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_vein/break3.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_vein/break3.ogg new file mode 100644 index 0000000..613af7e Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_vein/break3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_vein/break4.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_vein/break4.ogg new file mode 100644 index 0000000..5417119 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_vein/break4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/block/sculk_vein/break5.ogg b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_vein/break5.ogg new file mode 100644 index 0000000..f156c23 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/block/sculk_vein/break5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/item/goat_horn/call0.ogg b/common/src/main/resources/assets/wildbackport/sounds/item/goat_horn/call0.ogg new file mode 100644 index 0000000..de98354 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/item/goat_horn/call0.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/item/goat_horn/call1.ogg b/common/src/main/resources/assets/wildbackport/sounds/item/goat_horn/call1.ogg new file mode 100644 index 0000000..34fc130 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/item/goat_horn/call1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/item/goat_horn/call2.ogg b/common/src/main/resources/assets/wildbackport/sounds/item/goat_horn/call2.ogg new file mode 100644 index 0000000..f28b7e5 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/item/goat_horn/call2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/item/goat_horn/call3.ogg b/common/src/main/resources/assets/wildbackport/sounds/item/goat_horn/call3.ogg new file mode 100644 index 0000000..0828589 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/item/goat_horn/call3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/item/goat_horn/call4.ogg b/common/src/main/resources/assets/wildbackport/sounds/item/goat_horn/call4.ogg new file mode 100644 index 0000000..d2c30e7 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/item/goat_horn/call4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/item/goat_horn/call5.ogg b/common/src/main/resources/assets/wildbackport/sounds/item/goat_horn/call5.ogg new file mode 100644 index 0000000..c4c8848 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/item/goat_horn/call5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/item/goat_horn/call6.ogg b/common/src/main/resources/assets/wildbackport/sounds/item/goat_horn/call6.ogg new file mode 100644 index 0000000..01aba9e Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/item/goat_horn/call6.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/item/goat_horn/call7.ogg b/common/src/main/resources/assets/wildbackport/sounds/item/goat_horn/call7.ogg new file mode 100644 index 0000000..2a4e72d Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/item/goat_horn/call7.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/frog/death1.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/death1.ogg new file mode 100644 index 0000000..5b389d9 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/death1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/frog/death2.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/death2.ogg new file mode 100644 index 0000000..a9b120b Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/death2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/frog/death3.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/death3.ogg new file mode 100644 index 0000000..555d75e Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/death3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/frog/eat1.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/eat1.ogg new file mode 100644 index 0000000..d49b530 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/eat1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/frog/eat2.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/eat2.ogg new file mode 100644 index 0000000..5490c0a Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/eat2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/frog/eat3.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/eat3.ogg new file mode 100644 index 0000000..6fff09d Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/eat3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/frog/eat4.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/eat4.ogg new file mode 100644 index 0000000..5442fb1 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/eat4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/frog/hurt1.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/hurt1.ogg new file mode 100644 index 0000000..c545a01 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/hurt1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/frog/hurt2.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/hurt2.ogg new file mode 100644 index 0000000..14452bf Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/hurt2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/frog/hurt3.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/hurt3.ogg new file mode 100644 index 0000000..4bdedb6 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/hurt3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/frog/hurt4.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/hurt4.ogg new file mode 100644 index 0000000..b0fe557 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/hurt4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/frog/hurt5.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/hurt5.ogg new file mode 100644 index 0000000..8f88ece Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/hurt5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/frog/idle1.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/idle1.ogg new file mode 100644 index 0000000..a1fd6e5 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/idle1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/frog/idle2.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/idle2.ogg new file mode 100644 index 0000000..dcfd910 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/idle2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/frog/idle3.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/idle3.ogg new file mode 100644 index 0000000..ab0ddd5 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/idle3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/frog/idle4.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/idle4.ogg new file mode 100644 index 0000000..da697ae Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/idle4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/frog/idle5.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/idle5.ogg new file mode 100644 index 0000000..79b8959 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/idle5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/frog/idle6.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/idle6.ogg new file mode 100644 index 0000000..5fa50ec Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/idle6.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/frog/idle7.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/idle7.ogg new file mode 100644 index 0000000..d4f0d00 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/idle7.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/frog/idle8.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/idle8.ogg new file mode 100644 index 0000000..1682404 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/idle8.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/frog/lay_spawn1.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/lay_spawn1.ogg new file mode 100644 index 0000000..69e8b42 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/lay_spawn1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/frog/lay_spawn2.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/lay_spawn2.ogg new file mode 100644 index 0000000..c0c58e8 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/lay_spawn2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/frog/long_jump1.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/long_jump1.ogg new file mode 100644 index 0000000..4b4b67b Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/long_jump1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/frog/long_jump2.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/long_jump2.ogg new file mode 100644 index 0000000..e9d3e78 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/long_jump2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/frog/long_jump3.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/long_jump3.ogg new file mode 100644 index 0000000..6e043ef Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/long_jump3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/frog/long_jump4.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/long_jump4.ogg new file mode 100644 index 0000000..84d9d9f Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/long_jump4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/frog/step1.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/step1.ogg new file mode 100644 index 0000000..bc6aa98 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/step1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/frog/step2.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/step2.ogg new file mode 100644 index 0000000..2eb440e Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/step2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/frog/step3.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/step3.ogg new file mode 100644 index 0000000..4a8c072 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/step3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/frog/step4.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/step4.ogg new file mode 100644 index 0000000..e851bf4 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/step4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/frog/tounge1.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/tounge1.ogg new file mode 100644 index 0000000..a1436fd Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/tounge1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/frog/tounge2.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/tounge2.ogg new file mode 100644 index 0000000..93b0041 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/tounge2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/frog/tounge3.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/tounge3.ogg new file mode 100644 index 0000000..027d7e4 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/tounge3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/frog/tounge4.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/tounge4.ogg new file mode 100644 index 0000000..eee8631 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/frog/tounge4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/tadpole/death1.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/tadpole/death1.ogg new file mode 100644 index 0000000..a528d5d Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/tadpole/death1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/tadpole/death2.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/tadpole/death2.ogg new file mode 100644 index 0000000..5321273 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/tadpole/death2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/tadpole/hurt1.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/tadpole/hurt1.ogg new file mode 100644 index 0000000..480b6f1 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/tadpole/hurt1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/tadpole/hurt2.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/tadpole/hurt2.ogg new file mode 100644 index 0000000..57fd026 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/tadpole/hurt2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/tadpole/hurt3.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/tadpole/hurt3.ogg new file mode 100644 index 0000000..3531989 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/tadpole/hurt3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/tadpole/hurt4.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/tadpole/hurt4.ogg new file mode 100644 index 0000000..f4547ee Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/tadpole/hurt4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/agitated_1.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/agitated_1.ogg new file mode 100644 index 0000000..657976f Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/agitated_1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/agitated_2.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/agitated_2.ogg new file mode 100644 index 0000000..a6587bc Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/agitated_2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/agitated_3.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/agitated_3.ogg new file mode 100644 index 0000000..b5e9f06 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/agitated_3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/agitated_4.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/agitated_4.ogg new file mode 100644 index 0000000..3b3fc05 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/agitated_4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/agitated_5.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/agitated_5.ogg new file mode 100644 index 0000000..58d202c Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/agitated_5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/agitated_6.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/agitated_6.ogg new file mode 100644 index 0000000..1e3b693 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/agitated_6.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/angry_1.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/angry_1.ogg new file mode 100644 index 0000000..efb776b Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/angry_1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/angry_2.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/angry_2.ogg new file mode 100644 index 0000000..6c2b8bd Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/angry_2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/angry_3.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/angry_3.ogg new file mode 100644 index 0000000..3436755 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/angry_3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/angry_4.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/angry_4.ogg new file mode 100644 index 0000000..a3ded03 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/angry_4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/angry_5.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/angry_5.ogg new file mode 100644 index 0000000..8c9ff39 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/angry_5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/angry_6.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/angry_6.ogg new file mode 100644 index 0000000..f8510ce Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/angry_6.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/attack_impact_1.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/attack_impact_1.ogg new file mode 100644 index 0000000..e551ba7 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/attack_impact_1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/attack_impact_2.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/attack_impact_2.ogg new file mode 100644 index 0000000..28ddb2e Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/attack_impact_2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/death_1.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/death_1.ogg new file mode 100644 index 0000000..e482c39 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/death_1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/death_2.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/death_2.ogg new file mode 100644 index 0000000..183e46d Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/death_2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/dig.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/dig.ogg new file mode 100644 index 0000000..655a75d Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/dig.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/emerge.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/emerge.ogg new file mode 100644 index 0000000..f3884e5 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/emerge.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/heartbeat_1.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/heartbeat_1.ogg new file mode 100644 index 0000000..cb96576 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/heartbeat_1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/heartbeat_2.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/heartbeat_2.ogg new file mode 100644 index 0000000..6efc76e Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/heartbeat_2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/heartbeat_3.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/heartbeat_3.ogg new file mode 100644 index 0000000..cff5ec1 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/heartbeat_3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/heartbeat_4.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/heartbeat_4.ogg new file mode 100644 index 0000000..5c95d29 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/heartbeat_4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/hurt_1.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/hurt_1.ogg new file mode 100644 index 0000000..3a98e14 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/hurt_1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/hurt_2.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/hurt_2.ogg new file mode 100644 index 0000000..86949f5 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/hurt_2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/hurt_3.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/hurt_3.ogg new file mode 100644 index 0000000..85e58af Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/hurt_3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/hurt_4.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/hurt_4.ogg new file mode 100644 index 0000000..aedaa5b Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/hurt_4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_1.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_1.ogg new file mode 100644 index 0000000..4fa6b87 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_10.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_10.ogg new file mode 100644 index 0000000..30eccd3 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_10.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_11.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_11.ogg new file mode 100644 index 0000000..92acd9b Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_11.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_12.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_12.ogg new file mode 100644 index 0000000..188ce11 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_12.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_2.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_2.ogg new file mode 100644 index 0000000..38d2f3f Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_3.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_3.ogg new file mode 100644 index 0000000..0d1ec1c Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_4.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_4.ogg new file mode 100644 index 0000000..1667ec6 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_5.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_5.ogg new file mode 100644 index 0000000..54eb492 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_6.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_6.ogg new file mode 100644 index 0000000..07375c1 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_6.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_7.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_7.ogg new file mode 100644 index 0000000..0ccee7f Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_7.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_8.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_8.ogg new file mode 100644 index 0000000..3509eb3 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_8.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_9.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_9.ogg new file mode 100644 index 0000000..a9cf35b Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/idle_9.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/listening_1.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/listening_1.ogg new file mode 100644 index 0000000..3f9210e Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/listening_1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/listening_2.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/listening_2.ogg new file mode 100644 index 0000000..c01cf3c Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/listening_2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/listening_3.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/listening_3.ogg new file mode 100644 index 0000000..4146d5e Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/listening_3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/listening_4.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/listening_4.ogg new file mode 100644 index 0000000..957413f Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/listening_4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/listening_5.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/listening_5.ogg new file mode 100644 index 0000000..093cfd0 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/listening_5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/listening_angry_1.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/listening_angry_1.ogg new file mode 100644 index 0000000..c8c0032 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/listening_angry_1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/listening_angry_2.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/listening_angry_2.ogg new file mode 100644 index 0000000..bcad838 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/listening_angry_2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/listening_angry_3.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/listening_angry_3.ogg new file mode 100644 index 0000000..5964954 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/listening_angry_3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/listening_angry_4.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/listening_angry_4.ogg new file mode 100644 index 0000000..8e7f141 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/listening_angry_4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/listening_angry_5.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/listening_angry_5.ogg new file mode 100644 index 0000000..1d13d18 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/listening_angry_5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/nearby_close_1.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/nearby_close_1.ogg new file mode 100644 index 0000000..f173f6d Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/nearby_close_1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/nearby_close_2.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/nearby_close_2.ogg new file mode 100644 index 0000000..f0322a4 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/nearby_close_2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/nearby_close_3.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/nearby_close_3.ogg new file mode 100644 index 0000000..ccbd721 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/nearby_close_3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/nearby_close_4.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/nearby_close_4.ogg new file mode 100644 index 0000000..25ec28b Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/nearby_close_4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/nearby_closer_1.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/nearby_closer_1.ogg new file mode 100644 index 0000000..6fcf46f Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/nearby_closer_1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/nearby_closer_2.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/nearby_closer_2.ogg new file mode 100644 index 0000000..e32008f Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/nearby_closer_2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/nearby_closer_3.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/nearby_closer_3.ogg new file mode 100644 index 0000000..b1b8970 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/nearby_closer_3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/nearby_closest_1.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/nearby_closest_1.ogg new file mode 100644 index 0000000..d7745ba Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/nearby_closest_1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/nearby_closest_2.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/nearby_closest_2.ogg new file mode 100644 index 0000000..4e5db5a Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/nearby_closest_2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/nearby_closest_3.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/nearby_closest_3.ogg new file mode 100644 index 0000000..be172c2 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/nearby_closest_3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/roar_1.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/roar_1.ogg new file mode 100644 index 0000000..54450bb Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/roar_1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/roar_2.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/roar_2.ogg new file mode 100644 index 0000000..de2066f Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/roar_2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/roar_3.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/roar_3.ogg new file mode 100644 index 0000000..e61613c Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/roar_3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/roar_4.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/roar_4.ogg new file mode 100644 index 0000000..57fac03 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/roar_4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/roar_5.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/roar_5.ogg new file mode 100644 index 0000000..9e7953f Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/roar_5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sniff_1.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sniff_1.ogg new file mode 100644 index 0000000..ff69165 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sniff_1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sniff_2.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sniff_2.ogg new file mode 100644 index 0000000..5d25a01 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sniff_2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sniff_3.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sniff_3.ogg new file mode 100644 index 0000000..ed4ba5e Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sniff_3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sniff_4.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sniff_4.ogg new file mode 100644 index 0000000..5ad5422 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sniff_4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sonic_boom1.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sonic_boom1.ogg new file mode 100644 index 0000000..a8205d3 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sonic_boom1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sonic_boom2.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sonic_boom2.ogg new file mode 100644 index 0000000..2c41f2b Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sonic_boom2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sonic_boom3.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sonic_boom3.ogg new file mode 100644 index 0000000..fc9d28b Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sonic_boom3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sonic_boom4.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sonic_boom4.ogg new file mode 100644 index 0000000..d2abbc9 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sonic_boom4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sonic_charge1.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sonic_charge1.ogg new file mode 100644 index 0000000..516d0f7 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sonic_charge1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sonic_charge2.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sonic_charge2.ogg new file mode 100644 index 0000000..17e18e1 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sonic_charge2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sonic_charge3.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sonic_charge3.ogg new file mode 100644 index 0000000..9a0df89 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sonic_charge3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sonic_charge4.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sonic_charge4.ogg new file mode 100644 index 0000000..e223fcd Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/sonic_charge4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/step_1.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/step_1.ogg new file mode 100644 index 0000000..794ae0f Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/step_1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/step_2.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/step_2.ogg new file mode 100644 index 0000000..cb75222 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/step_2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/step_3.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/step_3.ogg new file mode 100644 index 0000000..d31e3f2 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/step_3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/step_4.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/step_4.ogg new file mode 100644 index 0000000..7437964 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/step_4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/tendril_clicks_1.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/tendril_clicks_1.ogg new file mode 100644 index 0000000..03bd68b Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/tendril_clicks_1.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/tendril_clicks_2.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/tendril_clicks_2.ogg new file mode 100644 index 0000000..16e2a8f Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/tendril_clicks_2.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/tendril_clicks_3.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/tendril_clicks_3.ogg new file mode 100644 index 0000000..95143e7 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/tendril_clicks_3.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/tendril_clicks_4.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/tendril_clicks_4.ogg new file mode 100644 index 0000000..f390b6c Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/tendril_clicks_4.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/tendril_clicks_5.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/tendril_clicks_5.ogg new file mode 100644 index 0000000..cf08791 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/tendril_clicks_5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/mob/warden/tendril_clicks_6.ogg b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/tendril_clicks_6.ogg new file mode 100644 index 0000000..9b0f728 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/mob/warden/tendril_clicks_6.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/sounds/records/5.ogg b/common/src/main/resources/assets/wildbackport/sounds/records/5.ogg new file mode 100644 index 0000000..6545616 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/sounds/records/5.ogg differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/frogspawn.png b/common/src/main/resources/assets/wildbackport/textures/block/frogspawn.png new file mode 100644 index 0000000..2289054 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/frogspawn.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/mangrove_door_bottom.png b/common/src/main/resources/assets/wildbackport/textures/block/mangrove_door_bottom.png new file mode 100644 index 0000000..d8ab563 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/mangrove_door_bottom.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/mangrove_door_top.png b/common/src/main/resources/assets/wildbackport/textures/block/mangrove_door_top.png new file mode 100644 index 0000000..900efe1 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/mangrove_door_top.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/mangrove_leaves.png b/common/src/main/resources/assets/wildbackport/textures/block/mangrove_leaves.png new file mode 100644 index 0000000..8a51d89 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/mangrove_leaves.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/mangrove_log.png b/common/src/main/resources/assets/wildbackport/textures/block/mangrove_log.png new file mode 100644 index 0000000..149d833 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/mangrove_log.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/mangrove_log_top.png b/common/src/main/resources/assets/wildbackport/textures/block/mangrove_log_top.png new file mode 100644 index 0000000..f2c4d64 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/mangrove_log_top.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/mangrove_planks.png b/common/src/main/resources/assets/wildbackport/textures/block/mangrove_planks.png new file mode 100644 index 0000000..a18b4db Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/mangrove_planks.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/mangrove_propagule.png b/common/src/main/resources/assets/wildbackport/textures/block/mangrove_propagule.png new file mode 100644 index 0000000..6226526 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/mangrove_propagule.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/mangrove_propagule_hanging.png b/common/src/main/resources/assets/wildbackport/textures/block/mangrove_propagule_hanging.png new file mode 100644 index 0000000..1ebc363 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/mangrove_propagule_hanging.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/mangrove_roots_side.png b/common/src/main/resources/assets/wildbackport/textures/block/mangrove_roots_side.png new file mode 100644 index 0000000..658754e Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/mangrove_roots_side.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/mangrove_roots_top.png b/common/src/main/resources/assets/wildbackport/textures/block/mangrove_roots_top.png new file mode 100644 index 0000000..5e2eb10 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/mangrove_roots_top.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/mangrove_trapdoor.png b/common/src/main/resources/assets/wildbackport/textures/block/mangrove_trapdoor.png new file mode 100644 index 0000000..4bd2fb7 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/mangrove_trapdoor.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/mud.png b/common/src/main/resources/assets/wildbackport/textures/block/mud.png new file mode 100644 index 0000000..104d291 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/mud.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/mud_bricks.png b/common/src/main/resources/assets/wildbackport/textures/block/mud_bricks.png new file mode 100644 index 0000000..714a786 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/mud_bricks.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/muddy_mangrove_roots_side.png b/common/src/main/resources/assets/wildbackport/textures/block/muddy_mangrove_roots_side.png new file mode 100644 index 0000000..9436714 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/muddy_mangrove_roots_side.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/muddy_mangrove_roots_top.png b/common/src/main/resources/assets/wildbackport/textures/block/muddy_mangrove_roots_top.png new file mode 100644 index 0000000..dbbe6b0 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/muddy_mangrove_roots_top.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/ochre_froglight_side.png b/common/src/main/resources/assets/wildbackport/textures/block/ochre_froglight_side.png new file mode 100644 index 0000000..c914bb8 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/ochre_froglight_side.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/ochre_froglight_top.png b/common/src/main/resources/assets/wildbackport/textures/block/ochre_froglight_top.png new file mode 100644 index 0000000..68cfb42 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/ochre_froglight_top.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/packed_mud.png b/common/src/main/resources/assets/wildbackport/textures/block/packed_mud.png new file mode 100644 index 0000000..c1539af Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/packed_mud.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/pearlescent_froglight_side.png b/common/src/main/resources/assets/wildbackport/textures/block/pearlescent_froglight_side.png new file mode 100644 index 0000000..8f15ce6 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/pearlescent_froglight_side.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/pearlescent_froglight_top.png b/common/src/main/resources/assets/wildbackport/textures/block/pearlescent_froglight_top.png new file mode 100644 index 0000000..c8cb051 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/pearlescent_froglight_top.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/reinforced_deepslate_bottom.png b/common/src/main/resources/assets/wildbackport/textures/block/reinforced_deepslate_bottom.png new file mode 100644 index 0000000..8198406 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/reinforced_deepslate_bottom.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/reinforced_deepslate_side.png b/common/src/main/resources/assets/wildbackport/textures/block/reinforced_deepslate_side.png new file mode 100644 index 0000000..03edd00 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/reinforced_deepslate_side.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/reinforced_deepslate_top.png b/common/src/main/resources/assets/wildbackport/textures/block/reinforced_deepslate_top.png new file mode 100644 index 0000000..bee3fab Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/reinforced_deepslate_top.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/sculk.png b/common/src/main/resources/assets/wildbackport/textures/block/sculk.png new file mode 100644 index 0000000..f15f87d Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/sculk.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/sculk.png.mcmeta b/common/src/main/resources/assets/wildbackport/textures/block/sculk.png.mcmeta new file mode 100644 index 0000000..020f8e5 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/textures/block/sculk.png.mcmeta @@ -0,0 +1,6 @@ +{ + "animation": { + "frametime": 20, + "interpolate": true + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/textures/block/sculk_catalyst_bottom.png b/common/src/main/resources/assets/wildbackport/textures/block/sculk_catalyst_bottom.png new file mode 100644 index 0000000..3db8e1f Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/sculk_catalyst_bottom.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/sculk_catalyst_side.png b/common/src/main/resources/assets/wildbackport/textures/block/sculk_catalyst_side.png new file mode 100644 index 0000000..d44db34 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/sculk_catalyst_side.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/sculk_catalyst_side_bloom.png b/common/src/main/resources/assets/wildbackport/textures/block/sculk_catalyst_side_bloom.png new file mode 100644 index 0000000..27ecdc8 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/sculk_catalyst_side_bloom.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/sculk_catalyst_side_bloom.png.mcmeta b/common/src/main/resources/assets/wildbackport/textures/block/sculk_catalyst_side_bloom.png.mcmeta new file mode 100644 index 0000000..581e920 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/textures/block/sculk_catalyst_side_bloom.png.mcmeta @@ -0,0 +1,5 @@ +{ + "animation": { + "frametime": 1 + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/textures/block/sculk_catalyst_top.png b/common/src/main/resources/assets/wildbackport/textures/block/sculk_catalyst_top.png new file mode 100644 index 0000000..75e7e8b Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/sculk_catalyst_top.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/sculk_catalyst_top_bloom.png b/common/src/main/resources/assets/wildbackport/textures/block/sculk_catalyst_top_bloom.png new file mode 100644 index 0000000..79f2e13 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/sculk_catalyst_top_bloom.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/sculk_catalyst_top_bloom.png.mcmeta b/common/src/main/resources/assets/wildbackport/textures/block/sculk_catalyst_top_bloom.png.mcmeta new file mode 100644 index 0000000..581e920 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/textures/block/sculk_catalyst_top_bloom.png.mcmeta @@ -0,0 +1,5 @@ +{ + "animation": { + "frametime": 1 + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/textures/block/sculk_shrieker_bottom.png b/common/src/main/resources/assets/wildbackport/textures/block/sculk_shrieker_bottom.png new file mode 100644 index 0000000..9892049 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/sculk_shrieker_bottom.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/sculk_shrieker_inner_top.png b/common/src/main/resources/assets/wildbackport/textures/block/sculk_shrieker_inner_top.png new file mode 100644 index 0000000..f65f8b4 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/sculk_shrieker_inner_top.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/sculk_shrieker_inner_top.png.mcmeta b/common/src/main/resources/assets/wildbackport/textures/block/sculk_shrieker_inner_top.png.mcmeta new file mode 100644 index 0000000..e9b1851 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/textures/block/sculk_shrieker_inner_top.png.mcmeta @@ -0,0 +1,6 @@ +{ + "animation": { + "frametime": 3, + "interpolate": true + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/textures/block/sculk_shrieker_side.png b/common/src/main/resources/assets/wildbackport/textures/block/sculk_shrieker_side.png new file mode 100644 index 0000000..ffe8afe Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/sculk_shrieker_side.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/sculk_shrieker_top.png b/common/src/main/resources/assets/wildbackport/textures/block/sculk_shrieker_top.png new file mode 100644 index 0000000..828a18a Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/sculk_shrieker_top.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/sculk_vein.png b/common/src/main/resources/assets/wildbackport/textures/block/sculk_vein.png new file mode 100644 index 0000000..7e9116e Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/sculk_vein.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/sculk_vein.png.mcmeta b/common/src/main/resources/assets/wildbackport/textures/block/sculk_vein.png.mcmeta new file mode 100644 index 0000000..020f8e5 --- /dev/null +++ b/common/src/main/resources/assets/wildbackport/textures/block/sculk_vein.png.mcmeta @@ -0,0 +1,6 @@ +{ + "animation": { + "frametime": 20, + "interpolate": true + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/wildbackport/textures/block/stripped_mangrove_log.png b/common/src/main/resources/assets/wildbackport/textures/block/stripped_mangrove_log.png new file mode 100644 index 0000000..7ff5669 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/stripped_mangrove_log.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/stripped_mangrove_log_top.png b/common/src/main/resources/assets/wildbackport/textures/block/stripped_mangrove_log_top.png new file mode 100644 index 0000000..9d05e81 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/stripped_mangrove_log_top.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/verdant_froglight_side.png b/common/src/main/resources/assets/wildbackport/textures/block/verdant_froglight_side.png new file mode 100644 index 0000000..5f18747 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/verdant_froglight_side.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/block/verdant_froglight_top.png b/common/src/main/resources/assets/wildbackport/textures/block/verdant_froglight_top.png new file mode 100644 index 0000000..964bfb7 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/block/verdant_froglight_top.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/entity/allay/allay.png b/common/src/main/resources/assets/wildbackport/textures/entity/allay/allay.png new file mode 100644 index 0000000..ab47fbf Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/entity/allay/allay.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/entity/boat/mangrove.png b/common/src/main/resources/assets/wildbackport/textures/entity/boat/mangrove.png new file mode 100644 index 0000000..7569bd7 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/entity/boat/mangrove.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/entity/chest_boat/acacia.png b/common/src/main/resources/assets/wildbackport/textures/entity/chest_boat/acacia.png new file mode 100644 index 0000000..77c7d1a Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/entity/chest_boat/acacia.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/entity/chest_boat/birch.png b/common/src/main/resources/assets/wildbackport/textures/entity/chest_boat/birch.png new file mode 100644 index 0000000..5045953 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/entity/chest_boat/birch.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/entity/chest_boat/dark_oak.png b/common/src/main/resources/assets/wildbackport/textures/entity/chest_boat/dark_oak.png new file mode 100644 index 0000000..71de553 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/entity/chest_boat/dark_oak.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/entity/chest_boat/jungle.png b/common/src/main/resources/assets/wildbackport/textures/entity/chest_boat/jungle.png new file mode 100644 index 0000000..7f8dd93 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/entity/chest_boat/jungle.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/entity/chest_boat/mangrove.png b/common/src/main/resources/assets/wildbackport/textures/entity/chest_boat/mangrove.png new file mode 100644 index 0000000..beff8c8 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/entity/chest_boat/mangrove.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/entity/chest_boat/oak.png b/common/src/main/resources/assets/wildbackport/textures/entity/chest_boat/oak.png new file mode 100644 index 0000000..8bf9921 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/entity/chest_boat/oak.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/entity/chest_boat/spruce.png b/common/src/main/resources/assets/wildbackport/textures/entity/chest_boat/spruce.png new file mode 100644 index 0000000..7ad7f05 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/entity/chest_boat/spruce.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/entity/frog/cold_frog.png b/common/src/main/resources/assets/wildbackport/textures/entity/frog/cold_frog.png new file mode 100644 index 0000000..b6944af Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/entity/frog/cold_frog.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/entity/frog/temperate_frog.png b/common/src/main/resources/assets/wildbackport/textures/entity/frog/temperate_frog.png new file mode 100644 index 0000000..b9634d1 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/entity/frog/temperate_frog.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/entity/frog/warm_frog.png b/common/src/main/resources/assets/wildbackport/textures/entity/frog/warm_frog.png new file mode 100644 index 0000000..adc947f Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/entity/frog/warm_frog.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/entity/signs/mangrove.png b/common/src/main/resources/assets/wildbackport/textures/entity/signs/mangrove.png new file mode 100644 index 0000000..c18ac85 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/entity/signs/mangrove.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/entity/tadpole/tadpole.png b/common/src/main/resources/assets/wildbackport/textures/entity/tadpole/tadpole.png new file mode 100644 index 0000000..f9a3f1c Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/entity/tadpole/tadpole.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/entity/warden/warden.png b/common/src/main/resources/assets/wildbackport/textures/entity/warden/warden.png new file mode 100644 index 0000000..aa6824e Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/entity/warden/warden.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/entity/warden/warden_bioluminescent_layer.png b/common/src/main/resources/assets/wildbackport/textures/entity/warden/warden_bioluminescent_layer.png new file mode 100644 index 0000000..4107777 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/entity/warden/warden_bioluminescent_layer.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/entity/warden/warden_heart.png b/common/src/main/resources/assets/wildbackport/textures/entity/warden/warden_heart.png new file mode 100644 index 0000000..4cc4491 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/entity/warden/warden_heart.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/entity/warden/warden_pulsating_spots_1.png b/common/src/main/resources/assets/wildbackport/textures/entity/warden/warden_pulsating_spots_1.png new file mode 100644 index 0000000..014c392 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/entity/warden/warden_pulsating_spots_1.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/entity/warden/warden_pulsating_spots_2.png b/common/src/main/resources/assets/wildbackport/textures/entity/warden/warden_pulsating_spots_2.png new file mode 100644 index 0000000..799b053 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/entity/warden/warden_pulsating_spots_2.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/acacia_chest_boat.png b/common/src/main/resources/assets/wildbackport/textures/item/acacia_chest_boat.png new file mode 100644 index 0000000..745f09c Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/acacia_chest_boat.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/birch_chest_boat.png b/common/src/main/resources/assets/wildbackport/textures/item/birch_chest_boat.png new file mode 100644 index 0000000..08f471a Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/birch_chest_boat.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/dark_oak_chest_boat.png b/common/src/main/resources/assets/wildbackport/textures/item/dark_oak_chest_boat.png new file mode 100644 index 0000000..6d22339 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/dark_oak_chest_boat.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/disc_fragment_5.png b/common/src/main/resources/assets/wildbackport/textures/item/disc_fragment_5.png new file mode 100644 index 0000000..575c286 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/disc_fragment_5.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/echo_shard.png b/common/src/main/resources/assets/wildbackport/textures/item/echo_shard.png new file mode 100644 index 0000000..cf11dbe Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/echo_shard.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/goat_horn.png b/common/src/main/resources/assets/wildbackport/textures/item/goat_horn.png new file mode 100644 index 0000000..b4115a4 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/goat_horn.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/jungle_chest_boat.png b/common/src/main/resources/assets/wildbackport/textures/item/jungle_chest_boat.png new file mode 100644 index 0000000..5e782d5 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/jungle_chest_boat.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/mangrove_boat.png b/common/src/main/resources/assets/wildbackport/textures/item/mangrove_boat.png new file mode 100644 index 0000000..4646587 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/mangrove_boat.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/mangrove_chest_boat.png b/common/src/main/resources/assets/wildbackport/textures/item/mangrove_chest_boat.png new file mode 100644 index 0000000..ed06d35 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/mangrove_chest_boat.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/mangrove_door.png b/common/src/main/resources/assets/wildbackport/textures/item/mangrove_door.png new file mode 100644 index 0000000..9584f14 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/mangrove_door.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/mangrove_propagule.png b/common/src/main/resources/assets/wildbackport/textures/item/mangrove_propagule.png new file mode 100644 index 0000000..6cb5802 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/mangrove_propagule.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/mangrove_sign.png b/common/src/main/resources/assets/wildbackport/textures/item/mangrove_sign.png new file mode 100644 index 0000000..3e347c2 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/mangrove_sign.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/music_disc_5.png b/common/src/main/resources/assets/wildbackport/textures/item/music_disc_5.png new file mode 100644 index 0000000..af515c0 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/music_disc_5.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/oak_chest_boat.png b/common/src/main/resources/assets/wildbackport/textures/item/oak_chest_boat.png new file mode 100644 index 0000000..50e8da4 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/oak_chest_boat.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_00.png b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_00.png new file mode 100644 index 0000000..cabc24a Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_00.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_01.png b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_01.png new file mode 100644 index 0000000..ce084bb Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_01.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_02.png b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_02.png new file mode 100644 index 0000000..d0c9575 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_02.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_03.png b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_03.png new file mode 100644 index 0000000..b2f8fdf Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_03.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_04.png b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_04.png new file mode 100644 index 0000000..64d3d4f Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_04.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_05.png b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_05.png new file mode 100644 index 0000000..c97dcc2 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_05.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_06.png b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_06.png new file mode 100644 index 0000000..9bfa3a4 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_06.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_07.png b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_07.png new file mode 100644 index 0000000..45cc65c Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_07.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_08.png b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_08.png new file mode 100644 index 0000000..f77ea1d Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_08.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_09.png b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_09.png new file mode 100644 index 0000000..59b9f79 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_09.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_10.png b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_10.png new file mode 100644 index 0000000..8e142a0 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_10.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_11.png b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_11.png new file mode 100644 index 0000000..ef6b35f Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_11.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_12.png b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_12.png new file mode 100644 index 0000000..6a07862 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_12.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_13.png b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_13.png new file mode 100644 index 0000000..c24f42d Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_13.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_14.png b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_14.png new file mode 100644 index 0000000..f7ab77d Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_14.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_15.png b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_15.png new file mode 100644 index 0000000..118c8c3 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_15.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_16.png b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_16.png new file mode 100644 index 0000000..0c7bc0c Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_16.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_17.png b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_17.png new file mode 100644 index 0000000..4eb38a4 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_17.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_18.png b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_18.png new file mode 100644 index 0000000..9daaa5b Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_18.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_19.png b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_19.png new file mode 100644 index 0000000..84f439d Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_19.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_20.png b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_20.png new file mode 100644 index 0000000..b0325e1 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_20.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_21.png b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_21.png new file mode 100644 index 0000000..5ed3429 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_21.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_22.png b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_22.png new file mode 100644 index 0000000..b01c912 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_22.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_23.png b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_23.png new file mode 100644 index 0000000..f101e35 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_23.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_24.png b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_24.png new file mode 100644 index 0000000..c288922 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_24.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_25.png b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_25.png new file mode 100644 index 0000000..48da1c5 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_25.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_26.png b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_26.png new file mode 100644 index 0000000..43cac71 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_26.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_27.png b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_27.png new file mode 100644 index 0000000..1e72091 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_27.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_28.png b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_28.png new file mode 100644 index 0000000..d395159 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_28.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_29.png b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_29.png new file mode 100644 index 0000000..1bccf7b Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_29.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_30.png b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_30.png new file mode 100644 index 0000000..d648394 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_30.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_31.png b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_31.png new file mode 100644 index 0000000..00751a8 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/recovery_compass_31.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/spruce_chest_boat.png b/common/src/main/resources/assets/wildbackport/textures/item/spruce_chest_boat.png new file mode 100644 index 0000000..969e442 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/spruce_chest_boat.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/item/tadpole_bucket.png b/common/src/main/resources/assets/wildbackport/textures/item/tadpole_bucket.png new file mode 100644 index 0000000..710ff31 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/item/tadpole_bucket.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/mob_effect/darkness.png b/common/src/main/resources/assets/wildbackport/textures/mob_effect/darkness.png new file mode 100644 index 0000000..a9ae306 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/mob_effect/darkness.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sculk_charge_0.png b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_charge_0.png new file mode 100644 index 0000000..ae59346 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_charge_0.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sculk_charge_1.png b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_charge_1.png new file mode 100644 index 0000000..e6e8981 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_charge_1.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sculk_charge_2.png b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_charge_2.png new file mode 100644 index 0000000..8617f8e Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_charge_2.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sculk_charge_3.png b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_charge_3.png new file mode 100644 index 0000000..6cbfb6a Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_charge_3.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sculk_charge_4.png b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_charge_4.png new file mode 100644 index 0000000..b4807a5 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_charge_4.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sculk_charge_5.png b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_charge_5.png new file mode 100644 index 0000000..014b23e Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_charge_5.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sculk_charge_6.png b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_charge_6.png new file mode 100644 index 0000000..6911ff7 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_charge_6.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sculk_charge_pop_0.png b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_charge_pop_0.png new file mode 100644 index 0000000..52daaf0 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_charge_pop_0.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sculk_charge_pop_1.png b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_charge_pop_1.png new file mode 100644 index 0000000..f3d1bb3 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_charge_pop_1.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sculk_charge_pop_2.png b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_charge_pop_2.png new file mode 100644 index 0000000..f3e46d5 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_charge_pop_2.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sculk_charge_pop_3.png b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_charge_pop_3.png new file mode 100644 index 0000000..243b14f Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_charge_pop_3.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sculk_soul_0.png b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_soul_0.png new file mode 100644 index 0000000..0bbb8a0 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_soul_0.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sculk_soul_1.png b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_soul_1.png new file mode 100644 index 0000000..557a172 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_soul_1.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sculk_soul_10.png b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_soul_10.png new file mode 100644 index 0000000..032cb3b Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_soul_10.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sculk_soul_2.png b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_soul_2.png new file mode 100644 index 0000000..c6453b1 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_soul_2.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sculk_soul_3.png b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_soul_3.png new file mode 100644 index 0000000..385f206 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_soul_3.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sculk_soul_4.png b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_soul_4.png new file mode 100644 index 0000000..e7d29d6 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_soul_4.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sculk_soul_5.png b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_soul_5.png new file mode 100644 index 0000000..954d315 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_soul_5.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sculk_soul_6.png b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_soul_6.png new file mode 100644 index 0000000..7ce8be9 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_soul_6.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sculk_soul_7.png b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_soul_7.png new file mode 100644 index 0000000..6e75f80 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_soul_7.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sculk_soul_8.png b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_soul_8.png new file mode 100644 index 0000000..0bd82b7 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_soul_8.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sculk_soul_9.png b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_soul_9.png new file mode 100644 index 0000000..25f8a1d Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sculk_soul_9.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/shriek.png b/common/src/main/resources/assets/wildbackport/textures/particle/shriek.png new file mode 100644 index 0000000..1d89514 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/shriek.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_0.png b/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_0.png new file mode 100644 index 0000000..7ef771e Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_0.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_1.png b/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_1.png new file mode 100644 index 0000000..3a09efc Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_1.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_10.png b/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_10.png new file mode 100644 index 0000000..43eb648 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_10.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_11.png b/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_11.png new file mode 100644 index 0000000..48a371b Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_11.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_12.png b/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_12.png new file mode 100644 index 0000000..2bef1ef Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_12.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_13.png b/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_13.png new file mode 100644 index 0000000..72ac5b5 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_13.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_14.png b/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_14.png new file mode 100644 index 0000000..e7e9151 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_14.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_15.png b/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_15.png new file mode 100644 index 0000000..7780b59 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_15.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_2.png b/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_2.png new file mode 100644 index 0000000..1347ffe Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_2.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_3.png b/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_3.png new file mode 100644 index 0000000..a0675dc Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_3.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_4.png b/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_4.png new file mode 100644 index 0000000..ef11a42 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_4.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_5.png b/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_5.png new file mode 100644 index 0000000..445007b Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_5.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_6.png b/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_6.png new file mode 100644 index 0000000..24acd2a Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_6.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_7.png b/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_7.png new file mode 100644 index 0000000..0eea70b Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_7.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_8.png b/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_8.png new file mode 100644 index 0000000..6eb28ae Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_8.png differ diff --git a/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_9.png b/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_9.png new file mode 100644 index 0000000..5ec6688 Binary files /dev/null and b/common/src/main/resources/assets/wildbackport/textures/particle/sonic_boom_9.png differ diff --git a/common/src/main/resources/data/minecraft/tags/blocks/dirt.json b/common/src/main/resources/data/minecraft/tags/blocks/dirt.json new file mode 100644 index 0000000..353ed7e --- /dev/null +++ b/common/src/main/resources/data/minecraft/tags/blocks/dirt.json @@ -0,0 +1,7 @@ +{ + "replace": false, + "values": [ + "wildbackport:mud", + "wildbackport:muddy_mangrove_roots" + ] +} \ No newline at end of file diff --git a/common/src/main/resources/data/minecraft/tags/blocks/flower_pots.json b/common/src/main/resources/data/minecraft/tags/blocks/flower_pots.json new file mode 100644 index 0000000..9cb8fb2 --- /dev/null +++ b/common/src/main/resources/data/minecraft/tags/blocks/flower_pots.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "wildbackport:potted_mangrove_propagule" + ] +} \ No newline at end of file diff --git a/common/src/main/resources/data/minecraft/tags/blocks/snow_layer_can_survive_on.json b/common/src/main/resources/data/minecraft/tags/blocks/snow_layer_can_survive_on.json new file mode 100644 index 0000000..0bdc8fc --- /dev/null +++ b/common/src/main/resources/data/minecraft/tags/blocks/snow_layer_can_survive_on.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "wildbackport:mud" + ] +} \ No newline at end of file diff --git a/common/src/main/resources/data/minecraft/tags/game_events/vibrations.json b/common/src/main/resources/data/minecraft/tags/game_events/vibrations.json new file mode 100644 index 0000000..9c11d7f --- /dev/null +++ b/common/src/main/resources/data/minecraft/tags/game_events/vibrations.json @@ -0,0 +1,8 @@ +{ + "replace": false, + "values": [ + "wildbackport:entity_die", + "wildbackport:instrument_play", + "wildbackport:note_block_play" + ] +} \ No newline at end of file diff --git a/common/src/main/resources/data/wildbackport/structures/feature_cage_with_allays.nbt b/common/src/main/resources/data/wildbackport/structures/feature_cage_with_allays.nbt new file mode 100644 index 0000000..b50a319 Binary files /dev/null and b/common/src/main/resources/data/wildbackport/structures/feature_cage_with_allays.nbt differ diff --git a/common/src/main/resources/data/wildbackport/structures/pillager_outpost/feature_cage_with_allays.nbt b/common/src/main/resources/data/wildbackport/structures/pillager_outpost/feature_cage_with_allays.nbt new file mode 100644 index 0000000..b50a319 Binary files /dev/null and b/common/src/main/resources/data/wildbackport/structures/pillager_outpost/feature_cage_with_allays.nbt differ diff --git a/common/src/main/resources/data/wildbackport/tags/blocks/frog_prefer_jump_to.json b/common/src/main/resources/data/wildbackport/tags/blocks/frog_prefer_jump_to.json new file mode 100644 index 0000000..cb7253b --- /dev/null +++ b/common/src/main/resources/data/wildbackport/tags/blocks/frog_prefer_jump_to.json @@ -0,0 +1,7 @@ +{ + "replace": false, + "values": [ + "minecraft:lily_pad", + "minecraft:big_dripleaf" + ] +} \ No newline at end of file diff --git a/common/src/main/resources/data/wildbackport/tags/blocks/sculk_replaceable.json b/common/src/main/resources/data/wildbackport/tags/blocks/sculk_replaceable.json new file mode 100644 index 0000000..02855de --- /dev/null +++ b/common/src/main/resources/data/wildbackport/tags/blocks/sculk_replaceable.json @@ -0,0 +1,21 @@ +{ + "replace": false, + "values": [ + "#minecraft:base_stone_overworld", + "#minecraft:dirt", + "#minecraft:terracotta", + "#minecraft:nylium", + "#minecraft:base_stone_nether", + "#minecraft:sand", + "minecraft:gravel", + "minecraft:soul_sand", + "minecraft:soul_soil", + "minecraft:calcite", + "minecraft:smooth_basalt", + "minecraft:clay", + "minecraft:dripstone_block", + "minecraft:end_stone", + "minecraft:red_sandstone", + "minecraft:sandstone" + ] +} \ No newline at end of file diff --git a/common/src/main/resources/data/wildbackport/tags/blocks/sculk_replaceable_world_gen.json b/common/src/main/resources/data/wildbackport/tags/blocks/sculk_replaceable_world_gen.json new file mode 100644 index 0000000..dc8fc38 --- /dev/null +++ b/common/src/main/resources/data/wildbackport/tags/blocks/sculk_replaceable_world_gen.json @@ -0,0 +1,11 @@ +{ + "replace": false, + "values": [ + "#wildbackport:sculk_replaceable", + "minecraft:deepslate_bricks", + "minecraft:deepslate_tiles", + "minecraft:cobbled_deepslate", + "minecraft:cracked_deepslate_bricks", + "minecraft:cracked_deepslate_tiles" + ] +} \ No newline at end of file diff --git a/common/src/main/resources/data/wildbackport/tags/entity_types/frog_food.json b/common/src/main/resources/data/wildbackport/tags/entity_types/frog_food.json new file mode 100644 index 0000000..92a9813 --- /dev/null +++ b/common/src/main/resources/data/wildbackport/tags/entity_types/frog_food.json @@ -0,0 +1,7 @@ +{ + "replace": false, + "values": [ + "minecraft:slime", + "minecraft:magma_cube" + ] +} \ No newline at end of file diff --git a/common/src/main/resources/data/wildbackport/tags/game_events/allay_can_listen.json b/common/src/main/resources/data/wildbackport/tags/game_events/allay_can_listen.json new file mode 100644 index 0000000..2d9d383 --- /dev/null +++ b/common/src/main/resources/data/wildbackport/tags/game_events/allay_can_listen.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "wildbackport:note_block_play" + ] +} \ No newline at end of file diff --git a/common/src/main/resources/data/wildbackport/tags/game_events/shrieker_can_listen.json b/common/src/main/resources/data/wildbackport/tags/game_events/shrieker_can_listen.json new file mode 100644 index 0000000..50c0ca2 --- /dev/null +++ b/common/src/main/resources/data/wildbackport/tags/game_events/shrieker_can_listen.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "wildbackport:sculk_sensor_tendrils_clicking" + ] +} \ No newline at end of file diff --git a/common/src/main/resources/data/wildbackport/tags/game_events/warden_can_listen.json b/common/src/main/resources/data/wildbackport/tags/game_events/warden_can_listen.json new file mode 100644 index 0000000..060a97e --- /dev/null +++ b/common/src/main/resources/data/wildbackport/tags/game_events/warden_can_listen.json @@ -0,0 +1,35 @@ +{ + "replace": false, + "values": [ + "minecraft:block_attach", + "minecraft:block_change", + "minecraft:block_close", + "minecraft:block_destroy", + "minecraft:block_detach", + "minecraft:block_open", + "minecraft:block_place", + "minecraft:container_close", + "minecraft:container_open", + "minecraft:dispense_fail", + "wildbackport:entity_die", + "minecraft:equip", + "minecraft:explode", + "minecraft:fluid_pickup", + "minecraft:fluid_place", + "minecraft:hit_ground", + "wildbackport:instrument_play", + "minecraft:lightning_strike", + "wildbackport:note_block_play", + "minecraft:piston_contract", + "minecraft:piston_extend", + "minecraft:prime_fuse", + "minecraft:projectile_land", + "minecraft:projectile_shoot", + "minecraft:shear", + "minecraft:splash", + "minecraft:step", + "minecraft:swim", + "wildbackport:shriek", + "#wildbackport:shrieker_can_listen" + ] +} \ No newline at end of file diff --git a/common/src/main/resources/data/wildbackport/tags/worldgen/biome/spawns_cold_variant_frogs.json b/common/src/main/resources/data/wildbackport/tags/worldgen/biome/spawns_cold_variant_frogs.json new file mode 100644 index 0000000..ca85473 --- /dev/null +++ b/common/src/main/resources/data/wildbackport/tags/worldgen/biome/spawns_cold_variant_frogs.json @@ -0,0 +1,21 @@ +{ + "replace": false, + "values": [ + "minecraft:snowy_plains", + "minecraft:ice_spikes", + "minecraft:frozen_peaks", + "minecraft:jagged_peaks", + "minecraft:snowy_slopes", + "minecraft:frozen_ocean", + "minecraft:deep_frozen_ocean", + "minecraft:grove", + "wildbackport:deep_dark", + "minecraft:frozen_river", + "minecraft:snowy_taiga", + "minecraft:snowy_beach", + "minecraft:the_end", + "minecraft:small_end_islands", + "minecraft:end_barrens", + "#minecraft:has_structure/end_city" + ] +} \ No newline at end of file diff --git a/common/src/main/resources/data/wildbackport/tags/worldgen/biome/spawns_warm_variant_frogs.json b/common/src/main/resources/data/wildbackport/tags/worldgen/biome/spawns_warm_variant_frogs.json new file mode 100644 index 0000000..12d7a6d --- /dev/null +++ b/common/src/main/resources/data/wildbackport/tags/worldgen/biome/spawns_warm_variant_frogs.json @@ -0,0 +1,14 @@ +{ + "replace": false, + "values": [ + "minecraft:desert", + "minecraft:warm_ocean", + "#minecraft:is_jungle", + "#minecraft:has_structure/village_savanna", + "minecraft:savanna_plateau", + "minecraft:windswept_savanna", + "#minecraft:is_nether", + "#minecraft:is_badlands", + "wildbackport:mangrove_swamp" + ] +} \ No newline at end of file diff --git a/common/src/main/resources/wildbackport-common.mixins.json b/common/src/main/resources/wildbackport-common.mixins.json new file mode 100644 index 0000000..fa40c6a --- /dev/null +++ b/common/src/main/resources/wildbackport-common.mixins.json @@ -0,0 +1,41 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "com.cursedcauldron.wildbackport.core.mixin", + "compatibilityLevel": "JAVA_17", + "mixins": [ + "access.ActivityAccessor", + "access.CriteriaTriggersAccessor", + "access.DamageSourceAccessor", + "access.DoorBlockAccessor", + "access.MemoryModuleTypeAccessor", + "access.ModelPartAccessor", + "access.PressurePlateBlockAccessor", + "access.RecordItemAccessor", + "access.SensorTypeAccessor", + "access.SheetsAccessor", + "access.SimpleParticleTypeAccessor", + "access.StairBlockAccessor", + "access.StructureTemplatePoolAccessor", + "access.TrapDoorBlockAccessor", + "access.WoodButtonBlockAccessor", + "access.WoodTypeAccessor", + "common.BeardifierMixin", + "common.BlockEntityTypeMixin", + "common.LivingEntityMixin", + "common.PlayerMixin", + "extension.BoatTypeMixin", + "extension.PoseMixin", + "network.ServerGamePacketListenerImplMixin" + ], + "client": [ + "client.LocalPlayerMixin", + "client.ModelPartMixin", + "client.PartDefinitionMixin", + "network.ClientPacketListenerMixin", + "network.MultiPlayerGameModeMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/common/src/main/resources/wildbackport.accesswidener b/common/src/main/resources/wildbackport.accesswidener new file mode 100644 index 0000000..7e49688 --- /dev/null +++ b/common/src/main/resources/wildbackport.accesswidener @@ -0,0 +1,8 @@ +accessWidener v2 named + +transitive-accessible class net/minecraft/world/level/block/entity/BlockEntityType$BlockEntitySupplier +transitive-accessible class net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement$Placer +transitive-accessible class net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement$PieceState + +transitive-accessible method net/minecraft/client/particle/HugeExplosionParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDLnet/minecraft/client/particle/SpriteSet;)V +transitive-accessible method net/minecraft/world/level/block/MultifaceBlock hasFace (Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/Direction;)Z \ No newline at end of file diff --git a/fabric/build.gradle b/fabric/build.gradle new file mode 100644 index 0000000..208dc4f --- /dev/null +++ b/fabric/build.gradle @@ -0,0 +1,75 @@ +plugins { + id "com.github.johnrengelman.shadow" version "7.1.2" +} + +architectury { + platformSetupLoomIde() + fabric() +} + +configurations { + common + shadowCommon // Don't use shadow from the shadow plugin because we don't want IDEA to index this. + compileClasspath.extendsFrom common + runtimeClasspath.extendsFrom common + developmentFabric.extendsFrom common +} + +dependencies { + modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" + modApi "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}" + + common(project(path: ":common", configuration: "namedElements")) { transitive false } + shadowCommon(project(path: ":common", configuration: "transformProductionFabric")) { transitive false } +} + +processResources { + inputs.property "version", project.version + + filesMatching("fabric.mod.json") { + expand "version": project.version + } +} + +shadowJar { + exclude "architectury.common.json" + + configurations = [project.configurations.shadowCommon] + classifier "dev-shadow" +} + +remapJar { + input.set shadowJar.archiveFile + dependsOn shadowJar + classifier null +} + +jar { + classifier "dev" +} + +sourcesJar { + def commonSources = project(":common").sourcesJar + dependsOn commonSources + from commonSources.archiveFile.map { zipTree(it) } +} + +components.java { + withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) { + skip() + } +} + +publishing { + publications { + mavenFabric(MavenPublication) { + artifactId = rootProject.archives_base_name + "-" + project.name + from components.java + } + } + + // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. + repositories { + // Add repositories to publish to here. + } +} \ No newline at end of file diff --git a/fabric/src/main/java/com/cursedcauldron/wildbackport/common/registry/fabric/WBItemsImpl.java b/fabric/src/main/java/com/cursedcauldron/wildbackport/common/registry/fabric/WBItemsImpl.java new file mode 100644 index 0000000..0fdffb2 --- /dev/null +++ b/fabric/src/main/java/com/cursedcauldron/wildbackport/common/registry/fabric/WBItemsImpl.java @@ -0,0 +1,17 @@ +package com.cursedcauldron.wildbackport.common.registry.fabric; + +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.SpawnEggItem; + +import java.util.function.Supplier; + +//<> + +public class WBItemsImpl { + public static Supplier spawnEgg(Supplier> mob, int background, int highlight) { + return () -> new SpawnEggItem(mob.get(), background, highlight, new Item.Properties().tab(CreativeModeTab.TAB_MISC)); + } +} \ No newline at end of file diff --git a/fabric/src/main/java/com/cursedcauldron/wildbackport/core/api/fabric/ColorRegistryImpl.java b/fabric/src/main/java/com/cursedcauldron/wildbackport/core/api/fabric/ColorRegistryImpl.java new file mode 100644 index 0000000..6e08344 --- /dev/null +++ b/fabric/src/main/java/com/cursedcauldron/wildbackport/core/api/fabric/ColorRegistryImpl.java @@ -0,0 +1,25 @@ +package com.cursedcauldron.wildbackport.core.api.fabric; + +import net.fabricmc.fabric.api.client.rendering.v1.ColorProviderRegistry; +import net.minecraft.client.color.block.BlockColor; +import net.minecraft.client.color.item.ItemColor; +import net.minecraft.world.level.ItemLike; +import net.minecraft.world.level.block.Block; + +import java.util.function.Supplier; + +public class ColorRegistryImpl { + @SafeVarargs + public static void register(ItemColor itemColor, Supplier... items) { + for (Supplier item : items) { + ColorProviderRegistry.ITEM.register(itemColor, item.get()); + } + } + + @SafeVarargs + public static void register(BlockColor blockColor, Supplier... blocks) { + for (Supplier block : blocks) { + ColorProviderRegistry.BLOCK.register(blockColor, block.get()); + } + } +} \ No newline at end of file diff --git a/fabric/src/main/java/com/cursedcauldron/wildbackport/core/api/fabric/CoreRegistryImpl.java b/fabric/src/main/java/com/cursedcauldron/wildbackport/core/api/fabric/CoreRegistryImpl.java new file mode 100644 index 0000000..a41ec34 --- /dev/null +++ b/fabric/src/main/java/com/cursedcauldron/wildbackport/core/api/fabric/CoreRegistryImpl.java @@ -0,0 +1,10 @@ +package com.cursedcauldron.wildbackport.core.api.fabric; + +import com.cursedcauldron.wildbackport.core.api.CoreRegistry; +import net.minecraft.core.Registry; + +public class CoreRegistryImpl { + public static CoreRegistry create(Registry key, String modId) { + return new CoreRegistry.DefaultRegistry<>(key, modId); + } +} \ No newline at end of file diff --git a/fabric/src/main/java/com/cursedcauldron/wildbackport/core/api/fabric/MobRegistryImpl.java b/fabric/src/main/java/com/cursedcauldron/wildbackport/core/api/fabric/MobRegistryImpl.java new file mode 100644 index 0000000..da5ccf9 --- /dev/null +++ b/fabric/src/main/java/com/cursedcauldron/wildbackport/core/api/fabric/MobRegistryImpl.java @@ -0,0 +1,15 @@ +package com.cursedcauldron.wildbackport.core.api.fabric; + +import net.fabricmc.fabric.api.object.builder.v1.entity.FabricDefaultAttributeRegistry; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.attributes.AttributeSupplier; + +import java.util.function.Supplier; + +public class MobRegistryImpl { + @SuppressWarnings("ConstantConditions") + public static void registerAttributes(Supplier> type, Supplier builder) { + FabricDefaultAttributeRegistry.register(type.get(), builder.get()); + } +} diff --git a/fabric/src/main/java/com/cursedcauldron/wildbackport/core/api/fabric/ParticleRegistryImpl.java b/fabric/src/main/java/com/cursedcauldron/wildbackport/core/api/fabric/ParticleRegistryImpl.java new file mode 100644 index 0000000..1ea8699 --- /dev/null +++ b/fabric/src/main/java/com/cursedcauldron/wildbackport/core/api/fabric/ParticleRegistryImpl.java @@ -0,0 +1,19 @@ +package com.cursedcauldron.wildbackport.core.api.fabric; + +import com.cursedcauldron.wildbackport.core.api.ParticleRegistry; +import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry; +import net.minecraft.client.particle.ParticleProvider; +import net.minecraft.core.particles.ParticleOptions; +import net.minecraft.core.particles.ParticleType; + +import java.util.function.Supplier; + +public class ParticleRegistryImpl { + public static > void create(Supplier

type, ParticleProvider provider) { + ParticleFactoryRegistry.getInstance().register(type.get(), provider); + } + + public static > void create(Supplier

type, ParticleRegistry.Factory factory) { + ParticleFactoryRegistry.getInstance().register(type.get(), factory::create); + } +} \ No newline at end of file diff --git a/fabric/src/main/java/com/cursedcauldron/wildbackport/core/api/fabric/RenderRegistryImpl.java b/fabric/src/main/java/com/cursedcauldron/wildbackport/core/api/fabric/RenderRegistryImpl.java new file mode 100644 index 0000000..5c4190e --- /dev/null +++ b/fabric/src/main/java/com/cursedcauldron/wildbackport/core/api/fabric/RenderRegistryImpl.java @@ -0,0 +1,36 @@ +package com.cursedcauldron.wildbackport.core.api.fabric; + +import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap; +import net.fabricmc.fabric.api.client.rendering.v1.BlockEntityRendererRegistry; +import net.fabricmc.fabric.api.client.rendering.v1.EntityModelLayerRegistry; +import net.fabricmc.fabric.api.client.rendering.v1.EntityRendererRegistry; +import net.minecraft.client.model.geom.ModelLayerLocation; +import net.minecraft.client.model.geom.builders.LayerDefinition; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; + +import java.util.function.Supplier; + +public class RenderRegistryImpl { + public static void setBlockRenderType(RenderType type, Block... blocks) { + BlockRenderLayerMap.INSTANCE.putBlocks(type, blocks); + } + + public static void setEntityRender(Supplier> type, EntityRendererProvider provider) { + EntityRendererRegistry.register(type.get(), provider); + } + + public static void setLayerDefinition(ModelLayerLocation layer, Supplier definition) { + EntityModelLayerRegistry.registerModelLayer(layer, definition::get); + } + + public static void setBlockEntityRender(Supplier> type, BlockEntityRendererProvider provider) { + BlockEntityRendererRegistry.register(type.get(), provider); + } +} diff --git a/fabric/src/main/java/com/cursedcauldron/wildbackport/core/api/fabric/WoodTypeRegistryImpl.java b/fabric/src/main/java/com/cursedcauldron/wildbackport/core/api/fabric/WoodTypeRegistryImpl.java new file mode 100644 index 0000000..c042f89 --- /dev/null +++ b/fabric/src/main/java/com/cursedcauldron/wildbackport/core/api/fabric/WoodTypeRegistryImpl.java @@ -0,0 +1,30 @@ +package com.cursedcauldron.wildbackport.core.api.fabric; + +import com.cursedcauldron.wildbackport.core.mixin.access.SheetsAccessor; +import com.cursedcauldron.wildbackport.core.mixin.access.WoodTypeAccessor; +import net.fabricmc.api.EnvType; +import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.client.renderer.Sheets; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.block.state.properties.WoodType; + +public class WoodTypeRegistryImpl { + public static WoodType create(ResourceLocation location) { + WoodType woodType = WoodTypeAccessor.callRegister(new WoodTypeImpl(location)); + if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) Sheets.SIGN_MATERIALS.put(woodType, SheetsAccessor.callCreateSignMaterial(woodType)); + return woodType; + } + + public static class WoodTypeImpl extends WoodType { + private final ResourceLocation location; + + private WoodTypeImpl(ResourceLocation location) { + super(location.getPath()); + this.location = location; + } + + public ResourceLocation getLocation() { + return this.location; + } + } +} \ No newline at end of file diff --git a/fabric/src/main/java/com/cursedcauldron/wildbackport/core/mixin/fabric/client/SheetsMixin.java b/fabric/src/main/java/com/cursedcauldron/wildbackport/core/mixin/fabric/client/SheetsMixin.java new file mode 100644 index 0000000..a40adfa --- /dev/null +++ b/fabric/src/main/java/com/cursedcauldron/wildbackport/core/mixin/fabric/client/SheetsMixin.java @@ -0,0 +1,22 @@ +package com.cursedcauldron.wildbackport.core.mixin.fabric.client; + +import com.cursedcauldron.wildbackport.core.api.fabric.WoodTypeRegistryImpl; +import net.minecraft.client.renderer.Sheets; +import net.minecraft.client.resources.model.Material; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.block.state.properties.WoodType; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(Sheets.class) +public class SheetsMixin { + @Inject(method = "createSignMaterial", at = @At("HEAD"), cancellable = true) + private static void wb$createSign(WoodType woodType, CallbackInfoReturnable cir) { + if (woodType instanceof WoodTypeRegistryImpl.WoodTypeImpl impl) { + ResourceLocation location = impl.getLocation(); + cir.setReturnValue(new Material(Sheets.SIGN_SHEET, new ResourceLocation(location.getNamespace(), "entity/signs/" + location.getPath()))); + } + } +} \ No newline at end of file diff --git a/fabric/src/main/java/com/cursedcauldron/wildbackport/fabric/WildBackportFabric.java b/fabric/src/main/java/com/cursedcauldron/wildbackport/fabric/WildBackportFabric.java new file mode 100644 index 0000000..5d01b6c --- /dev/null +++ b/fabric/src/main/java/com/cursedcauldron/wildbackport/fabric/WildBackportFabric.java @@ -0,0 +1,13 @@ +package com.cursedcauldron.wildbackport.fabric; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.common.CommonSetup; +import net.fabricmc.api.ModInitializer; + +public class WildBackportFabric implements ModInitializer { + @Override + public void onInitialize() { + WildBackport.bootstrap(); + CommonSetup.onCommon(); + } +} \ No newline at end of file diff --git a/fabric/src/main/java/com/cursedcauldron/wildbackport/fabric/WildBackportFabricClient.java b/fabric/src/main/java/com/cursedcauldron/wildbackport/fabric/WildBackportFabricClient.java new file mode 100644 index 0000000..0d334b9 --- /dev/null +++ b/fabric/src/main/java/com/cursedcauldron/wildbackport/fabric/WildBackportFabricClient.java @@ -0,0 +1,12 @@ +package com.cursedcauldron.wildbackport.fabric; + +import com.cursedcauldron.wildbackport.client.ClientSetup; +import net.fabricmc.api.ClientModInitializer; + +public class WildBackportFabricClient implements ClientModInitializer { + @Override + public void onInitializeClient() { + ClientSetup.onClient(); + ClientSetup.onPostClient(); + } +} \ No newline at end of file diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json new file mode 100644 index 0000000..5f95c5f --- /dev/null +++ b/fabric/src/main/resources/fabric.mod.json @@ -0,0 +1,32 @@ +{ + "schemaVersion": 1, + "id": "wildbackport", + "version": "${version}", + "name": "Wildbackport", + "description": "a mod that backports the features from the wild update", + "authors": [ + "BlackGear", + "Orcinus", + "Dopadream" + ], + "contact": {}, + "license": "All-Rights-Reserved", + "icon": "icon.png", + "environment": "*", + "entrypoints": { + "main": [ + "com.cursedcauldron.wildbackport.fabric.WildBackportFabric" + ], + "client": [ + "com.cursedcauldron.wildbackport.fabric.WildBackportFabricClient" + ] + }, + "mixins": [ + "wildbackport.mixins.json", + "wildbackport-common.mixins.json" + ], + "depends": { + "fabricloader": ">=0.14.8", + "minecraft": ">=1.18.2" + } +} diff --git a/fabric/src/main/resources/wildbackport.accesswidener b/fabric/src/main/resources/wildbackport.accesswidener new file mode 100644 index 0000000..7e49688 --- /dev/null +++ b/fabric/src/main/resources/wildbackport.accesswidener @@ -0,0 +1,8 @@ +accessWidener v2 named + +transitive-accessible class net/minecraft/world/level/block/entity/BlockEntityType$BlockEntitySupplier +transitive-accessible class net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement$Placer +transitive-accessible class net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement$PieceState + +transitive-accessible method net/minecraft/client/particle/HugeExplosionParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDLnet/minecraft/client/particle/SpriteSet;)V +transitive-accessible method net/minecraft/world/level/block/MultifaceBlock hasFace (Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/Direction;)Z \ No newline at end of file diff --git a/fabric/src/main/resources/wildbackport.mixins.json b/fabric/src/main/resources/wildbackport.mixins.json new file mode 100644 index 0000000..8cd6dd5 --- /dev/null +++ b/fabric/src/main/resources/wildbackport.mixins.json @@ -0,0 +1,14 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "com.cursedcauldron.wildbackport.core.mixin.fabric", + "compatibilityLevel": "JAVA_17", + "mixins": [ + ], + "client": [ + "client.SheetsMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/forge/build.gradle b/forge/build.gradle new file mode 100644 index 0000000..e6a44b3 --- /dev/null +++ b/forge/build.gradle @@ -0,0 +1,84 @@ +plugins { + id "com.github.johnrengelman.shadow" version "7.1.2" +} + +loom { + accessWidenerPath = project(":common").loom.accessWidenerPath + + forge { + convertAccessWideners = true + extraAccessWideners.add loom.accessWidenerPath.get().asFile.name + } +} + +architectury { + platformSetupLoomIde() + forge() +} + +configurations { + common + shadowCommon // Don't use shadow from the shadow plugin because we don't want IDEA to index this. + compileClasspath.extendsFrom common + runtimeClasspath.extendsFrom common + developmentForge.extendsFrom common +} + +dependencies { + forge "net.minecraftforge:forge:${rootProject.forge_version}" + + common(project(path: ":common", configuration: "namedElements")) { transitive false } + shadowCommon(project(path: ":common", configuration: "transformProductionForge")) { transitive = false } +} + +processResources { + inputs.property "version", project.version + + filesMatching("META-INF/mods.toml") { + expand "version": project.version + } +} + +shadowJar { + exclude "fabric.mod.json" + exclude "architectury.common.json" + + configurations = [project.configurations.shadowCommon] + classifier "dev-shadow" +} + +remapJar { + input.set shadowJar.archiveFile + dependsOn shadowJar + classifier null +} + +jar { + classifier "dev" +} + +sourcesJar { + def commonSources = project(":common").sourcesJar + dependsOn commonSources + from commonSources.archiveFile.map { zipTree(it) } +} + +components.java { + withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) { + skip() + } +} + +publishing { + publications { + mavenForge(MavenPublication) { + artifactId = rootProject.archives_base_name + "-" + project.name + from components.java + } + } + + // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. + repositories { + // Add repositories to publish to here. + } +} \ No newline at end of file diff --git a/forge/gradle.properties b/forge/gradle.properties new file mode 100644 index 0000000..32f842a --- /dev/null +++ b/forge/gradle.properties @@ -0,0 +1 @@ +loom.platform=forge \ No newline at end of file diff --git a/forge/src/main/java/com/cursedcauldron/wildbackport/common/registry/forge/WBItemsImpl.java b/forge/src/main/java/com/cursedcauldron/wildbackport/common/registry/forge/WBItemsImpl.java new file mode 100644 index 0000000..4282cd3 --- /dev/null +++ b/forge/src/main/java/com/cursedcauldron/wildbackport/common/registry/forge/WBItemsImpl.java @@ -0,0 +1,17 @@ +package com.cursedcauldron.wildbackport.common.registry.forge; + +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.Item; +import net.minecraftforge.common.ForgeSpawnEggItem; + +import java.util.function.Supplier; + +//<> + +public class WBItemsImpl { + public static Supplier spawnEgg(Supplier> mob, int background, int highlight) { + return () -> new ForgeSpawnEggItem(mob, background, highlight, new Item.Properties().tab(CreativeModeTab.TAB_MISC)); + } +} diff --git a/forge/src/main/java/com/cursedcauldron/wildbackport/core/api/forge/ColorRegistryImpl.java b/forge/src/main/java/com/cursedcauldron/wildbackport/core/api/forge/ColorRegistryImpl.java new file mode 100644 index 0000000..dce5612 --- /dev/null +++ b/forge/src/main/java/com/cursedcauldron/wildbackport/core/api/forge/ColorRegistryImpl.java @@ -0,0 +1,50 @@ +package com.cursedcauldron.wildbackport.core.api.forge; + +import com.cursedcauldron.wildbackport.WildBackport; +import net.minecraft.client.color.block.BlockColor; +import net.minecraft.client.color.item.ItemColor; +import net.minecraft.world.level.ItemLike; +import net.minecraft.world.level.block.Block; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.client.event.ColorHandlerEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; + +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Consumer; +import java.util.function.Supplier; + +@Mod.EventBusSubscriber(modid = WildBackport.MOD_ID, value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.MOD) +public class ColorRegistryImpl { + private static final Set> ITEM_COLORS = ConcurrentHashMap.newKeySet(); + private static final Set> BLOCK_COLORS = ConcurrentHashMap.newKeySet(); + + @SafeVarargs + public static void register(ItemColor itemColor, Supplier... items) { + ITEM_COLORS.add(event -> { + for (Supplier item : items) { + event.getItemColors().register(itemColor, item.get()); + } + }); + } + + @SafeVarargs + public static void register(BlockColor blockColor, Supplier... blocks) { + BLOCK_COLORS.add(event -> { + for (Supplier block : blocks) { + event.getBlockColors().register(blockColor, block.get()); + } + }); + } + + @SubscribeEvent + public static void onEvent(ColorHandlerEvent.Item event) { + ITEM_COLORS.forEach(consumer -> consumer.accept(event)); + } + + @SubscribeEvent + public static void onEvent(ColorHandlerEvent.Block event) { + BLOCK_COLORS.forEach(consumer -> consumer.accept(event)); + } +} \ No newline at end of file diff --git a/forge/src/main/java/com/cursedcauldron/wildbackport/core/api/forge/CoreRegistryImpl.java b/forge/src/main/java/com/cursedcauldron/wildbackport/core/api/forge/CoreRegistryImpl.java new file mode 100644 index 0000000..b63ba4d --- /dev/null +++ b/forge/src/main/java/com/cursedcauldron/wildbackport/core/api/forge/CoreRegistryImpl.java @@ -0,0 +1,34 @@ +package com.cursedcauldron.wildbackport.core.api.forge; + +import com.cursedcauldron.wildbackport.core.api.CoreRegistry; +import net.minecraft.core.Registry; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.IForgeRegistryEntry; + +import java.util.function.Supplier; + +public class CoreRegistryImpl> extends CoreRegistry { + private final DeferredRegister registry; + + public CoreRegistryImpl(Registry registry, String modId) { + super(registry, modId); + this.registry = DeferredRegister.create(registry.key(), modId); + } + + @SuppressWarnings("all") + public static CoreRegistry create(Registry key, String modId) { + return new CoreRegistryImpl(key, modId); + } + + @Override + public Supplier register(String key, Supplier entry) { + return this.registry.register(key, entry); + } + + @Override + public void bootstrap() { + IEventBus bus = EventBuses.getModEventBus(this.modId).orElseThrow(() -> new IllegalStateException("Attempted to register stuff before registering a Mod Event Bus for: " + this.modId)); + this.registry.register(bus); + } +} \ No newline at end of file diff --git a/forge/src/main/java/com/cursedcauldron/wildbackport/core/api/forge/EventBuses.java b/forge/src/main/java/com/cursedcauldron/wildbackport/core/api/forge/EventBuses.java new file mode 100644 index 0000000..36404f6 --- /dev/null +++ b/forge/src/main/java/com/cursedcauldron/wildbackport/core/api/forge/EventBuses.java @@ -0,0 +1,44 @@ +package com.cursedcauldron.wildbackport.core.api.forge; + +import net.minecraftforge.eventbus.api.IEventBus; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.Consumer; + +//<> + +public class EventBuses { + private static final HashMap MOD_EVENT_BUSES = new HashMap<>(); + private static final Map>> ON_REGISTERED = new HashMap<>(); + + public static void registerModEventBus(String modId, IEventBus bus) { + IEventBus previousBus = MOD_EVENT_BUSES.put(modId, bus); + if (previousBus != null) { + throw new IllegalStateException("Attempted to register a mod event bus for modid '" + modId + "' twice."); + } + } + + public static void onRegistered(String modId, Consumer busConsumer) { + if (MOD_EVENT_BUSES.containsKey(modId)) { + busConsumer.accept(MOD_EVENT_BUSES.get(modId)); + } else { + synchronized (ON_REGISTERED) { + ON_REGISTERED.computeIfAbsent(modId, s -> new ArrayList<>()).add(busConsumer); + } + } + } + + public static Optional getModEventBus(String modId) { + return Optional.ofNullable(MOD_EVENT_BUSES.get(modId)); + } + + public static IEventBus getModEventBusOrThrow(String modId) { + return getModEventBus(modId).orElseThrow( + () -> new IllegalStateException("Mod Event Bus for modid '" + modId + "' has not been registered.") + ); + } +} \ No newline at end of file diff --git a/forge/src/main/java/com/cursedcauldron/wildbackport/core/api/forge/MobRegistryImpl.java b/forge/src/main/java/com/cursedcauldron/wildbackport/core/api/forge/MobRegistryImpl.java new file mode 100644 index 0000000..877e8af --- /dev/null +++ b/forge/src/main/java/com/cursedcauldron/wildbackport/core/api/forge/MobRegistryImpl.java @@ -0,0 +1,15 @@ +package com.cursedcauldron.wildbackport.core.api.forge; + +import com.cursedcauldron.wildbackport.WildBackport; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.attributes.AttributeSupplier; +import net.minecraftforge.event.entity.EntityAttributeCreationEvent; + +import java.util.function.Supplier; + +public class MobRegistryImpl { + public static void registerAttributes(Supplier> type, Supplier attribute) { + EventBuses.getModEventBusOrThrow(WildBackport.MOD_ID).addListener(event -> event.put(type.get(), attribute.get().build())); + } +} \ No newline at end of file diff --git a/forge/src/main/java/com/cursedcauldron/wildbackport/core/api/forge/ParticleRegistryImpl.java b/forge/src/main/java/com/cursedcauldron/wildbackport/core/api/forge/ParticleRegistryImpl.java new file mode 100644 index 0000000..bb5d985 --- /dev/null +++ b/forge/src/main/java/com/cursedcauldron/wildbackport/core/api/forge/ParticleRegistryImpl.java @@ -0,0 +1,37 @@ +package com.cursedcauldron.wildbackport.core.api.forge; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.core.api.ParticleRegistry; +import net.minecraft.client.Minecraft; +import net.minecraft.client.particle.ParticleProvider; +import net.minecraft.core.particles.ParticleOptions; +import net.minecraft.core.particles.ParticleType; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.client.event.ParticleFactoryRegisterEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; + +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Consumer; +import java.util.function.Supplier; + +//<> + +@Mod.EventBusSubscriber(modid = WildBackport.MOD_ID, value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.MOD) +public class ParticleRegistryImpl { + private static final Set> FACTORIES = ConcurrentHashMap.newKeySet(); + + @SubscribeEvent + public static void event(ParticleFactoryRegisterEvent event) { + FACTORIES.forEach(consumer -> consumer.accept(event)); + } + + public static > void create(Supplier

type, ParticleProvider provider) { + FACTORIES.add(event -> Minecraft.getInstance().particleEngine.register(type.get(), provider)); + } + + public static > void create(Supplier

type, ParticleRegistry.Factory factory) { + FACTORIES.add(event -> Minecraft.getInstance().particleEngine.register(type.get(), factory::create)); + } +} \ No newline at end of file diff --git a/forge/src/main/java/com/cursedcauldron/wildbackport/core/api/forge/RenderRegistryImpl.java b/forge/src/main/java/com/cursedcauldron/wildbackport/core/api/forge/RenderRegistryImpl.java new file mode 100644 index 0000000..95c6e6c --- /dev/null +++ b/forge/src/main/java/com/cursedcauldron/wildbackport/core/api/forge/RenderRegistryImpl.java @@ -0,0 +1,59 @@ +package com.cursedcauldron.wildbackport.core.api.forge; + +import com.cursedcauldron.wildbackport.WildBackport; +import net.minecraft.client.model.geom.ModelLayerLocation; +import net.minecraft.client.model.geom.builders.LayerDefinition; +import net.minecraft.client.renderer.ItemBlockRenderTypes; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.client.event.EntityRenderersEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; + +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Consumer; +import java.util.function.Supplier; + +//<> + +@Mod.EventBusSubscriber(modid = WildBackport.MOD_ID, value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.MOD) +public class RenderRegistryImpl { + private static final Set> RENDERERS = ConcurrentHashMap.newKeySet(); + private static final Set> LAYER_DEFINITIONS = ConcurrentHashMap.newKeySet(); + + public static void setBlockRenderType(RenderType type, Block... blocks) { + for (Block block : blocks) { + ItemBlockRenderTypes.setRenderLayer(block, type); + } + } + + @SubscribeEvent + public static void event(EntityRenderersEvent.RegisterRenderers event) { + RENDERERS.forEach(consumer -> consumer.accept(event)); + } + + @SubscribeEvent + public static void event(EntityRenderersEvent.RegisterLayerDefinitions event) { + LAYER_DEFINITIONS.forEach(consumer -> consumer.accept(event)); + } + + public static void setEntityRender(Supplier> type, EntityRendererProvider provider) { + RENDERERS.add(event -> event.registerEntityRenderer(type.get(), provider)); + } + + public static void setLayerDefinition(ModelLayerLocation layer, Supplier definition) { + LAYER_DEFINITIONS.add(event -> event.registerLayerDefinition(layer, definition)); + } + + public static void setBlockEntityRender(Supplier> type, BlockEntityRendererProvider provider) { + RENDERERS.add(event -> event.registerBlockEntityRenderer(type.get(), provider)); + } +} \ No newline at end of file diff --git a/forge/src/main/java/com/cursedcauldron/wildbackport/core/api/forge/WoodTypeRegistryImpl.java b/forge/src/main/java/com/cursedcauldron/wildbackport/core/api/forge/WoodTypeRegistryImpl.java new file mode 100644 index 0000000..98fe09f --- /dev/null +++ b/forge/src/main/java/com/cursedcauldron/wildbackport/core/api/forge/WoodTypeRegistryImpl.java @@ -0,0 +1,15 @@ +package com.cursedcauldron.wildbackport.core.api.forge; + +import com.cursedcauldron.wildbackport.core.mixin.access.WoodTypeAccessor; +import net.minecraft.client.renderer.Sheets; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.block.state.properties.WoodType; +import net.minecraftforge.fml.loading.FMLLoader; + +public class WoodTypeRegistryImpl { + public static WoodType create(ResourceLocation location) { + WoodType woodType = WoodTypeAccessor.callRegister(WoodTypeAccessor.createWoodType(location.toString())); + if (FMLLoader.getDist().isClient()) Sheets.addWoodType(woodType); + return woodType; + } +} \ No newline at end of file diff --git a/forge/src/main/java/com/cursedcauldron/wildbackport/forge/WildBackportForge.java b/forge/src/main/java/com/cursedcauldron/wildbackport/forge/WildBackportForge.java new file mode 100644 index 0000000..0d6ea8b --- /dev/null +++ b/forge/src/main/java/com/cursedcauldron/wildbackport/forge/WildBackportForge.java @@ -0,0 +1,27 @@ +package com.cursedcauldron.wildbackport.forge; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.client.ClientSetup; +import com.cursedcauldron.wildbackport.common.CommonSetup; +import com.cursedcauldron.wildbackport.core.api.forge.EventBuses; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.fml.DistExecutor; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; +import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; + +@Mod(WildBackport.MOD_ID) +public class WildBackportForge { + public WildBackportForge() { + IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus(); + EventBuses.registerModEventBus(WildBackport.MOD_ID, bus); + bus.addListener(event -> CommonSetup.onPostClient()); + bus.addListener(event -> ClientSetup.onPostClient()); + + WildBackport.bootstrap(); + CommonSetup.onCommon(); + DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> ClientSetup::onClient); + } +} \ No newline at end of file diff --git a/forge/src/main/java/com/cursedcauldron/wildbackport/forge/WildBackportForgeClient.java b/forge/src/main/java/com/cursedcauldron/wildbackport/forge/WildBackportForgeClient.java new file mode 100644 index 0000000..7e94bdf --- /dev/null +++ b/forge/src/main/java/com/cursedcauldron/wildbackport/forge/WildBackportForgeClient.java @@ -0,0 +1,19 @@ +package com.cursedcauldron.wildbackport.forge; + +import com.cursedcauldron.wildbackport.client.ClientSetup; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; + +@OnlyIn(Dist.CLIENT) +public class WildBackportForgeClient { + public WildBackportForgeClient() { + FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup); + } + + public void setup(FMLClientSetupEvent event) { + ClientSetup.onClient(); + ClientSetup.onPostClient(); + } +} diff --git a/forge/src/main/resources/META-INF/mods.toml b/forge/src/main/resources/META-INF/mods.toml new file mode 100644 index 0000000..8bab1b8 --- /dev/null +++ b/forge/src/main/resources/META-INF/mods.toml @@ -0,0 +1,27 @@ +modLoader = "javafml" +loaderVersion = "[40,)" +license = "All Rights Reserved" + +[[mods]] +modId = "wildbackport" +version = "${version}" +displayName = "The Wild Backport" +logoFile = "icon.png" +authors = "BlackGear, Orcinus, Dopadream" +description = ''' +a mod that backports the features from the wild update +''' + +[[dependencies.wildbackport]] + modId = "forge" + mandatory = true + versionRange = "[40,)" + ordering = "NONE" + side = "BOTH" + +[[dependencies.wildbackport]] + modId = "minecraft" + mandatory = true + versionRange = "[1.18.2,1.19)" + ordering = "NONE" + side = "BOTH" \ No newline at end of file diff --git a/forge/src/main/resources/pack.mcmeta b/forge/src/main/resources/pack.mcmeta new file mode 100644 index 0000000..334abc5 --- /dev/null +++ b/forge/src/main/resources/pack.mcmeta @@ -0,0 +1,8 @@ +{ + "pack": { + "description": "wildbackport resources", + "pack_format": 8, + "forge:resource_pack_format": 8, + "forge:data_pack_format": 9 + } +} diff --git a/forge/src/main/resources/wildbackport.mixins.json b/forge/src/main/resources/wildbackport.mixins.json new file mode 100644 index 0000000..0210cfa --- /dev/null +++ b/forge/src/main/resources/wildbackport.mixins.json @@ -0,0 +1,13 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "com.cursedcauldron.wildbackport.mixin.forge", + "compatibilityLevel": "JAVA_17", + "mixins": [ + ], + "client": [ + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..0d00283 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,9 @@ +org.gradle.jvmargs=-Xmx1G +minecraft_version=1.18.2 +archives_base_name=wildbackport +mod_version=1.0.0 +maven_group=com.cursedcauldron +architectury_version=4.5.74 +fabric_loader_version=0.14.8 +fabric_api_version=0.56.1+1.18.2 +forge_version=1.18.2-40.1.54 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..7454180 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..2e6e589 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..c53aefa --- /dev/null +++ b/gradlew @@ -0,0 +1,234 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +APP_NAME="Gradle" +APP_BASE_NAME=${0##*/} + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..107acd3 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..06a89e4 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,12 @@ +pluginManagement { + repositories { + maven { url "https://maven.fabricmc.net/" } + maven { url "https://maven.architectury.dev/" } + maven { url "https://maven.minecraftforge.net/" } + gradlePluginPortal() + } +} + +include("common") +include("fabric") +include("forge") \ No newline at end of file