├── .gitattributes ├── .github └── ISSUE_TEMPLATE │ └── bug-feature.md ├── .gitignore ├── LICENSE ├── README.md ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src └── main ├── java └── net │ └── liopyu │ └── entityjs │ ├── EntityJSMod.java │ ├── EntityJSPlugin.java │ ├── builders │ ├── MobBuilder.java │ ├── living │ │ ├── BaseLivingEntityBuilder.java │ │ ├── LivingEntityTypeBuilderJS.java │ │ ├── entityjs │ │ │ ├── AnimalEntityBuilder.java │ │ │ ├── AnimalEntityJSBuilder.java │ │ │ ├── BaseLivingEntityJSBuilder.java │ │ │ ├── ContainerTameableJSBuilder.java │ │ │ ├── MobBuilder.java │ │ │ ├── MobEntityJSBuilder.java │ │ │ ├── PathfinderMobBuilder.java │ │ │ ├── TameableMobBuilder.java │ │ │ ├── TameableMobJSBuilder.java │ │ │ └── WaterEntityJSBuilder.java │ │ └── vanilla │ │ │ ├── AllayJSBuilder.java │ │ │ ├── AxolotlJSBuilder.java │ │ │ ├── BatJSBuilder.java │ │ │ ├── BeeJSBuilder.java │ │ │ ├── BlazeJSBuilder.java │ │ │ ├── CatJSBuilder.java │ │ │ ├── CaveSpiderJSBuilder.java │ │ │ ├── ChickenJSBuilder.java │ │ │ ├── CowJSBuilder.java │ │ │ ├── CreeperJSBuilder.java │ │ │ ├── DolphinJSBuilder.java │ │ │ ├── DonkeyJSBuilder.java │ │ │ ├── EnderManJSBuilder.java │ │ │ ├── EvokerJSBuilder.java │ │ │ ├── GhastJSBuilder.java │ │ │ ├── GoatJSBuilder.java │ │ │ ├── GuardianJSBuilder.java │ │ │ ├── HorseJSBuilder.java │ │ │ ├── IllusionerJSBuilder.java │ │ │ ├── IronGolemJSBuilder.java │ │ │ ├── PandaJSBuilder.java │ │ │ ├── ParrotJSBuilder.java │ │ │ ├── PiglinJSBuilder.java │ │ │ ├── SkeletonJSBuilder.java │ │ │ ├── SlimeJSBuilder.java │ │ │ ├── WitherJSBuilder.java │ │ │ ├── WolfJSBuilder.java │ │ │ └── ZombieJSBuilder.java │ ├── misc │ │ ├── JumpControlJSBuilder.java │ │ ├── LookControlJSBuilder.java │ │ └── MoveControlJSBuilder.java │ ├── modification │ │ ├── ModifyAgeableMobBuilder.java │ │ ├── ModifyAnimalBuilder.java │ │ ├── ModifyEntityBuilder.java │ │ ├── ModifyLivingEntityBuilder.java │ │ ├── ModifyMobBuilder.java │ │ ├── ModifyPathfinderMobBuilder.java │ │ ├── ModifyProjectileBuilder.java │ │ ├── ModifyTamableAnimalBuilder.java │ │ └── TestModifyEntityBuilder.java │ └── nonliving │ │ ├── BaseEntityBuilder.java │ │ ├── BaseNonAnimatableEntityBuilder.java │ │ ├── EntityTypeBuilder.java │ │ ├── NonAnimatableEntityTypeBuilder.java │ │ ├── entityjs │ │ ├── ArrowEntityBuilder.java │ │ ├── ArrowEntityJSBuilder.java │ │ ├── BaseEntityJSBuilder.java │ │ ├── PartBuilder.java │ │ ├── ProjectileAnimatableJSBuilder.java │ │ ├── ProjectileEntityBuilder.java │ │ └── ProjectileEntityJSBuilder.java │ │ ├── modded │ │ └── CGMProjectileEntityJSBuilder.java │ │ └── vanilla │ │ ├── BoatEntityBuilder.java │ │ ├── BoatJSBuilder.java │ │ ├── EyeOfEnderEntityBuilder.java │ │ ├── EyeOfEnderJSBuilder.java │ │ └── TridentJSBuilder.java │ ├── client │ ├── ClientEventHandlers.java │ ├── living │ │ ├── KubeJSEntityRenderer.java │ │ └── model │ │ │ ├── EntityModelJS.java │ │ │ ├── GeoLayerJS.java │ │ │ ├── GeoLayerJSBuilder.java │ │ │ └── GlowingGeoLayerJS.java │ ├── nonliving │ │ ├── KubeJSArrowEntityRenderer.java │ │ ├── KubeJSBoatRenderer.java │ │ ├── KubeJSEnderEyeRenderer.java │ │ ├── KubeJSNLEntityRenderer.java │ │ ├── KubeJSProjectileEntityRenderer.java │ │ └── model │ │ │ ├── BoatEntityModel.java │ │ │ └── NonLivingEntityModel.java │ └── utils │ │ └── VertexModifier.java │ ├── entities │ ├── living │ │ ├── entityjs │ │ │ ├── AnimalEntityJS.java │ │ │ ├── BaseLivingEntityJS.java │ │ │ ├── ContainerTameableEntityJS.java │ │ │ ├── IAnimatableJS.java │ │ │ ├── MobEntityJS.java │ │ │ ├── TameableMobJS.java │ │ │ └── WaterEntityJS.java │ │ └── vanilla │ │ │ ├── AllayEntityJS.java │ │ │ ├── AxolotlEntityJS.java │ │ │ ├── BatEntityJS.java │ │ │ ├── BeeEntityJS.java │ │ │ ├── BlazeEntityJS.java │ │ │ ├── CatEntityJS.java │ │ │ ├── CaveSpiderEntityJS.java │ │ │ ├── ChickenEntityJS.java │ │ │ ├── CowEntityJS.java │ │ │ ├── CreeperEntityJS.java │ │ │ ├── DolphinEntityJS.java │ │ │ ├── DonkeyEntityJS.java │ │ │ ├── EnderManEntityJS.java │ │ │ ├── EvokerEntityJS.java │ │ │ ├── GhastEntityJS.java │ │ │ ├── GoatEntityJS.java │ │ │ ├── GuardianEntityJS.java │ │ │ ├── HorseEntityJS.java │ │ │ ├── IllusionerEntityJS.java │ │ │ ├── IronGolemEntityJS.java │ │ │ ├── PandaEntityJS.java │ │ │ ├── ParrotEntityJS.java │ │ │ ├── PiglinEntityJS.java │ │ │ ├── SkeletonEntityJS.java │ │ │ ├── SlimeEntityJS.java │ │ │ ├── WitherEntityJS.java │ │ │ ├── WolfEntityJS.java │ │ │ └── ZombieEntityJS.java │ └── nonliving │ │ ├── entityjs │ │ ├── ArrowEntityJS.java │ │ ├── BaseEntityJS.java │ │ ├── IAnimatableJSNL.java │ │ ├── IArrowEntityJS.java │ │ ├── IProjectileEntityJS.java │ │ ├── PartEntityJS.java │ │ ├── ProjectileAnimatableJS.java │ │ └── ProjectileEntityJS.java │ │ ├── modded │ │ └── CGMProjectileEntityJS.java │ │ └── vanilla │ │ ├── BoatEntityJS.java │ │ ├── EyeOfEnderEntityJS.java │ │ └── TridentEntityJS.java │ ├── events │ ├── AddGoalSelectorsEventJS.java │ ├── AddGoalTargetsEventJS.java │ ├── BiomeSpawnsEventJS.java │ ├── BuildBrainEventJS.java │ ├── BuildBrainProviderEventJS.java │ ├── EntityModificationEventJS.java │ ├── GoalEventJS.java │ ├── ModifyAttributeEventJS.java │ ├── RegisterMobCategoryEventJS.java │ └── RegisterSpawnPlacementsEventJS.java │ ├── inventory │ └── ContainerJS.java │ ├── item │ ├── ArrowItemBuilder.java │ ├── CGMProjectileItemBuilder.java │ ├── EyeOfEnderItemBuilder.java │ ├── ProjectileItemBuilder.java │ ├── SpawnEggItemBuilder.java │ └── TridentItemBuilder.java │ ├── mixin │ ├── AnimationControllerMixin.java │ ├── EntityMixin.java │ ├── EntityRendererMixin.java │ ├── KubeJSCommandsMixin.java │ ├── LivingEntityMixin.java │ ├── LivingEntityRendererMixin.java │ ├── MobMixin.java │ ├── PathfinderMobMixin.java │ ├── ProjectileMixin.java │ └── ServerScriptManagerMixin.java │ └── util │ ├── ContextUtils.java │ ├── EntityJSHelperClass.java │ ├── EntityJSUtils.java │ ├── EventHandlers.java │ ├── ModKeybinds.java │ ├── RegistryUtil.java │ ├── SubEvents.java │ ├── ai │ ├── Behaviors.java │ ├── CustomGoal.java │ ├── JumpControlJS.java │ ├── LookControlJS.java │ └── MoveControlJS.java │ └── implementation │ ├── EventBasedSpawnModifier.java │ ├── IAnimationControllerJS.java │ └── IEntityJS.java └── resources ├── META-INF ├── accesstransformer.cfg └── mods.toml ├── assets ├── entityjs │ └── lang │ │ └── en_us.json └── kubejs │ ├── animations │ └── entity │ │ ├── sasuke.animation.json │ │ └── wyrm.animation.json │ ├── geo │ └── entity │ │ ├── sasuke.geo.json │ │ └── wyrm.geo.json │ └── textures │ ├── entity │ ├── projectiles │ │ ├── arrow.png │ │ └── projectile.png │ ├── sasuke.png │ └── wyrm.png │ ├── item │ ├── arrow.png │ └── projectile.png │ └── models │ └── entity │ └── projectile.png ├── data └── entityjs │ └── forge │ └── biome_modifier │ └── event_based.json ├── entityjs.mixins.json ├── kubejs.plugins.txt └── pack.mcmeta /.gitattributes: -------------------------------------------------------------------------------- 1 | # Disable autocrlf on generated files, they always generate with LF 2 | # Add any extra files or paths here to make git stop saying they 3 | # are changed when only line endings change. 4 | src/generated/**/.cache/cache text eol=lf 5 | src/generated/**/*.json text eol=lf 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-feature.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug/Feature 3 | about: Request a feature or report a bug! 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | Report an issue or feature request 11 | 12 | **Mod Version:** 13 | Provide the version of the EntityJS mod you are using. 14 | 15 | **Minecraft Version:** 16 | Indicate the version of Minecraft where the issue occurs. 17 | 18 | **Minecraft Modloader:** 19 | Specify the modloader you're using; Forge, NeoForge, Fabric, etc. 20 | 21 | **Describe the Bug/Feature Request:** 22 | Provide a clear and concise description of the bug/feature. 23 | 24 | **Screenshots or Logs:** 25 | If applicable, add screenshots to help explain your problem. Also, include relevant logs if necessary. 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # eclipse 2 | bin 3 | *.launch 4 | .settings 5 | .metadata 6 | .classpath 7 | .project 8 | 9 | # idea 10 | out 11 | *.ipr 12 | *.iws 13 | *.iml 14 | .idea 15 | 16 | # gradle 17 | build 18 | .gradle 19 | 20 | # other 21 | eclipse 22 | run 23 | runs 24 | # Files from Forge MDK 25 | forge*changelog.txt 26 | pytests 27 | run1 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EntityJS 2 | 3 | EntityJS is a powerful addon for KubeJS that enhances your Minecraft experience by providing dynamic entity registry 4 | capabilities, Geckolib-like animations with LioLib, spawn control, attribute modification, and full AI support. With 5 | EntityJS, you can bring your custom entities to life with ease and precision. 6 | 7 | ## Key Features 8 | 9 | - **Dynamic Entity Registry**: Easily register custom entities and define their attributes and behaviors using 10 | JavaScript. 11 | 12 | - **Geckolib-like Animations with LioLib**: Enjoy smooth and lifelike animations for your entities, utilizing LioLib, a 13 | Geckolib 4 fork, for advanced animation capabilities. 14 | 15 | - **Spawn Control**: Take full control over entity spawning by specifying spawn conditions, rates, and locations. 16 | 17 | - **Attribute Modification**: Fine-tune entity attributes such as health, speed, damage, and more to suit your gameplay 18 | needs. 19 | 20 | - **Full AI Support**: Access a comprehensive set of AI behaviors and functions to create intelligent and interactive 21 | entities. 22 | 23 | ## Getting Started 24 | 25 | To start using EntityJS, simply install the addon alongside KubeJS and begin creating your custom entities and 26 | animations. Refer to the documentation for detailed instructions and examples. 27 | 28 | ## Documentation 29 | 30 | Visit the [EntityJS Wiki](https://github.com/liopyu/EntityJS/wiki) for comprehensive documentation, tutorials, and 31 | examples to help you unleash the full potential of EntityJS. 32 | 33 | ## Community 34 | 35 | Join our [Discord](https://discord.gg/lat) community to connect with other users, share your creations, and get help 36 | with any questions or issues you encounter while using EntityJS. 37 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Sets default memory used for gradle commands. Can be overridden by user or command line properties. 2 | # This is required to provide enough memory for the Minecraft decompilation process. 3 | org.gradle.jvmargs=-Xmx3G 4 | org.gradle.daemon=false 5 | minecraft_version=1.19.2 6 | minecraft_version_range=[1.19.2,1.20) 7 | forge_version=43.3.5 8 | forge_version_range=[43,) 9 | loader_version_range=[43,) 10 | mapping_channel=parchment 11 | mapping_version=2022.11.27-1.19.2 12 | mod_id=entityjs 13 | mod_name=EntityJS 14 | mod_license=GNU General Public License Version 3 15 | mod_version=0.5.0-1.19.2 16 | mod_group_id=net.liopyu.entityjs 17 | mod_authors=Liopyu,Too Much Mail 18 | mod_description=Entity Registry Addon Mod For KubeJS 19 | mixin_version=0.8.5 20 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liopyu/EntityJS/e8e0d1b94daf96e7a2c78b26396f229f31254081/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip 4 | networkTimeout=10000 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%"=="" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%"=="" set DIRNAME=. 29 | @rem This is normally unused 30 | set APP_BASE_NAME=%~n0 31 | set APP_HOME=%DIRNAME% 32 | 33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 35 | 36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 38 | 39 | @rem Find java.exe 40 | if defined JAVA_HOME goto findJavaFromJavaHome 41 | 42 | set JAVA_EXE=java.exe 43 | %JAVA_EXE% -version >NUL 2>&1 44 | if %ERRORLEVEL% equ 0 goto execute 45 | 46 | echo. 47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 48 | echo. 49 | echo Please set the JAVA_HOME variable in your environment to match the 50 | echo location of your Java installation. 51 | 52 | goto fail 53 | 54 | :findJavaFromJavaHome 55 | set JAVA_HOME=%JAVA_HOME:"=% 56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 57 | 58 | if exist "%JAVA_EXE%" goto execute 59 | 60 | echo. 61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 62 | echo. 63 | echo Please set the JAVA_HOME variable in your environment to match the 64 | echo location of your Java installation. 65 | 66 | goto fail 67 | 68 | :execute 69 | @rem Setup the command line 70 | 71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 72 | 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if %ERRORLEVEL% equ 0 goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | set EXIT_CODE=%ERRORLEVEL% 85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 87 | exit /b %EXIT_CODE% 88 | 89 | :mainEnd 90 | if "%OS%"=="Windows_NT" endlocal 91 | 92 | :omega 93 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | maven { url = 'https://repo.spongepowered.org/repository/maven-public/' } 5 | maven { 6 | name = 'MinecraftForge' 7 | url = 'https://maven.minecraftforge.net/' 8 | } 9 | maven { 10 | // Shedaniel's maven (Architectury API) 11 | url = "https://maven.architectury.dev" 12 | content { 13 | includeGroup "dev.architectury" 14 | } 15 | } 16 | 17 | maven { 18 | // saps.dev Maven (KubeJS and Rhino) 19 | url = "https://maven.saps.dev/releases" 20 | content { 21 | includeGroup "dev.latvian.mods" 22 | } 23 | } 24 | 25 | maven { url = 'https://repo.spongepowered.org/repository/maven-public/' } 26 | 27 | maven { url = 'https://maven.parchmentmc.org' } 28 | } 29 | 30 | } 31 | 32 | plugins { 33 | id 'org.gradle.toolchains.foojay-resolver-convention' version '0.7.+' 34 | } -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/EntityJSMod.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs; 2 | 3 | import com.mojang.logging.LogUtils; 4 | import dev.latvian.mods.kubejs.util.ConsoleJS; 5 | import net.liopyu.entityjs.client.ClientEventHandlers; 6 | import net.liopyu.entityjs.util.EventHandlers; 7 | import net.liopyu.entityjs.util.RegistryUtil; 8 | import net.minecraft.resources.ResourceLocation; 9 | import net.minecraftforge.api.distmarker.Dist; 10 | import net.minecraftforge.fml.common.Mod; 11 | import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; 12 | import net.minecraftforge.fml.loading.FMLEnvironment; 13 | import net.minecraftforge.registries.ForgeRegistries; 14 | import org.slf4j.Logger; 15 | 16 | import java.util.HashSet; 17 | import java.util.Set; 18 | 19 | 20 | @Mod(EntityJSMod.MOD_ID) 21 | public class EntityJSMod { 22 | public static final Logger LOGGER = LogUtils.getLogger(); 23 | 24 | public static final String MOD_ID = "entityjs"; 25 | 26 | public EntityJSMod() { 27 | LOGGER.info("Loading EntityJS-Liopyu"); 28 | 29 | EventHandlers.init(); 30 | RegistryUtil.init(FMLJavaModLoadingContext.get().getModEventBus()); 31 | 32 | if (FMLEnvironment.dist == Dist.CLIENT) { 33 | ClientEventHandlers.init(); 34 | } 35 | 36 | } 37 | 38 | 39 | public static ResourceLocation identifier(String path) { 40 | return new ResourceLocation(MOD_ID, path); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/MobBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders; 2 | 3 | import net.liopyu.entityjs.builders.living.entityjs.PathfinderMobBuilder; 4 | import net.liopyu.entityjs.entities.living.entityjs.IAnimatableJS; 5 | import net.minecraft.resources.ResourceLocation; 6 | import net.minecraft.world.entity.PathfinderMob; 7 | 8 | /** 9 | * Standin class for older Iron's Spells Kubejs Compat Mod Versions 10 | */ 11 | public abstract class MobBuilder extends PathfinderMobBuilder { 12 | public MobBuilder(ResourceLocation i) { 13 | super(i); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/LivingEntityTypeBuilderJS.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living; 2 | 3 | import dev.latvian.mods.kubejs.util.UtilsJS; 4 | import net.liopyu.entityjs.entities.living.entityjs.IAnimatableJS; 5 | import net.minecraft.world.entity.EntityType; 6 | import net.minecraft.world.entity.LivingEntity; 7 | import net.minecraft.world.level.block.Block; 8 | import net.minecraftforge.registries.ForgeRegistries; 9 | 10 | public class LivingEntityTypeBuilderJS { 11 | private final BaseLivingEntityBuilder builder; 12 | 13 | public > LivingEntityTypeBuilderJS(T builder) { 14 | this.builder = builder; 15 | } 16 | 17 | public EntityType get() { 18 | var js = this.builder; 19 | 20 | var builder = EntityType.Builder.of(js.factory(), js.mobCategory); 21 | builder 22 | .sized(js.width, js.height) 23 | .clientTrackingRange(js.clientTrackingRange) 24 | .updateInterval(js.updateInterval); 25 | 26 | if (js.spawnFarFromPlayer) { 27 | builder.canSpawnFarFromPlayer(); 28 | } 29 | if (js.fireImmune) { 30 | builder.fireImmune(); 31 | } 32 | if (!js.save) { 33 | builder.noSave(); 34 | } 35 | if (js.immuneTo.length > 0) { 36 | final Block[] blocks = new Block[js.immuneTo.length]; 37 | for (int i = 0; i < js.immuneTo.length; i++) { 38 | blocks[i] = ForgeRegistries.BLOCKS.getValue(js.immuneTo[i]); 39 | } 40 | builder.immuneTo(blocks); 41 | } 42 | if (!js.summonable) { 43 | builder.noSummon(); 44 | } 45 | 46 | return UtilsJS.cast(builder.build(js.id.toString())); // If this fails, uh... do better? 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/entityjs/AnimalEntityJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living.entityjs; 2 | 3 | 4 | import net.liopyu.entityjs.builders.living.entityjs.AnimalEntityBuilder; 5 | import net.liopyu.entityjs.entities.living.entityjs.AnimalEntityJS; 6 | import net.liopyu.entityjs.entities.living.entityjs.MobEntityJS; 7 | import net.minecraft.resources.ResourceLocation; 8 | import net.minecraft.world.entity.EntityType; 9 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 10 | import net.minecraft.world.entity.ai.attributes.Attributes; 11 | 12 | public class AnimalEntityJSBuilder extends AnimalEntityBuilder { 13 | 14 | public AnimalEntityJSBuilder(ResourceLocation i) { 15 | super(i); 16 | 17 | } 18 | 19 | @Override 20 | public EntityType.EntityFactory factory() { 21 | return (type, level) -> new AnimalEntityJS(this, type, level); 22 | } 23 | 24 | @Override 25 | public AttributeSupplier.Builder getAttributeBuilder() { 26 | return MobEntityJS.createMobAttributes() 27 | .add(Attributes.MAX_HEALTH) 28 | .add(Attributes.FOLLOW_RANGE) 29 | .add(Attributes.ATTACK_DAMAGE) 30 | .add(Attributes.ARMOR) 31 | .add(Attributes.ARMOR_TOUGHNESS) 32 | .add(Attributes.ATTACK_SPEED) 33 | .add(Attributes.ATTACK_KNOCKBACK) 34 | .add(Attributes.LUCK) 35 | .add(Attributes.MOVEMENT_SPEED); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/entityjs/BaseLivingEntityJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living.entityjs; 2 | 3 | import net.liopyu.entityjs.builders.living.BaseLivingEntityBuilder; 4 | import net.liopyu.entityjs.entities.living.entityjs.BaseLivingEntityJS; 5 | import net.minecraft.resources.ResourceLocation; 6 | import net.minecraft.world.entity.EntityType; 7 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 8 | import net.minecraft.world.entity.ai.attributes.Attributes; 9 | 10 | public class BaseLivingEntityJSBuilder extends BaseLivingEntityBuilder { 11 | 12 | public BaseLivingEntityJSBuilder(ResourceLocation i) { 13 | super(i); 14 | } 15 | 16 | @Override 17 | public EntityType.EntityFactory factory() { 18 | return (type, level) -> new BaseLivingEntityJS(this, type, level); 19 | } 20 | 21 | @Override 22 | public AttributeSupplier.Builder getAttributeBuilder() { 23 | final AttributeSupplier.Builder builder = BaseLivingEntityJS.createLivingAttributes(); 24 | builder.add(Attributes.ATTACK_DAMAGE); 25 | builder.add(Attributes.ATTACK_SPEED); 26 | builder.add(Attributes.ATTACK_KNOCKBACK); 27 | return BaseLivingEntityJS.createLivingAttributes(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/entityjs/ContainerTameableJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living.entityjs; 2 | 3 | import net.liopyu.entityjs.entities.living.entityjs.ContainerTameableEntityJS; 4 | import net.liopyu.entityjs.entities.living.entityjs.MobEntityJS; 5 | import net.liopyu.entityjs.entities.living.entityjs.TameableMobJS; 6 | import net.minecraft.resources.ResourceLocation; 7 | import net.minecraft.world.entity.EntityType; 8 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 9 | import net.minecraft.world.entity.ai.attributes.Attributes; 10 | 11 | public class ContainerTameableJSBuilder extends TameableMobBuilder { 12 | public ContainerTameableJSBuilder(ResourceLocation i) { 13 | super(i); 14 | } 15 | 16 | @Override 17 | public EntityType.EntityFactory factory() { 18 | return (type, level) -> new ContainerTameableEntityJS(this, type, level); 19 | } 20 | 21 | @Override 22 | public AttributeSupplier.Builder getAttributeBuilder() { 23 | return MobEntityJS.createMobAttributes() 24 | .add(Attributes.MAX_HEALTH) 25 | .add(Attributes.FOLLOW_RANGE) 26 | .add(Attributes.ATTACK_DAMAGE) 27 | .add(Attributes.ARMOR) 28 | .add(Attributes.ARMOR_TOUGHNESS) 29 | .add(Attributes.ATTACK_SPEED) 30 | .add(Attributes.ATTACK_KNOCKBACK) 31 | .add(Attributes.LUCK) 32 | .add(Attributes.MOVEMENT_SPEED); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/entityjs/MobEntityJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living.entityjs; 2 | 3 | import net.liopyu.entityjs.builders.living.entityjs.MobBuilder; 4 | import net.liopyu.entityjs.entities.living.entityjs.MobEntityJS; 5 | import net.minecraft.resources.ResourceLocation; 6 | import net.minecraft.world.entity.EntityType; 7 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 8 | import net.minecraft.world.entity.ai.attributes.Attributes; 9 | import net.minecraft.world.level.pathfinder.Path; 10 | 11 | public class MobEntityJSBuilder extends PathfinderMobBuilder { 12 | 13 | public MobEntityJSBuilder(ResourceLocation i) { 14 | super(i); 15 | } 16 | 17 | @Override 18 | public EntityType.EntityFactory factory() { 19 | return (type, level) -> new MobEntityJS(this, type, level); 20 | } 21 | 22 | @Override 23 | public AttributeSupplier.Builder getAttributeBuilder() { 24 | return MobEntityJS.createMobAttributes() 25 | .add(Attributes.MAX_HEALTH) 26 | .add(Attributes.FOLLOW_RANGE) 27 | .add(Attributes.ATTACK_DAMAGE) 28 | .add(Attributes.ARMOR) 29 | .add(Attributes.ARMOR_TOUGHNESS) 30 | .add(Attributes.ATTACK_SPEED) 31 | .add(Attributes.ATTACK_KNOCKBACK) 32 | .add(Attributes.LUCK) 33 | .add(Attributes.MOVEMENT_SPEED); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/entityjs/PathfinderMobBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living.entityjs; 2 | 3 | import dev.latvian.mods.kubejs.typings.Info; 4 | import net.liopyu.entityjs.entities.living.entityjs.IAnimatableJS; 5 | import net.liopyu.entityjs.util.ContextUtils; 6 | import net.minecraft.resources.ResourceLocation; 7 | import net.minecraft.world.entity.Mob; 8 | import net.minecraft.world.entity.PathfinderMob; 9 | 10 | import java.util.function.Function; 11 | 12 | public abstract class PathfinderMobBuilder extends MobBuilder { 13 | public transient Function shouldStayCloseToLeashHolder; 14 | public transient Double followLeashSpeed; 15 | public transient Function walkTargetValue; 16 | 17 | public PathfinderMobBuilder(ResourceLocation i) { 18 | super(i); 19 | } 20 | 21 | 22 | @Info(value = """ 23 | Sets the function to determine whether the entity should stay close to its leash holder. 24 | 25 | @param predicate A Function accepting a {@link Mob} parameter, 26 | defining the condition for the entity to stay close to its leash holder. 27 | 28 | Example usage: 29 | ```javascript 30 | mobBuilder.shouldStayCloseToLeashHolder(entity => { 31 | // Custom logic to determine whether the entity should stay close to its leash holder. 32 | return true; 33 | }); 34 | ``` 35 | """) 36 | public PathfinderMobBuilder shouldStayCloseToLeashHolder(Function predicate) { 37 | this.shouldStayCloseToLeashHolder = predicate; 38 | return this; 39 | } 40 | 41 | @Info(value = """ 42 | Sets the follow leash speed for the entity. 43 | 44 | @param speed The follow leash speed. 45 | 46 | Example usage: 47 | ```javascript 48 | mobBuilder.followLeashSpeed(1.5); 49 | ``` 50 | """) 51 | public PathfinderMobBuilder followLeashSpeed(double speed) { 52 | this.followLeashSpeed = speed; 53 | return this; 54 | } 55 | 56 | @Info(value = """ 57 | Sets the walk target value function for the entity. 58 | 59 | @param function A Function accepting a {@link ContextUtils.EntityBlockPosLevelContext} parameter, 60 | defining the walk target value based on the entity's interaction with a specific block. 61 | 62 | Example usage: 63 | ```javascript 64 | mobBuilder.walkTargetValue(context => { 65 | // Custom logic to calculate the walk target value based on the provided context. 66 | // Access information about the block position and level using the provided context. 67 | return 10; 68 | }); 69 | ``` 70 | """) 71 | public PathfinderMobBuilder walkTargetValue(Function function) { 72 | this.walkTargetValue = function; 73 | return this; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/entityjs/TameableMobBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living.entityjs; 2 | 3 | import dev.latvian.mods.kubejs.typings.Info; 4 | import net.liopyu.entityjs.builders.living.entityjs.AnimalEntityBuilder; 5 | import net.liopyu.entityjs.builders.living.entityjs.MobBuilder; 6 | import net.liopyu.entityjs.entities.living.entityjs.IAnimatableJS; 7 | import net.liopyu.entityjs.util.ContextUtils; 8 | import net.minecraft.resources.ResourceLocation; 9 | import net.minecraft.world.entity.TamableAnimal; 10 | import net.minecraft.world.item.crafting.Ingredient; 11 | 12 | import java.util.function.Consumer; 13 | import java.util.function.Function; 14 | 15 | public abstract class TameableMobBuilder extends AnimalEntityBuilder { 16 | public transient Ingredient tamableFood; 17 | public transient Function tamableFoodPredicate; 18 | public transient Consumer onTamed; 19 | public transient Consumer tameOverride; 20 | 21 | public TameableMobBuilder(ResourceLocation i) { 22 | super(i); 23 | } 24 | 25 | @Info(value = """ 26 | Sets a Consumer invoked after the entity is tamed 27 | and replaces the logic used to set the UUID of the owner 28 | with the parameter of ContextUtils.PlayerEntityContext callback 29 | 30 | @param tameOverride A Consumer responsible for determining the uuid to set when the entity is tamed. 31 | 32 | Example usage: 33 | ```javascript 34 | mobBuilder.tameOverride(context => { 35 | const {entity,player} = context 36 | // Mimic the vanilla way of setting the uuid when the entity is tamed. 37 | entity.setOwnerUUID(player.getUUID()); 38 | }); 39 | ``` 40 | """) 41 | public MobBuilder tameOverride(Consumer tameOverride) { 42 | this.tameOverride = tameOverride; 43 | return this; 44 | } 45 | 46 | @Info(value = """ 47 | Sets a Consumer with the parameter of ContextUtils.PlayerEntityContext callback 48 | This is fired after the entity is tamed and all tame logic has already taken place. 49 | Useful if you don't want to mess with the UUID logic in the tameOverride method. 50 | 51 | @param onTamed A Consumer that fires when the entity is tamed. 52 | 53 | Example usage: 54 | ```javascript 55 | mobBuilder.onTamed(entity => { 56 | // Do stuff when the entity is tamed. 57 | }); 58 | ``` 59 | """) 60 | public MobBuilder onTamed(Consumer onTamed) { 61 | this.onTamed = onTamed; 62 | return this; 63 | } 64 | 65 | @Info(value = """ 66 | Sets a function to determine if the player's current itemstack will tame the mob. 67 | 68 | @param tamableFoodPredicate A Function accepting a ContextUtils.EntityItemStackContext parameter 69 | 70 | Example usage: 71 | ```javascript 72 | mobBuilder.tamableFood([ 73 | 'minecraft:diamond', 74 | 'minecraft:wheat' 75 | ]); 76 | ``` 77 | """) 78 | public MobBuilder tamableFood(Ingredient tamableFood) { 79 | this.tamableFood = tamableFood; 80 | return this; 81 | } 82 | 83 | @Info(value = """ 84 | Sets a function to determine if the player's current itemstack will tame the mob. 85 | 86 | @param tamableFoodPredicate A Function accepting a ContextUtils.EntityItemStackContext parameter 87 | 88 | Example usage: 89 | ```javascript 90 | mobBuilder.tamableFoodPredicate(context => { 91 | const { entity, item } = context 92 | return item.id == 'minecraft:diamond' // Return true if the player's current itemstack will tame the mob. 93 | }); 94 | ``` 95 | """) 96 | public MobBuilder tamableFoodPredicate(Function tamableFoodPredicate) { 97 | this.tamableFoodPredicate = tamableFoodPredicate; 98 | return this; 99 | } 100 | } -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/entityjs/TameableMobJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living.entityjs; 2 | 3 | 4 | import net.liopyu.entityjs.builders.living.entityjs.TameableMobBuilder; 5 | import net.liopyu.entityjs.entities.living.entityjs.MobEntityJS; 6 | import net.liopyu.entityjs.entities.living.entityjs.TameableMobJS; 7 | import net.minecraft.resources.ResourceLocation; 8 | import net.minecraft.world.entity.EntityType; 9 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 10 | import net.minecraft.world.entity.ai.attributes.Attributes; 11 | 12 | public class TameableMobJSBuilder extends TameableMobBuilder { 13 | 14 | public TameableMobJSBuilder(ResourceLocation i) { 15 | super(i); 16 | 17 | } 18 | 19 | @Override 20 | public EntityType.EntityFactory factory() { 21 | return (type, level) -> new TameableMobJS(this, type, level); 22 | } 23 | 24 | @Override 25 | public AttributeSupplier.Builder getAttributeBuilder() { 26 | return MobEntityJS.createMobAttributes() 27 | .add(Attributes.MAX_HEALTH) 28 | .add(Attributes.FOLLOW_RANGE) 29 | .add(Attributes.ATTACK_DAMAGE) 30 | .add(Attributes.ARMOR) 31 | .add(Attributes.ARMOR_TOUGHNESS) 32 | .add(Attributes.ATTACK_SPEED) 33 | .add(Attributes.ATTACK_KNOCKBACK) 34 | .add(Attributes.LUCK) 35 | .add(Attributes.MOVEMENT_SPEED); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/entityjs/WaterEntityJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living.entityjs; 2 | 3 | import dev.latvian.mods.kubejs.typings.Info; 4 | import net.liopyu.entityjs.entities.living.entityjs.MobEntityJS; 5 | import net.liopyu.entityjs.entities.living.entityjs.WaterEntityJS; 6 | import net.minecraft.resources.ResourceLocation; 7 | import net.minecraft.world.entity.EntityType; 8 | import net.minecraft.world.entity.LivingEntity; 9 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 10 | import net.minecraft.world.entity.ai.attributes.Attributes; 11 | 12 | import java.util.function.Function; 13 | 14 | public class WaterEntityJSBuilder extends PathfinderMobBuilder { 15 | public transient Function bucketItemStack; 16 | public transient boolean defaultGoals = true; 17 | public transient boolean canBeBucketed = false; 18 | 19 | public WaterEntityJSBuilder(ResourceLocation i) { 20 | super(i); 21 | } 22 | 23 | @Info(value = """ 24 | Whether or not the fish can be bucketed, if true it is recommended to set the 25 | bucketItemStack function in the builder otherwise it will give an empty itemstack 26 | and the bucket will be lost. 27 | Defaults to false 28 | Example usage: 29 | ```javascript 30 | builder.setCanBeBucketed(true) 31 | ``` 32 | """) 33 | public WaterEntityJSBuilder setCanBeBucketed(boolean canBeBucketed) { 34 | this.canBeBucketed = canBeBucketed; 35 | return this; 36 | } 37 | 38 | @Info(value = """ 39 | Whether or not the fish retains default swimming goals. 40 | Defaults to True 41 | Example usage: 42 | ```javascript 43 | builder.setDefaultGoals(false) 44 | ``` 45 | """) 46 | public WaterEntityJSBuilder setDefaultGoals(boolean defaultGoals) { 47 | this.defaultGoals = defaultGoals; 48 | return this; 49 | } 50 | 51 | @Info(value = """ 52 | @param bucketItemStack Function returning the itemstack to receive when bucketed 53 | Defaults to Empty Itemstack 54 | Example usage: 55 | ```javascript 56 | builder.bucketItemStack(entity => { 57 | // Use information about the entity to return an ItemStack. 58 | return Item.of('minecraft:diamond') 59 | }) 60 | ``` 61 | """) 62 | public WaterEntityJSBuilder bucketItemStack(Function function) { 63 | this.bucketItemStack = function; 64 | return this; 65 | } 66 | 67 | @Override 68 | public EntityType.EntityFactory factory() { 69 | return (type, level) -> new WaterEntityJS(this, type, level); 70 | } 71 | 72 | @Override 73 | public AttributeSupplier.Builder getAttributeBuilder() { 74 | return MobEntityJS.createMobAttributes() 75 | .add(Attributes.MAX_HEALTH, 3) 76 | .add(Attributes.FOLLOW_RANGE) 77 | .add(Attributes.ATTACK_DAMAGE) 78 | .add(Attributes.ARMOR) 79 | .add(Attributes.ARMOR_TOUGHNESS) 80 | .add(Attributes.ATTACK_SPEED) 81 | .add(Attributes.ATTACK_KNOCKBACK) 82 | .add(Attributes.LUCK) 83 | .add(Attributes.MOVEMENT_SPEED); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/vanilla/AllayJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living.vanilla; 2 | 3 | import dev.latvian.mods.kubejs.typings.Info; 4 | import net.liopyu.entityjs.builders.living.entityjs.MobBuilder; 5 | import net.liopyu.entityjs.builders.living.entityjs.PathfinderMobBuilder; 6 | import net.liopyu.entityjs.entities.living.entityjs.MobEntityJS; 7 | import net.liopyu.entityjs.entities.living.vanilla.AllayEntityJS; 8 | import net.liopyu.entityjs.entities.living.vanilla.CreeperEntityJS; 9 | import net.minecraft.resources.ResourceLocation; 10 | import net.minecraft.world.entity.EntityType; 11 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 12 | import net.minecraft.world.entity.ai.attributes.Attributes; 13 | 14 | public class AllayJSBuilder extends PathfinderMobBuilder { 15 | 16 | public AllayJSBuilder(ResourceLocation i) { 17 | super(i); 18 | } 19 | 20 | 21 | @Override 22 | public EntityType.EntityFactory factory() { 23 | return (type, level) -> new AllayEntityJS(this, type, level); 24 | } 25 | 26 | @Override 27 | public AttributeSupplier.Builder getAttributeBuilder() { 28 | return MobEntityJS.createMobAttributes() 29 | .add(Attributes.MAX_HEALTH) 30 | .add(Attributes.FOLLOW_RANGE) 31 | .add(Attributes.ATTACK_DAMAGE) 32 | .add(Attributes.ARMOR) 33 | .add(Attributes.ARMOR_TOUGHNESS) 34 | .add(Attributes.ATTACK_SPEED) 35 | .add(Attributes.ATTACK_KNOCKBACK) 36 | .add(Attributes.LUCK) 37 | .add(Attributes.FLYING_SPEED) 38 | .add(Attributes.MOVEMENT_SPEED); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/vanilla/AxolotlJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living.vanilla; 2 | 3 | import dev.latvian.mods.kubejs.typings.Info; 4 | import net.liopyu.entityjs.builders.living.entityjs.AnimalEntityBuilder; 5 | import net.liopyu.entityjs.builders.living.entityjs.MobBuilder; 6 | import net.liopyu.entityjs.builders.living.entityjs.PathfinderMobBuilder; 7 | import net.liopyu.entityjs.entities.living.entityjs.MobEntityJS; 8 | import net.liopyu.entityjs.entities.living.vanilla.AllayEntityJS; 9 | import net.liopyu.entityjs.entities.living.vanilla.AxolotlEntityJS; 10 | import net.liopyu.entityjs.util.ContextUtils; 11 | import net.liopyu.entityjs.util.EntityJSHelperClass; 12 | import net.minecraft.resources.ResourceLocation; 13 | import net.minecraft.world.entity.EntityType; 14 | import net.minecraft.world.entity.LivingEntity; 15 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 16 | import net.minecraft.world.entity.ai.attributes.Attributes; 17 | import net.minecraftforge.common.ForgeMod; 18 | import net.minecraftforge.registries.ForgeRegistries; 19 | 20 | import java.util.function.Function; 21 | 22 | public class AxolotlJSBuilder extends AnimalEntityBuilder { 23 | public transient Function bucketItemStack; 24 | 25 | public AxolotlJSBuilder(ResourceLocation i) { 26 | super(i); 27 | } 28 | 29 | @Info(value = """ 30 | @param bucketItemStack Function returning the itemstack to receive when bucketed 31 | Defaults to Axolotl Bucket 32 | Example usage: 33 | ```javascript 34 | builder.bucketItemStack(entity => { 35 | // Use information about the entity to return an ItemStack. 36 | return Item.of('minecraft:diamond') 37 | }) 38 | ``` 39 | """) 40 | public AxolotlJSBuilder bucketItemStack(Function function) { 41 | this.bucketItemStack = function; 42 | return this; 43 | } 44 | 45 | @Override 46 | public EntityType.EntityFactory factory() { 47 | return (type, level) -> new AxolotlEntityJS(this, type, level); 48 | } 49 | 50 | @Override 51 | public AttributeSupplier.Builder getAttributeBuilder() { 52 | return MobEntityJS.createMobAttributes() 53 | .add(Attributes.MAX_HEALTH) 54 | .add(Attributes.FOLLOW_RANGE) 55 | .add(Attributes.ATTACK_DAMAGE) 56 | .add(Attributes.ARMOR) 57 | .add(Attributes.ARMOR_TOUGHNESS) 58 | .add(Attributes.ATTACK_SPEED) 59 | .add(Attributes.ATTACK_KNOCKBACK) 60 | .add(Attributes.LUCK) 61 | .add(Attributes.FLYING_SPEED) 62 | .add(Attributes.MOVEMENT_SPEED, 1.0) 63 | .add(ForgeMod.SWIM_SPEED.get()); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/vanilla/BatJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living.vanilla; 2 | 3 | import net.liopyu.entityjs.builders.living.entityjs.MobBuilder; 4 | import net.liopyu.entityjs.entities.living.entityjs.MobEntityJS; 5 | import net.liopyu.entityjs.entities.living.vanilla.AllayEntityJS; 6 | import net.liopyu.entityjs.entities.living.vanilla.BatEntityJS; 7 | import net.minecraft.resources.ResourceLocation; 8 | import net.minecraft.world.entity.EntityType; 9 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 10 | import net.minecraft.world.entity.ai.attributes.Attributes; 11 | 12 | public class BatJSBuilder extends MobBuilder { 13 | public BatJSBuilder(ResourceLocation i) { 14 | super(i); 15 | } 16 | 17 | 18 | @Override 19 | public EntityType.EntityFactory factory() { 20 | return (type, level) -> new BatEntityJS(this, type, level); 21 | } 22 | 23 | @Override 24 | public AttributeSupplier.Builder getAttributeBuilder() { 25 | return MobEntityJS.createMobAttributes() 26 | .add(Attributes.MAX_HEALTH) 27 | .add(Attributes.FOLLOW_RANGE) 28 | .add(Attributes.ATTACK_DAMAGE) 29 | .add(Attributes.ARMOR) 30 | .add(Attributes.ARMOR_TOUGHNESS) 31 | .add(Attributes.ATTACK_SPEED) 32 | .add(Attributes.ATTACK_KNOCKBACK) 33 | .add(Attributes.LUCK) 34 | .add(Attributes.FLYING_SPEED) 35 | .add(Attributes.MOVEMENT_SPEED); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/vanilla/BeeJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living.vanilla; 2 | 3 | import dev.latvian.mods.kubejs.typings.Info; 4 | import net.liopyu.entityjs.builders.living.entityjs.AnimalEntityBuilder; 5 | import net.liopyu.entityjs.builders.living.entityjs.PathfinderMobBuilder; 6 | import net.liopyu.entityjs.entities.living.entityjs.MobEntityJS; 7 | import net.liopyu.entityjs.entities.living.vanilla.BeeEntityJS; 8 | import net.liopyu.entityjs.entities.living.vanilla.ZombieEntityJS; 9 | import net.minecraft.resources.ResourceLocation; 10 | import net.minecraft.world.entity.EntityType; 11 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 12 | import net.minecraft.world.entity.ai.attributes.Attributes; 13 | 14 | public class BeeJSBuilder extends AnimalEntityBuilder { 15 | public transient Boolean defaultGoals; 16 | 17 | public BeeJSBuilder(ResourceLocation i) { 18 | super(i); 19 | defaultGoals = true; 20 | } 21 | 22 | @Info(value = """ 23 | @param defaultGoals Sets whether the mob should inherit it's goals from it's superclass 24 | Defaults to true. 25 | 26 | Example usage: 27 | ```javascript 28 | builder.defaultGoals(false); 29 | ``` 30 | """) 31 | public BeeJSBuilder defaultGoals(boolean defaultGoals) { 32 | this.defaultGoals = defaultGoals; 33 | return this; 34 | } 35 | 36 | 37 | @Override 38 | public EntityType.EntityFactory factory() { 39 | return (type, level) -> new BeeEntityJS(this, type, level); 40 | } 41 | 42 | @Override 43 | public AttributeSupplier.Builder getAttributeBuilder() { 44 | return MobEntityJS.createMobAttributes() 45 | .add(Attributes.MAX_HEALTH) 46 | .add(Attributes.FOLLOW_RANGE) 47 | .add(Attributes.ATTACK_DAMAGE) 48 | .add(Attributes.ARMOR) 49 | .add(Attributes.ARMOR_TOUGHNESS) 50 | .add(Attributes.ATTACK_SPEED) 51 | .add(Attributes.ATTACK_KNOCKBACK) 52 | .add(Attributes.LUCK) 53 | .add(Attributes.FLYING_SPEED) 54 | .add(Attributes.MOVEMENT_SPEED); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/vanilla/BlazeJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living.vanilla; 2 | 3 | import dev.latvian.mods.kubejs.typings.Info; 4 | import net.liopyu.entityjs.builders.living.entityjs.PathfinderMobBuilder; 5 | import net.liopyu.entityjs.entities.living.entityjs.MobEntityJS; 6 | import net.liopyu.entityjs.entities.living.vanilla.BeeEntityJS; 7 | import net.liopyu.entityjs.entities.living.vanilla.BlazeEntityJS; 8 | import net.minecraft.resources.ResourceLocation; 9 | import net.minecraft.world.entity.EntityType; 10 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 11 | import net.minecraft.world.entity.ai.attributes.Attributes; 12 | 13 | public class BlazeJSBuilder extends PathfinderMobBuilder { 14 | public transient Boolean defaultGoals; 15 | 16 | public BlazeJSBuilder(ResourceLocation i) { 17 | super(i); 18 | defaultGoals = true; 19 | } 20 | 21 | @Info(value = """ 22 | @param defaultGoals Sets whether the mob should inherit it's goals from it's superclass 23 | Defaults to true. 24 | 25 | Example usage: 26 | ```javascript 27 | builder.defaultGoals(false); 28 | ``` 29 | """) 30 | public BlazeJSBuilder defaultGoals(boolean defaultGoals) { 31 | this.defaultGoals = defaultGoals; 32 | return this; 33 | } 34 | 35 | 36 | @Override 37 | public EntityType.EntityFactory factory() { 38 | return (type, level) -> new BlazeEntityJS(this, type, level); 39 | } 40 | 41 | @Override 42 | public AttributeSupplier.Builder getAttributeBuilder() { 43 | return MobEntityJS.createMobAttributes() 44 | .add(Attributes.MAX_HEALTH) 45 | .add(Attributes.FOLLOW_RANGE) 46 | .add(Attributes.ATTACK_DAMAGE) 47 | .add(Attributes.ARMOR) 48 | .add(Attributes.ARMOR_TOUGHNESS) 49 | .add(Attributes.ATTACK_SPEED) 50 | .add(Attributes.ATTACK_KNOCKBACK) 51 | .add(Attributes.LUCK) 52 | .add(Attributes.FLYING_SPEED) 53 | .add(Attributes.MOVEMENT_SPEED); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/vanilla/CatJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living.vanilla; 2 | 3 | import dev.latvian.mods.kubejs.typings.Info; 4 | import net.liopyu.entityjs.builders.living.entityjs.TameableMobBuilder; 5 | import net.liopyu.entityjs.entities.living.entityjs.MobEntityJS; 6 | import net.liopyu.entityjs.entities.living.vanilla.BatEntityJS; 7 | import net.liopyu.entityjs.entities.living.vanilla.CatEntityJS; 8 | import net.minecraft.resources.ResourceLocation; 9 | import net.minecraft.world.entity.EntityType; 10 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 11 | import net.minecraft.world.entity.ai.attributes.Attributes; 12 | 13 | public class CatJSBuilder extends TameableMobBuilder { 14 | public transient Boolean defaultGoals; 15 | 16 | public CatJSBuilder(ResourceLocation i) { 17 | super(i); 18 | defaultGoals = true; 19 | } 20 | 21 | @Info(value = """ 22 | @param defaultGoals Sets whether the mob should inherit it's goals from it's superclass 23 | Defaults to true. 24 | 25 | Example usage: 26 | ```javascript 27 | builder.defaultGoals(false); 28 | ``` 29 | """) 30 | public CatJSBuilder defaultGoals(boolean defaultGoals) { 31 | this.defaultGoals = defaultGoals; 32 | return this; 33 | } 34 | 35 | @Override 36 | public EntityType.EntityFactory factory() { 37 | return (type, level) -> new CatEntityJS(this, type, level); 38 | } 39 | 40 | @Override 41 | public AttributeSupplier.Builder getAttributeBuilder() { 42 | return MobEntityJS.createMobAttributes() 43 | .add(Attributes.MAX_HEALTH) 44 | .add(Attributes.FOLLOW_RANGE) 45 | .add(Attributes.ATTACK_DAMAGE) 46 | .add(Attributes.ARMOR) 47 | .add(Attributes.ARMOR_TOUGHNESS) 48 | .add(Attributes.ATTACK_SPEED) 49 | .add(Attributes.ATTACK_KNOCKBACK) 50 | .add(Attributes.LUCK) 51 | .add(Attributes.MOVEMENT_SPEED); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/vanilla/CaveSpiderJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living.vanilla; 2 | 3 | import dev.latvian.mods.kubejs.typings.Info; 4 | import net.liopyu.entityjs.builders.living.entityjs.PathfinderMobBuilder; 5 | import net.liopyu.entityjs.entities.living.entityjs.MobEntityJS; 6 | import net.liopyu.entityjs.entities.living.vanilla.CaveSpiderEntityJS; 7 | import net.liopyu.entityjs.entities.living.vanilla.ZombieEntityJS; 8 | import net.minecraft.resources.ResourceLocation; 9 | import net.minecraft.world.entity.EntityType; 10 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 11 | import net.minecraft.world.entity.ai.attributes.Attributes; 12 | 13 | public class CaveSpiderJSBuilder extends PathfinderMobBuilder { 14 | public transient Boolean defaultGoals; 15 | 16 | public CaveSpiderJSBuilder(ResourceLocation i) { 17 | super(i); 18 | defaultGoals = true; 19 | } 20 | 21 | @Info(value = """ 22 | @param defaultGoals Sets whether the mob should inherit it's goals from it's superclass 23 | Defaults to true. 24 | 25 | Example usage: 26 | ```javascript 27 | builder.defaultGoals(false); 28 | ``` 29 | """) 30 | public CaveSpiderJSBuilder defaultGoals(boolean defaultGoals) { 31 | this.defaultGoals = defaultGoals; 32 | return this; 33 | } 34 | 35 | 36 | @Override 37 | public EntityType.EntityFactory factory() { 38 | return (type, level) -> new CaveSpiderEntityJS(this, type, level); 39 | } 40 | 41 | @Override 42 | public AttributeSupplier.Builder getAttributeBuilder() { 43 | return MobEntityJS.createMobAttributes() 44 | .add(Attributes.MAX_HEALTH) 45 | .add(Attributes.FOLLOW_RANGE) 46 | .add(Attributes.ATTACK_DAMAGE) 47 | .add(Attributes.ARMOR) 48 | .add(Attributes.ARMOR_TOUGHNESS) 49 | .add(Attributes.ATTACK_SPEED) 50 | .add(Attributes.ATTACK_KNOCKBACK) 51 | .add(Attributes.LUCK) 52 | .add(Attributes.MOVEMENT_SPEED); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/vanilla/ChickenJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living.vanilla; 2 | 3 | import dev.latvian.mods.kubejs.typings.Info; 4 | import net.liopyu.entityjs.builders.living.entityjs.AnimalEntityBuilder; 5 | import net.liopyu.entityjs.builders.living.entityjs.MobBuilder; 6 | import net.liopyu.entityjs.entities.living.entityjs.MobEntityJS; 7 | import net.liopyu.entityjs.entities.living.vanilla.BeeEntityJS; 8 | import net.liopyu.entityjs.entities.living.vanilla.ChickenEntityJS; 9 | import net.liopyu.entityjs.util.ContextUtils; 10 | import net.minecraft.resources.ResourceLocation; 11 | import net.minecraft.world.entity.EntityType; 12 | import net.minecraft.world.entity.LivingEntity; 13 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 14 | import net.minecraft.world.entity.ai.attributes.Attributes; 15 | 16 | import java.util.function.Function; 17 | 18 | public class ChickenJSBuilder extends AnimalEntityBuilder { 19 | public transient Boolean defaultGoals; 20 | public transient Function eggTime; 21 | 22 | public ChickenJSBuilder(ResourceLocation i) { 23 | super(i); 24 | defaultGoals = true; 25 | } 26 | 27 | @Info(value = """ 28 | @param defaultGoals Sets whether the mob should inherit it's goals from it's superclass 29 | Defaults to true. 30 | 31 | Example usage: 32 | ```javascript 33 | builder.defaultGoals(false); 34 | ``` 35 | """) 36 | public ChickenJSBuilder defaultGoals(boolean defaultGoals) { 37 | this.defaultGoals = defaultGoals; 38 | return this; 39 | } 40 | 41 | @Info(value = """ 42 | @param eggTime Sets a function to determine the laying egg time of the entity 43 | 44 | Example usage: 45 | ```javascript 46 | mobBuilder.eggTime(entity => { 47 | return 100 // returning 100 here will result in the entity laying an egg every 100 ticks 48 | }); 49 | ``` 50 | """) 51 | public ChickenJSBuilder eggTime(Function eggTime) { 52 | this.eggTime = eggTime; 53 | return this; 54 | } 55 | 56 | @Override 57 | public EntityType.EntityFactory factory() { 58 | return (type, level) -> new ChickenEntityJS(this, type, level); 59 | } 60 | 61 | @Override 62 | public AttributeSupplier.Builder getAttributeBuilder() { 63 | return MobEntityJS.createMobAttributes() 64 | .add(Attributes.MAX_HEALTH) 65 | .add(Attributes.FOLLOW_RANGE) 66 | .add(Attributes.ATTACK_DAMAGE) 67 | .add(Attributes.ARMOR) 68 | .add(Attributes.ARMOR_TOUGHNESS) 69 | .add(Attributes.ATTACK_SPEED) 70 | .add(Attributes.ATTACK_KNOCKBACK) 71 | .add(Attributes.LUCK) 72 | .add(Attributes.FLYING_SPEED) 73 | .add(Attributes.MOVEMENT_SPEED); 74 | } 75 | } 76 | 77 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/vanilla/CowJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living.vanilla; 2 | 3 | import dev.latvian.mods.kubejs.typings.Info; 4 | import net.liopyu.entityjs.builders.living.entityjs.AnimalEntityBuilder; 5 | import net.liopyu.entityjs.builders.living.entityjs.AnimalEntityJSBuilder; 6 | import net.liopyu.entityjs.entities.living.entityjs.MobEntityJS; 7 | import net.liopyu.entityjs.entities.living.vanilla.CowEntityJS; 8 | import net.liopyu.entityjs.entities.living.vanilla.ZombieEntityJS; 9 | import net.minecraft.resources.ResourceLocation; 10 | import net.minecraft.world.entity.EntityType; 11 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 12 | import net.minecraft.world.entity.ai.attributes.Attributes; 13 | 14 | public class CowJSBuilder extends AnimalEntityBuilder { 15 | public transient Boolean defaultGoals; 16 | 17 | public CowJSBuilder(ResourceLocation i) { 18 | super(i); 19 | defaultGoals = true; 20 | } 21 | 22 | @Info(value = """ 23 | @param defaultGoals Sets whether the mob should inherit it's goals from it's superclass 24 | Defaults to true. 25 | 26 | Example usage: 27 | ```javascript 28 | builder.defaultGoals(false); 29 | ``` 30 | """) 31 | public CowJSBuilder defaultGoals(boolean defaultGoals) { 32 | this.defaultGoals = defaultGoals; 33 | return this; 34 | } 35 | 36 | 37 | @Override 38 | public EntityType.EntityFactory factory() { 39 | return (type, level) -> new CowEntityJS(this, type, level); 40 | } 41 | 42 | @Override 43 | public AttributeSupplier.Builder getAttributeBuilder() { 44 | return MobEntityJS.createMobAttributes() 45 | .add(Attributes.MAX_HEALTH) 46 | .add(Attributes.FOLLOW_RANGE) 47 | .add(Attributes.ATTACK_DAMAGE) 48 | .add(Attributes.ARMOR) 49 | .add(Attributes.ARMOR_TOUGHNESS) 50 | .add(Attributes.ATTACK_SPEED) 51 | .add(Attributes.ATTACK_KNOCKBACK) 52 | .add(Attributes.LUCK) 53 | .add(Attributes.MOVEMENT_SPEED); 54 | } 55 | } -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/vanilla/CreeperJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living.vanilla; 2 | 3 | import dev.latvian.mods.kubejs.typings.Info; 4 | import net.liopyu.entityjs.builders.living.entityjs.MobBuilder; 5 | import net.liopyu.entityjs.builders.living.entityjs.PathfinderMobBuilder; 6 | import net.liopyu.entityjs.entities.living.entityjs.MobEntityJS; 7 | import net.liopyu.entityjs.entities.living.vanilla.CreeperEntityJS; 8 | import net.minecraft.resources.ResourceLocation; 9 | import net.minecraft.world.entity.EntityType; 10 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 11 | import net.minecraft.world.entity.ai.attributes.Attributes; 12 | 13 | 14 | public class CreeperJSBuilder extends PathfinderMobBuilder { 15 | public transient boolean defaultGoals; 16 | 17 | public CreeperJSBuilder(ResourceLocation i) { 18 | super(i); 19 | this.defaultGoals = true; 20 | } 21 | 22 | @Info(value = """ 23 | @param defaultGoals Sets whether the mob should inherit it's goals from it's superclass 24 | Defaults to true. 25 | 26 | Example usage: 27 | ```javascript 28 | builder.defaultGoals(false); 29 | ``` 30 | """) 31 | public CreeperJSBuilder defaultGoals(boolean defaultGoals) { 32 | this.defaultGoals = defaultGoals; 33 | return this; 34 | } 35 | 36 | @Override 37 | public EntityType.EntityFactory factory() { 38 | return (type, level) -> new CreeperEntityJS(this, type, level); 39 | } 40 | 41 | @Override 42 | public AttributeSupplier.Builder getAttributeBuilder() { 43 | return MobEntityJS.createMobAttributes() 44 | .add(Attributes.MAX_HEALTH) 45 | .add(Attributes.FOLLOW_RANGE) 46 | .add(Attributes.ATTACK_DAMAGE) 47 | .add(Attributes.ARMOR) 48 | .add(Attributes.ARMOR_TOUGHNESS) 49 | .add(Attributes.ATTACK_SPEED) 50 | .add(Attributes.ATTACK_KNOCKBACK) 51 | .add(Attributes.LUCK) 52 | .add(Attributes.MOVEMENT_SPEED); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/vanilla/DolphinJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living.vanilla; 2 | 3 | import dev.latvian.mods.kubejs.typings.Info; 4 | import net.liopyu.entityjs.builders.living.entityjs.AnimalEntityBuilder; 5 | import net.liopyu.entityjs.builders.living.entityjs.PathfinderMobBuilder; 6 | import net.liopyu.entityjs.entities.living.entityjs.MobEntityJS; 7 | import net.liopyu.entityjs.entities.living.vanilla.CreeperEntityJS; 8 | import net.liopyu.entityjs.entities.living.vanilla.DolphinEntityJS; 9 | import net.minecraft.resources.ResourceLocation; 10 | import net.minecraft.world.entity.EntityType; 11 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 12 | import net.minecraft.world.entity.ai.attributes.Attributes; 13 | 14 | public class DolphinJSBuilder extends PathfinderMobBuilder { 15 | public transient boolean defaultGoals; 16 | 17 | public DolphinJSBuilder(ResourceLocation i) { 18 | super(i); 19 | this.defaultGoals = true; 20 | } 21 | 22 | @Info(value = """ 23 | @param defaultGoals Sets whether the mob should inherit it's goals from it's superclass 24 | Defaults to true. 25 | 26 | Example usage: 27 | ```javascript 28 | builder.defaultGoals(false); 29 | ``` 30 | """) 31 | public DolphinJSBuilder defaultGoals(boolean defaultGoals) { 32 | this.defaultGoals = defaultGoals; 33 | return this; 34 | } 35 | 36 | @Override 37 | public EntityType.EntityFactory factory() { 38 | return (type, level) -> new DolphinEntityJS(this, type, level); 39 | } 40 | 41 | @Override 42 | public AttributeSupplier.Builder getAttributeBuilder() { 43 | return MobEntityJS.createMobAttributes() 44 | .add(Attributes.MAX_HEALTH) 45 | .add(Attributes.FOLLOW_RANGE) 46 | .add(Attributes.ATTACK_DAMAGE) 47 | .add(Attributes.ARMOR) 48 | .add(Attributes.ARMOR_TOUGHNESS) 49 | .add(Attributes.ATTACK_SPEED) 50 | .add(Attributes.ATTACK_KNOCKBACK) 51 | .add(Attributes.LUCK) 52 | .add(Attributes.MOVEMENT_SPEED); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/vanilla/DonkeyJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living.vanilla; 2 | 3 | import dev.latvian.mods.kubejs.typings.Info; 4 | import net.liopyu.entityjs.builders.living.entityjs.AnimalEntityBuilder; 5 | import net.liopyu.entityjs.entities.living.entityjs.MobEntityJS; 6 | import net.liopyu.entityjs.entities.living.vanilla.DolphinEntityJS; 7 | import net.liopyu.entityjs.entities.living.vanilla.DonkeyEntityJS; 8 | import net.minecraft.resources.ResourceLocation; 9 | import net.minecraft.world.entity.EntityType; 10 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 11 | import net.minecraft.world.entity.ai.attributes.Attributes; 12 | 13 | public class DonkeyJSBuilder extends AnimalEntityBuilder { 14 | public transient boolean defaultGoals; 15 | public transient Boolean defaultBehaviourGoals; 16 | 17 | public DonkeyJSBuilder(ResourceLocation i) { 18 | super(i); 19 | this.defaultGoals = true; 20 | defaultBehaviourGoals = true; 21 | } 22 | 23 | @Info(value = """ 24 | @param defaultBehaviourGoals Sets whether the mob should inherit it's goal behavior from it's superclass 25 | Defaults to true. 26 | 27 | Example usage: 28 | ```javascript 29 | builder.defaultBehaviourGoals(false); 30 | ``` 31 | """) 32 | public DonkeyJSBuilder defaultBehaviourGoals(boolean defaultBehaviourGoals) { 33 | this.defaultBehaviourGoals = defaultBehaviourGoals; 34 | return this; 35 | } 36 | 37 | @Info(value = """ 38 | @param defaultGoals Sets whether the mob should inherit it's goals from it's superclass 39 | Defaults to true. 40 | 41 | Example usage: 42 | ```javascript 43 | builder.defaultGoals(false); 44 | ``` 45 | """) 46 | public DonkeyJSBuilder defaultGoals(boolean defaultGoals) { 47 | this.defaultGoals = defaultGoals; 48 | return this; 49 | } 50 | 51 | @Override 52 | public EntityType.EntityFactory factory() { 53 | return (type, level) -> new DonkeyEntityJS(this, type, level); 54 | } 55 | 56 | @Override 57 | public AttributeSupplier.Builder getAttributeBuilder() { 58 | return MobEntityJS.createMobAttributes() 59 | .add(Attributes.MAX_HEALTH) 60 | .add(Attributes.FOLLOW_RANGE) 61 | .add(Attributes.ATTACK_DAMAGE) 62 | .add(Attributes.ARMOR) 63 | .add(Attributes.ARMOR_TOUGHNESS) 64 | .add(Attributes.ATTACK_SPEED) 65 | .add(Attributes.ATTACK_KNOCKBACK) 66 | .add(Attributes.LUCK) 67 | .add(Attributes.MOVEMENT_SPEED); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/vanilla/EnderManJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living.vanilla; 2 | 3 | import dev.latvian.mods.kubejs.typings.Info; 4 | import net.liopyu.entityjs.builders.living.entityjs.PathfinderMobBuilder; 5 | import net.liopyu.entityjs.entities.living.entityjs.MobEntityJS; 6 | import net.liopyu.entityjs.entities.living.vanilla.EnderManEntityJS; 7 | import net.liopyu.entityjs.entities.living.vanilla.ZombieEntityJS; 8 | import net.minecraft.resources.ResourceLocation; 9 | import net.minecraft.world.entity.EntityType; 10 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 11 | import net.minecraft.world.entity.ai.attributes.Attributes; 12 | 13 | public class EnderManJSBuilder extends PathfinderMobBuilder { 14 | public transient Boolean defaultGoals; 15 | 16 | public EnderManJSBuilder(ResourceLocation i) { 17 | super(i); 18 | defaultGoals = true; 19 | } 20 | 21 | @Info(value = """ 22 | @param defaultGoals Sets whether the mob should inherit it's goals from it's superclass 23 | Defaults to true. 24 | 25 | Example usage: 26 | ```javascript 27 | builder.defaultGoals(false); 28 | ``` 29 | """) 30 | public EnderManJSBuilder defaultGoals(boolean defaultGoals) { 31 | this.defaultGoals = defaultGoals; 32 | return this; 33 | } 34 | 35 | 36 | @Override 37 | public EntityType.EntityFactory factory() { 38 | return (type, level) -> new EnderManEntityJS(this, type, level); 39 | } 40 | 41 | @Override 42 | public AttributeSupplier.Builder getAttributeBuilder() { 43 | return MobEntityJS.createMobAttributes() 44 | .add(Attributes.MAX_HEALTH) 45 | .add(Attributes.FOLLOW_RANGE) 46 | .add(Attributes.ATTACK_DAMAGE) 47 | .add(Attributes.ARMOR) 48 | .add(Attributes.ARMOR_TOUGHNESS) 49 | .add(Attributes.ATTACK_SPEED) 50 | .add(Attributes.ATTACK_KNOCKBACK) 51 | .add(Attributes.LUCK) 52 | .add(Attributes.SPAWN_REINFORCEMENTS_CHANCE) 53 | .add(Attributes.MOVEMENT_SPEED); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/vanilla/EvokerJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living.vanilla; 2 | 3 | import dev.latvian.mods.kubejs.typings.Info; 4 | import net.liopyu.entityjs.builders.living.entityjs.PathfinderMobBuilder; 5 | import net.liopyu.entityjs.entities.living.entityjs.MobEntityJS; 6 | import net.liopyu.entityjs.entities.living.vanilla.EnderManEntityJS; 7 | import net.liopyu.entityjs.entities.living.vanilla.EvokerEntityJS; 8 | import net.minecraft.resources.ResourceLocation; 9 | import net.minecraft.world.entity.EntityType; 10 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 11 | import net.minecraft.world.entity.ai.attributes.Attributes; 12 | 13 | public class EvokerJSBuilder extends PathfinderMobBuilder { 14 | public transient Boolean defaultGoals; 15 | 16 | public EvokerJSBuilder(ResourceLocation i) { 17 | super(i); 18 | defaultGoals = true; 19 | } 20 | 21 | @Info(value = """ 22 | @param defaultGoals Sets whether the mob should inherit it's goals from it's superclass 23 | Defaults to true. 24 | 25 | Example usage: 26 | ```javascript 27 | builder.defaultGoals(false); 28 | ``` 29 | """) 30 | public EvokerJSBuilder defaultGoals(boolean defaultGoals) { 31 | this.defaultGoals = defaultGoals; 32 | return this; 33 | } 34 | 35 | 36 | @Override 37 | public EntityType.EntityFactory factory() { 38 | return (type, level) -> new EvokerEntityJS(this, type, level); 39 | } 40 | 41 | @Override 42 | public AttributeSupplier.Builder getAttributeBuilder() { 43 | return MobEntityJS.createMobAttributes() 44 | .add(Attributes.MAX_HEALTH) 45 | .add(Attributes.FOLLOW_RANGE) 46 | .add(Attributes.ATTACK_DAMAGE) 47 | .add(Attributes.ARMOR) 48 | .add(Attributes.ARMOR_TOUGHNESS) 49 | .add(Attributes.ATTACK_SPEED) 50 | .add(Attributes.ATTACK_KNOCKBACK) 51 | .add(Attributes.LUCK) 52 | .add(Attributes.SPAWN_REINFORCEMENTS_CHANCE) 53 | .add(Attributes.MOVEMENT_SPEED); 54 | } 55 | } 56 | 57 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/vanilla/GhastJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living.vanilla; 2 | 3 | import dev.latvian.mods.kubejs.typings.Info; 4 | import net.liopyu.entityjs.builders.living.entityjs.MobBuilder; 5 | import net.liopyu.entityjs.entities.living.entityjs.MobEntityJS; 6 | import net.liopyu.entityjs.entities.living.vanilla.EvokerEntityJS; 7 | import net.liopyu.entityjs.entities.living.vanilla.GhastEntityJS; 8 | import net.minecraft.resources.ResourceLocation; 9 | import net.minecraft.world.entity.EntityType; 10 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 11 | import net.minecraft.world.entity.ai.attributes.Attributes; 12 | 13 | public class GhastJSBuilder extends MobBuilder { 14 | public transient Boolean defaultGoals; 15 | 16 | public GhastJSBuilder(ResourceLocation i) { 17 | super(i); 18 | defaultGoals = true; 19 | } 20 | 21 | @Info(value = """ 22 | @param defaultGoals Sets whether the mob should inherit it's goals from it's superclass 23 | Defaults to true. 24 | 25 | Example usage: 26 | ```javascript 27 | builder.defaultGoals(false); 28 | ``` 29 | """) 30 | public GhastJSBuilder defaultGoals(boolean defaultGoals) { 31 | this.defaultGoals = defaultGoals; 32 | return this; 33 | } 34 | 35 | 36 | @Override 37 | public EntityType.EntityFactory factory() { 38 | return (type, level) -> new GhastEntityJS(this, type, level); 39 | } 40 | 41 | @Override 42 | public AttributeSupplier.Builder getAttributeBuilder() { 43 | return MobEntityJS.createMobAttributes() 44 | .add(Attributes.MAX_HEALTH) 45 | .add(Attributes.FOLLOW_RANGE) 46 | .add(Attributes.ATTACK_DAMAGE) 47 | .add(Attributes.ARMOR) 48 | .add(Attributes.ARMOR_TOUGHNESS) 49 | .add(Attributes.ATTACK_SPEED) 50 | .add(Attributes.ATTACK_KNOCKBACK) 51 | .add(Attributes.LUCK) 52 | .add(Attributes.MOVEMENT_SPEED); 53 | } 54 | } 55 | 56 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/vanilla/GoatJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living.vanilla; 2 | 3 | import dev.latvian.mods.kubejs.typings.Info; 4 | import net.liopyu.entityjs.builders.living.entityjs.AnimalEntityBuilder; 5 | import net.liopyu.entityjs.entities.living.entityjs.MobEntityJS; 6 | import net.liopyu.entityjs.entities.living.vanilla.EvokerEntityJS; 7 | import net.liopyu.entityjs.entities.living.vanilla.GoatEntityJS; 8 | import net.minecraft.resources.ResourceLocation; 9 | import net.minecraft.world.entity.EntityType; 10 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 11 | import net.minecraft.world.entity.ai.attributes.Attributes; 12 | 13 | public class GoatJSBuilder extends AnimalEntityBuilder { 14 | public transient Boolean defaultGoals; 15 | 16 | public GoatJSBuilder(ResourceLocation i) { 17 | super(i); 18 | defaultGoals = true; 19 | } 20 | 21 | @Info(value = """ 22 | @param defaultGoals Sets whether the mob should inherit it's goals from it's superclass 23 | Defaults to true. 24 | 25 | Example usage: 26 | ```javascript 27 | builder.defaultGoals(false); 28 | ``` 29 | """) 30 | public GoatJSBuilder defaultGoals(boolean defaultGoals) { 31 | this.defaultGoals = defaultGoals; 32 | return this; 33 | } 34 | 35 | 36 | @Override 37 | public EntityType.EntityFactory factory() { 38 | return (type, level) -> new GoatEntityJS(this, type, level); 39 | } 40 | 41 | @Override 42 | public AttributeSupplier.Builder getAttributeBuilder() { 43 | return MobEntityJS.createMobAttributes() 44 | .add(Attributes.MAX_HEALTH) 45 | .add(Attributes.FOLLOW_RANGE) 46 | .add(Attributes.ATTACK_DAMAGE) 47 | .add(Attributes.ARMOR) 48 | .add(Attributes.ARMOR_TOUGHNESS) 49 | .add(Attributes.ATTACK_SPEED) 50 | .add(Attributes.ATTACK_KNOCKBACK) 51 | .add(Attributes.LUCK) 52 | .add(Attributes.MOVEMENT_SPEED); 53 | } 54 | } 55 | 56 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/vanilla/GuardianJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living.vanilla; 2 | 3 | import dev.latvian.mods.kubejs.typings.Info; 4 | import net.liopyu.entityjs.builders.living.entityjs.PathfinderMobBuilder; 5 | import net.liopyu.entityjs.entities.living.entityjs.MobEntityJS; 6 | import net.liopyu.entityjs.entities.living.vanilla.GoatEntityJS; 7 | import net.liopyu.entityjs.entities.living.vanilla.GuardianEntityJS; 8 | import net.minecraft.resources.ResourceLocation; 9 | import net.minecraft.world.entity.EntityType; 10 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 11 | import net.minecraft.world.entity.ai.attributes.Attributes; 12 | 13 | public class GuardianJSBuilder extends PathfinderMobBuilder { 14 | public transient Boolean defaultGoals; 15 | 16 | public GuardianJSBuilder(ResourceLocation i) { 17 | super(i); 18 | defaultGoals = true; 19 | } 20 | 21 | @Info(value = """ 22 | @param defaultGoals Sets whether the mob should inherit it's goals from it's superclass 23 | Defaults to true. 24 | 25 | Example usage: 26 | ```javascript 27 | builder.defaultGoals(false); 28 | ``` 29 | """) 30 | public GuardianJSBuilder defaultGoals(boolean defaultGoals) { 31 | this.defaultGoals = defaultGoals; 32 | return this; 33 | } 34 | 35 | 36 | @Override 37 | public EntityType.EntityFactory factory() { 38 | return (type, level) -> new GuardianEntityJS(this, type, level); 39 | } 40 | 41 | @Override 42 | public AttributeSupplier.Builder getAttributeBuilder() { 43 | return MobEntityJS.createMobAttributes() 44 | .add(Attributes.MAX_HEALTH) 45 | .add(Attributes.FOLLOW_RANGE) 46 | .add(Attributes.ATTACK_DAMAGE) 47 | .add(Attributes.ARMOR) 48 | .add(Attributes.ARMOR_TOUGHNESS) 49 | .add(Attributes.ATTACK_SPEED) 50 | .add(Attributes.ATTACK_KNOCKBACK) 51 | .add(Attributes.LUCK) 52 | .add(Attributes.MOVEMENT_SPEED); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/vanilla/IllusionerJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living.vanilla; 2 | 3 | import dev.latvian.mods.kubejs.typings.Info; 4 | import net.liopyu.entityjs.builders.living.entityjs.MobBuilder; 5 | import net.liopyu.entityjs.builders.living.entityjs.PathfinderMobBuilder; 6 | import net.liopyu.entityjs.entities.living.entityjs.MobEntityJS; 7 | import net.liopyu.entityjs.entities.living.vanilla.EvokerEntityJS; 8 | import net.liopyu.entityjs.entities.living.vanilla.IllusionerEntityJS; 9 | import net.liopyu.entityjs.util.EntityJSHelperClass; 10 | import net.minecraft.resources.ResourceLocation; 11 | import net.minecraft.world.entity.EntityType; 12 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 13 | import net.minecraft.world.entity.ai.attributes.Attributes; 14 | 15 | public class IllusionerJSBuilder extends PathfinderMobBuilder { 16 | public transient Boolean defaultGoals; 17 | public transient Object setCelebrateSound; 18 | 19 | public IllusionerJSBuilder(ResourceLocation i) { 20 | super(i); 21 | defaultGoals = true; 22 | } 23 | 24 | @Info(value = """ 25 | Sets the sound to play when the entity is celebrating using either a string representation or a ResourceLocation object. 26 | 27 | Example usage: 28 | ```javascript 29 | mobBuilder.setCelebrateSound("minecraft:entity.zombie.ambient"); 30 | ``` 31 | """) 32 | public IllusionerJSBuilder setCelebrateSound(Object ambientSound) { 33 | if (ambientSound instanceof String) { 34 | this.setCelebrateSound = new ResourceLocation((String) ambientSound); 35 | } else if (ambientSound instanceof ResourceLocation resourceLocation) { 36 | this.setCelebrateSound = resourceLocation; 37 | } else { 38 | EntityJSHelperClass.logErrorMessageOnce("[EntityJS]: Invalid value for setCelebrateSound. Value: " + ambientSound + ". Must be a ResourceLocation or String. Example: \"minecraft:entity.zombie.ambient\""); 39 | this.setCelebrateSound = null; 40 | } 41 | return this; 42 | } 43 | 44 | @Info(value = """ 45 | @param defaultGoals Sets whether the mob should inherit it's goals from it's superclass 46 | Defaults to true. 47 | 48 | Example usage: 49 | ```javascript 50 | builder.defaultGoals(false); 51 | ``` 52 | """) 53 | public IllusionerJSBuilder defaultGoals(boolean defaultGoals) { 54 | this.defaultGoals = defaultGoals; 55 | return this; 56 | } 57 | 58 | 59 | @Override 60 | public EntityType.EntityFactory factory() { 61 | return (type, level) -> new IllusionerEntityJS(this, type, level); 62 | } 63 | 64 | @Override 65 | public AttributeSupplier.Builder getAttributeBuilder() { 66 | return MobEntityJS.createMobAttributes() 67 | .add(Attributes.MAX_HEALTH) 68 | .add(Attributes.FOLLOW_RANGE) 69 | .add(Attributes.ATTACK_DAMAGE) 70 | .add(Attributes.ARMOR) 71 | .add(Attributes.ARMOR_TOUGHNESS) 72 | .add(Attributes.ATTACK_SPEED) 73 | .add(Attributes.ATTACK_KNOCKBACK) 74 | .add(Attributes.LUCK) 75 | .add(Attributes.MOVEMENT_SPEED); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/vanilla/IronGolemJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living.vanilla; 2 | 3 | import dev.latvian.mods.kubejs.typings.Info; 4 | import net.liopyu.entityjs.builders.living.entityjs.PathfinderMobBuilder; 5 | import net.liopyu.entityjs.entities.living.entityjs.MobEntityJS; 6 | import net.liopyu.entityjs.entities.living.vanilla.IronGolemEntityJS; 7 | import net.liopyu.entityjs.entities.living.vanilla.ZombieEntityJS; 8 | import net.minecraft.resources.ResourceLocation; 9 | import net.minecraft.world.entity.EntityType; 10 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 11 | import net.minecraft.world.entity.ai.attributes.Attributes; 12 | 13 | public class IronGolemJSBuilder extends PathfinderMobBuilder { 14 | public transient Boolean defaultGoals; 15 | 16 | public IronGolemJSBuilder(ResourceLocation i) { 17 | super(i); 18 | defaultGoals = true; 19 | } 20 | 21 | @Info(value = """ 22 | @param defaultGoals Sets whether the mob should inherit it's goals from it's superclass 23 | Defaults to true. 24 | 25 | Example usage: 26 | ```javascript 27 | builder.defaultGoals(false); 28 | ``` 29 | """) 30 | public IronGolemJSBuilder defaultGoals(boolean defaultGoals) { 31 | this.defaultGoals = defaultGoals; 32 | return this; 33 | } 34 | 35 | @Override 36 | public EntityType.EntityFactory factory() { 37 | return (type, level) -> new IronGolemEntityJS(this, type, level); 38 | } 39 | 40 | @Override 41 | public AttributeSupplier.Builder getAttributeBuilder() { 42 | return MobEntityJS.createMobAttributes() 43 | .add(Attributes.MAX_HEALTH) 44 | .add(Attributes.FOLLOW_RANGE) 45 | .add(Attributes.ATTACK_DAMAGE) 46 | .add(Attributes.ARMOR) 47 | .add(Attributes.ARMOR_TOUGHNESS) 48 | .add(Attributes.ATTACK_SPEED) 49 | .add(Attributes.ATTACK_KNOCKBACK) 50 | .add(Attributes.LUCK) 51 | .add(Attributes.MOVEMENT_SPEED); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/vanilla/PandaJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living.vanilla; 2 | 3 | import dev.latvian.mods.kubejs.typings.Info; 4 | import net.liopyu.entityjs.builders.living.entityjs.AnimalEntityBuilder; 5 | import net.liopyu.entityjs.entities.living.entityjs.MobEntityJS; 6 | import net.liopyu.entityjs.entities.living.vanilla.IllusionerEntityJS; 7 | import net.liopyu.entityjs.entities.living.vanilla.PandaEntityJS; 8 | import net.minecraft.resources.ResourceLocation; 9 | import net.minecraft.world.entity.EntityType; 10 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 11 | import net.minecraft.world.entity.ai.attributes.Attributes; 12 | 13 | public class PandaJSBuilder extends AnimalEntityBuilder { 14 | public transient Boolean defaultGoals; 15 | 16 | public PandaJSBuilder(ResourceLocation i) { 17 | super(i); 18 | defaultGoals = true; 19 | } 20 | 21 | @Info(value = """ 22 | @param defaultGoals Sets whether the mob should inherit it's goals from it's superclass 23 | Defaults to true. 24 | 25 | Example usage: 26 | ```javascript 27 | builder.defaultGoals(false); 28 | ``` 29 | """) 30 | public PandaJSBuilder defaultGoals(boolean defaultGoals) { 31 | this.defaultGoals = defaultGoals; 32 | return this; 33 | } 34 | 35 | 36 | @Override 37 | public EntityType.EntityFactory factory() { 38 | return (type, level) -> new PandaEntityJS(this, type, level); 39 | } 40 | 41 | @Override 42 | public AttributeSupplier.Builder getAttributeBuilder() { 43 | return MobEntityJS.createMobAttributes() 44 | .add(Attributes.MAX_HEALTH) 45 | .add(Attributes.FOLLOW_RANGE) 46 | .add(Attributes.ATTACK_DAMAGE) 47 | .add(Attributes.ARMOR) 48 | .add(Attributes.ARMOR_TOUGHNESS) 49 | .add(Attributes.ATTACK_SPEED) 50 | .add(Attributes.ATTACK_KNOCKBACK) 51 | .add(Attributes.LUCK) 52 | .add(Attributes.MOVEMENT_SPEED); 53 | } 54 | } 55 | 56 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/vanilla/ParrotJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living.vanilla; 2 | 3 | import dev.latvian.mods.kubejs.typings.Info; 4 | import net.liopyu.entityjs.builders.living.entityjs.TameableMobBuilder; 5 | import net.liopyu.entityjs.entities.living.entityjs.MobEntityJS; 6 | import net.liopyu.entityjs.entities.living.vanilla.HorseEntityJS; 7 | import net.liopyu.entityjs.entities.living.vanilla.ParrotEntityJS; 8 | import net.liopyu.entityjs.util.ContextUtils; 9 | import net.minecraft.resources.ResourceLocation; 10 | import net.minecraft.world.entity.EntityType; 11 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 12 | import net.minecraft.world.entity.ai.attributes.Attributes; 13 | 14 | import java.util.function.Consumer; 15 | 16 | public class ParrotJSBuilder extends TameableMobBuilder { 17 | public transient Consumer onTamed; 18 | public transient Consumer tameOverride; 19 | public transient Boolean defaultGoals; 20 | 21 | public ParrotJSBuilder(ResourceLocation i) { 22 | super(i); 23 | defaultGoals = true; 24 | } 25 | 26 | @Info(value = """ 27 | Sets a Consumer invoked after the entity is tamed 28 | and replaces the logic used to set the UUID of the owner 29 | with the parameter of ContextUtils.PlayerEntityContext callback 30 | 31 | @param tameOverride A Consumer responsible for determining the uuid to set when the entity is tamed. 32 | 33 | Example usage: 34 | ```javascript 35 | builder.tameOverride(context => { 36 | const {entity,player} = context 37 | // Mimic the vanilla way of setting the uuid when the entity is tamed. 38 | entity.setOwnerUUID(player.getUUID()); 39 | }); 40 | ``` 41 | """) 42 | public ParrotJSBuilder tameOverride(Consumer tameOverride) { 43 | this.tameOverride = tameOverride; 44 | return this; 45 | } 46 | 47 | @Info(value = """ 48 | Sets a Consumer with the parameter of ContextUtils.PlayerEntityContext callback 49 | This is fired after the entity is tamed and all tame logic has already taken place. 50 | Useful if you don't want to mess with the UUID logic in the tameOverride method. 51 | 52 | @param onTamed A Consumer that fires when the entity is tamed. 53 | 54 | Example usage: 55 | ```javascript 56 | builder.onTamed(entity => { 57 | // Do stuff when the entity is tamed. 58 | }); 59 | ``` 60 | """) 61 | public ParrotJSBuilder onTamed(Consumer onTamed) { 62 | this.onTamed = onTamed; 63 | return this; 64 | } 65 | 66 | @Info(value = """ 67 | @param defaultGoals Sets whether the mob should inherit it's goals from it's superclass 68 | Defaults to true. 69 | 70 | Example usage: 71 | ```javascript 72 | builder.defaultGoals(false); 73 | ``` 74 | """) 75 | public ParrotJSBuilder defaultGoals(boolean defaultGoals) { 76 | this.defaultGoals = defaultGoals; 77 | return this; 78 | } 79 | 80 | 81 | @Override 82 | public EntityType.EntityFactory factory() { 83 | return (type, level) -> new ParrotEntityJS(this, type, level); 84 | } 85 | 86 | @Override 87 | public AttributeSupplier.Builder getAttributeBuilder() { 88 | return MobEntityJS.createMobAttributes() 89 | .add(Attributes.MAX_HEALTH) 90 | .add(Attributes.FOLLOW_RANGE) 91 | .add(Attributes.ATTACK_DAMAGE) 92 | .add(Attributes.ARMOR) 93 | .add(Attributes.ARMOR_TOUGHNESS) 94 | .add(Attributes.ATTACK_SPEED) 95 | .add(Attributes.ATTACK_KNOCKBACK) 96 | .add(Attributes.LUCK) 97 | .add(Attributes.MOVEMENT_SPEED); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/vanilla/PiglinJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living.vanilla; 2 | 3 | import dev.latvian.mods.kubejs.typings.Info; 4 | import net.liopyu.entityjs.builders.living.entityjs.MobBuilder; 5 | import net.liopyu.entityjs.builders.living.entityjs.PathfinderMobBuilder; 6 | import net.liopyu.entityjs.entities.living.vanilla.BlazeEntityJS; 7 | import net.liopyu.entityjs.entities.living.vanilla.PiglinEntityJS; 8 | import net.liopyu.entityjs.util.ContextUtils; 9 | import net.minecraft.resources.ResourceLocation; 10 | import net.minecraft.world.entity.EntityType; 11 | import net.minecraft.world.entity.LivingEntity; 12 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 13 | 14 | import java.util.function.Consumer; 15 | import java.util.function.Function; 16 | 17 | public class PiglinJSBuilder extends PathfinderMobBuilder { 18 | public transient Boolean defaultGoals; 19 | public transient Function isConverting; 20 | public transient Consumer finishConversion; 21 | 22 | public PiglinJSBuilder(ResourceLocation i) { 23 | super(i); 24 | defaultGoals = true; 25 | } 26 | 27 | @Info(value = """ 28 | Sets a consumer responsible for spawning an entity after the mob has converted. 29 | 30 | @param finishConversion A Function accepting an entity parameter 31 | 32 | Example usage: 33 | ```javascript 34 | mobBuilder.finishConversion(entity => { 35 | //Convert to a ghast instead of a zombified piglin when in the overworld 36 | let EntityType = Java.loadClass("net.minecraft.world.entity.EntityType"); 37 | entity.convertTo(EntityType.GHAST, true); 38 | }); 39 | ``` 40 | """) 41 | public PiglinJSBuilder finishConversion(Consumer finishConversion) { 42 | this.finishConversion = finishConversion; 43 | return this; 44 | } 45 | 46 | @Info(value = """ 47 | Sets a function to determine if the entity is converting. 48 | 49 | @param isConverting A Function accepting an entity parameter 50 | 51 | Example usage: 52 | ```javascript 53 | mobBuilder.isConverting(entity => { 54 | return entity.age > 500; 55 | }); 56 | ``` 57 | """) 58 | public PiglinJSBuilder isConverting(Function isConverting) { 59 | this.isConverting = isConverting; 60 | return this; 61 | } 62 | 63 | @Info(value = """ 64 | @param defaultGoals Sets whether the mob should inherit it's goals from it's superclass 65 | Defaults to true. 66 | 67 | Example usage: 68 | ```javascript 69 | builder.defaultGoals(false); 70 | ``` 71 | """) 72 | public PiglinJSBuilder defaultGoals(boolean defaultGoals) { 73 | this.defaultGoals = defaultGoals; 74 | return this; 75 | } 76 | 77 | 78 | @Override 79 | public EntityType.EntityFactory factory() { 80 | return (type, level) -> new PiglinEntityJS(this, type, level); 81 | } 82 | 83 | @Override 84 | public AttributeSupplier.Builder getAttributeBuilder() { 85 | return PiglinEntityJS.createAttributes(); 86 | } 87 | } -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/vanilla/SlimeJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living.vanilla; 2 | 3 | import dev.latvian.mods.kubejs.typings.Info; 4 | import net.liopyu.entityjs.builders.living.entityjs.MobBuilder; 5 | import net.liopyu.entityjs.entities.living.vanilla.SlimeEntityJS; 6 | import net.liopyu.entityjs.util.ContextUtils; 7 | import net.minecraft.core.particles.ParticleOptions; 8 | import net.minecraft.core.particles.ParticleType; 9 | import net.minecraft.resources.ResourceLocation; 10 | import net.minecraft.sounds.SoundEvent; 11 | import net.minecraft.world.entity.EntityType; 12 | import net.minecraft.world.entity.LivingEntity; 13 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 14 | import net.minecraft.world.entity.ai.attributes.Attributes; 15 | 16 | import java.util.function.Consumer; 17 | 18 | public class SlimeJSBuilder extends MobBuilder { 19 | public transient Boolean defaultGoals; 20 | public transient ParticleOptions setParticleType; 21 | public transient Consumer dealDamage; 22 | public transient SoundEvent setSquishSound; 23 | 24 | public SlimeJSBuilder(ResourceLocation i) { 25 | super(i); 26 | defaultGoals = true; 27 | } 28 | 29 | @Info(value = """ 30 | @param setSquishSound Sets the squish sound 31 | 32 | Example usage: 33 | ```javascript 34 | builder.setSquishSound("block.azalea.hit"); 35 | ``` 36 | """) 37 | public SlimeJSBuilder setSquishSound(SoundEvent sound) { 38 | this.setSquishSound = sound; 39 | return this; 40 | } 41 | 42 | @Info(value = """ 43 | @param setParticleType Sets the particles emitted off the slime 44 | Defaults to slime particles 45 | 46 | Example usage: 47 | ```javascript 48 | builder.setParticleType("crit"); 49 | ``` 50 | """) 51 | public SlimeJSBuilder setParticleType(ParticleType type) { 52 | this.setParticleType = (ParticleOptions) type; 53 | return this; 54 | } 55 | 56 | @Info(value = """ 57 | @param dealDamage Overrides the way the slime deals damage 58 | 59 | Example usage: 60 | ```javascript 61 | builder.dealDamage(ctx => { 62 | const { entity, target } = ctx 63 | // Determine how the slime deals damage 64 | }); 65 | ``` 66 | """) 67 | public SlimeJSBuilder dealDamage(Consumer dealDamage) { 68 | this.dealDamage = dealDamage; 69 | return this; 70 | } 71 | 72 | 73 | @Info(value = """ 74 | @param defaultGoals Sets whether the mob should inherit it's goals from it's superclass 75 | Defaults to true. 76 | 77 | Example usage: 78 | ```javascript 79 | builder.defaultGoals(false); 80 | ``` 81 | """) 82 | public SlimeJSBuilder defaultGoals(boolean defaultGoals) { 83 | this.defaultGoals = defaultGoals; 84 | return this; 85 | } 86 | 87 | @Override 88 | public EntityType.EntityFactory factory() { 89 | return (type, level) -> new SlimeEntityJS(this, type, level); 90 | } 91 | 92 | @Override 93 | public AttributeSupplier.Builder getAttributeBuilder() { 94 | return SlimeEntityJS.createMobAttributes().add(Attributes.ATTACK_DAMAGE); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/vanilla/WitherJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living.vanilla; 2 | 3 | import dev.latvian.mods.kubejs.typings.Info; 4 | import net.liopyu.entityjs.builders.living.entityjs.PathfinderMobBuilder; 5 | import net.liopyu.entityjs.entities.living.vanilla.BlazeEntityJS; 6 | import net.liopyu.entityjs.entities.living.vanilla.WitherEntityJS; 7 | import net.minecraft.resources.ResourceLocation; 8 | import net.minecraft.world.entity.EntityType; 9 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 10 | 11 | public class WitherJSBuilder extends PathfinderMobBuilder { 12 | public transient Boolean defaultGoals; 13 | public transient String attackProjectile; 14 | public transient boolean customServerAiStep; 15 | 16 | public WitherJSBuilder(ResourceLocation i) { 17 | super(i); 18 | defaultGoals = true; 19 | customServerAiStep = true; 20 | } 21 | 22 | @Info(value = """ 23 | @param attackProjectile Sets the projectile shot by the wither. 24 | Defaults to a wither skull. 25 | 26 | Example usage: 27 | ```javascript 28 | builder.attackProjectile("minecraft:arrow"); 29 | ``` 30 | """) 31 | public WitherJSBuilder attackProjectile(String attackProjectile) { 32 | this.attackProjectile = attackProjectile; 33 | return this; 34 | } 35 | 36 | @Info(value = """ 37 | @param defaultGoals Sets whether the mob should inherit it's goals from it's superclass 38 | Defaults to true. 39 | 40 | Example usage: 41 | ```javascript 42 | builder.defaultGoals(false); 43 | ``` 44 | """) 45 | public WitherJSBuilder defaultGoals(boolean defaultGoals) { 46 | this.defaultGoals = defaultGoals; 47 | return this; 48 | } 49 | 50 | @Info(value = """ 51 | @param customServerAiStep Sets whether the mob has its default custom server ai step behavior 52 | Defaults to true. 53 | 54 | Example usage: 55 | ```javascript 56 | builder.customServerAiStep(false); 57 | ``` 58 | """) 59 | public WitherJSBuilder customServerAiStep(boolean customServerAiStep) { 60 | this.customServerAiStep = customServerAiStep; 61 | return this; 62 | } 63 | 64 | 65 | @Override 66 | public EntityType.EntityFactory factory() { 67 | return (type, level) -> new WitherEntityJS(this, type, level); 68 | } 69 | 70 | @Override 71 | public AttributeSupplier.Builder getAttributeBuilder() { 72 | return WitherEntityJS.createAttributes(); 73 | } 74 | } -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/vanilla/WolfJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living.vanilla; 2 | 3 | import dev.latvian.mods.kubejs.typings.Info; 4 | import net.liopyu.entityjs.builders.living.entityjs.MobBuilder; 5 | import net.liopyu.entityjs.builders.living.entityjs.PathfinderMobBuilder; 6 | import net.liopyu.entityjs.builders.living.entityjs.TameableMobBuilder; 7 | import net.liopyu.entityjs.entities.living.entityjs.MobEntityJS; 8 | import net.liopyu.entityjs.entities.living.vanilla.WolfEntityJS; 9 | import net.liopyu.entityjs.entities.living.vanilla.ZombieEntityJS; 10 | import net.minecraft.resources.ResourceLocation; 11 | import net.minecraft.world.entity.EntityType; 12 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 13 | import net.minecraft.world.entity.ai.attributes.Attributes; 14 | 15 | 16 | public class WolfJSBuilder extends TameableMobBuilder { 17 | public transient Boolean defaultGoals; 18 | 19 | public WolfJSBuilder(ResourceLocation i) { 20 | super(i); 21 | defaultGoals = true; 22 | } 23 | 24 | 25 | @Info(value = """ 26 | @param defaultGoals Sets whether the mob should inherit it's goals from it's superclass 27 | Defaults to true. 28 | 29 | Example usage: 30 | ```javascript 31 | builder.defaultGoals(false); 32 | ``` 33 | """) 34 | public WolfJSBuilder defaultGoals(boolean defaultGoals) { 35 | this.defaultGoals = defaultGoals; 36 | return this; 37 | } 38 | 39 | @Override 40 | public EntityType.EntityFactory factory() { 41 | return (type, level) -> new WolfEntityJS(this, type, level); 42 | } 43 | 44 | @Override 45 | public AttributeSupplier.Builder getAttributeBuilder() { 46 | return WolfEntityJS.createAttributes(); 47 | } 48 | } -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/living/vanilla/ZombieJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.living.vanilla; 2 | 3 | import dev.latvian.mods.kubejs.typings.Info; 4 | import net.liopyu.entityjs.builders.living.entityjs.MobBuilder; 5 | import net.liopyu.entityjs.builders.living.entityjs.PathfinderMobBuilder; 6 | import net.liopyu.entityjs.entities.living.entityjs.MobEntityJS; 7 | import net.liopyu.entityjs.entities.living.vanilla.ZombieEntityJS; 8 | import net.minecraft.resources.ResourceLocation; 9 | import net.minecraft.world.entity.EntityType; 10 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 11 | import net.minecraft.world.entity.ai.attributes.Attributes; 12 | 13 | 14 | public class ZombieJSBuilder extends PathfinderMobBuilder { 15 | public transient boolean defaultBehaviourGoals; 16 | public transient boolean defaultGoals; 17 | public transient boolean isSunSensitive; 18 | public transient boolean convertsInWater; 19 | 20 | 21 | public ZombieJSBuilder(ResourceLocation i) { 22 | super(i); 23 | defaultBehaviourGoals = true; 24 | defaultGoals = true; 25 | isSunSensitive = true; 26 | convertsInWater = true; 27 | } 28 | 29 | @Info(value = """ 30 | @param isSunSensitive Sets whether the mob should convert in water to another mob 31 | Defaults to true. 32 | 33 | Example usage: 34 | ```javascript 35 | builder.convertsInWater(false); 36 | ``` 37 | """) 38 | public ZombieJSBuilder convertsInWater(boolean convertsInWater) { 39 | this.convertsInWater = convertsInWater; 40 | return this; 41 | } 42 | 43 | @Info(value = """ 44 | @param isSunSensitive Sets whether the mob should burn in daylight 45 | Defaults to true. 46 | 47 | Example usage: 48 | ```javascript 49 | builder.isSunSensitive(false); 50 | ``` 51 | """) 52 | public ZombieJSBuilder isSunSensitive(boolean isSunSensitive) { 53 | this.isSunSensitive = isSunSensitive; 54 | return this; 55 | } 56 | 57 | @Info(value = """ 58 | @param defaultGoals Sets whether the mob should inherit it's goals from it's superclass 59 | Defaults to true. 60 | 61 | Example usage: 62 | ```javascript 63 | builder.defaultGoals(false); 64 | ``` 65 | """) 66 | public ZombieJSBuilder defaultGoals(boolean defaultGoals) { 67 | this.defaultGoals = defaultGoals; 68 | return this; 69 | } 70 | 71 | @Info(value = """ 72 | @param defaultBehaviourGoals Sets whether the mob should inherit it's goal behavior from it's superclass 73 | Defaults to true. 74 | 75 | Example usage: 76 | ```javascript 77 | builder.defaultBehaviourGoals(false); 78 | ``` 79 | """) 80 | public ZombieJSBuilder defaultBehaviourGoals(boolean defaultBehaviourGoals) { 81 | this.defaultBehaviourGoals = defaultBehaviourGoals; 82 | return this; 83 | } 84 | 85 | @Override 86 | public EntityType.EntityFactory factory() { 87 | return (type, level) -> new ZombieEntityJS(this, type, level); 88 | } 89 | 90 | @Override 91 | public AttributeSupplier.Builder getAttributeBuilder() { 92 | return MobEntityJS.createMobAttributes() 93 | .add(Attributes.MAX_HEALTH) 94 | .add(Attributes.FOLLOW_RANGE) 95 | .add(Attributes.ATTACK_DAMAGE) 96 | .add(Attributes.ARMOR) 97 | .add(Attributes.ARMOR_TOUGHNESS) 98 | .add(Attributes.ATTACK_SPEED) 99 | .add(Attributes.ATTACK_KNOCKBACK) 100 | .add(Attributes.LUCK) 101 | .add(Attributes.SPAWN_REINFORCEMENTS_CHANCE) 102 | .add(Attributes.MOVEMENT_SPEED); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/misc/JumpControlJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.misc; 2 | 3 | import net.minecraft.world.entity.Mob; 4 | 5 | import java.util.function.Consumer; 6 | 7 | public class JumpControlJSBuilder { 8 | 9 | public transient Consumer jump; 10 | public transient Consumer tick; 11 | 12 | public JumpControlJSBuilder jump(Consumer jump) { 13 | this.jump = jump; 14 | return this; 15 | } 16 | 17 | public JumpControlJSBuilder tick(Consumer tick) { 18 | this.tick = tick; 19 | return this; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/misc/LookControlJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.misc; 2 | 3 | import net.liopyu.entityjs.util.ContextUtils; 4 | import net.liopyu.entityjs.util.ai.LookControlJS; 5 | import net.minecraft.world.entity.Mob; 6 | 7 | import java.util.function.Consumer; 8 | import java.util.function.Function; 9 | 10 | public class LookControlJSBuilder { 11 | public transient Consumer setLookAtVec3; 12 | public transient Consumer setLookAtEntity; 13 | public transient Consumer setLookAtEntityWithRotation; 14 | public transient Consumer setLookAtCoords; 15 | public transient Consumer tick; 16 | public transient Consumer clampHeadRotationToBody; 17 | public transient Function resetXRotOnTick; 18 | public transient Function isLookingAtTarget; 19 | public transient Function setWantedX; 20 | public transient Function setWantedY; 21 | public transient Function setWantedZ; 22 | public transient Function getXRotD; 23 | public transient Function getYRotD; 24 | public transient Function rotateTowards; 25 | 26 | public LookControlJSBuilder setLookAtVec3(Consumer setLookAtVec3) { 27 | this.setLookAtVec3 = setLookAtVec3; 28 | return this; 29 | } 30 | 31 | public LookControlJSBuilder setIsLookingAtTarget(Function isLookingAtTarget) { 32 | this.isLookingAtTarget = isLookingAtTarget; 33 | return this; 34 | } 35 | 36 | public LookControlJSBuilder setWantedX(Function setWantedX) { 37 | this.setWantedX = setWantedX; 38 | return this; 39 | } 40 | 41 | public LookControlJSBuilder setWantedY(Function setWantedY) { 42 | this.setWantedY = setWantedY; 43 | return this; 44 | } 45 | 46 | public LookControlJSBuilder setWantedZ(Function setWantedZ) { 47 | this.setWantedZ = setWantedZ; 48 | return this; 49 | } 50 | 51 | public LookControlJSBuilder setXRotD(Function getXRotD) { 52 | this.getXRotD = getXRotD; 53 | return this; 54 | } 55 | 56 | public LookControlJSBuilder setYRotD(Function getYRotD) { 57 | this.getYRotD = getYRotD; 58 | return this; 59 | } 60 | 61 | public LookControlJSBuilder setRotateTowards(Function rotateTowards) { 62 | this.rotateTowards = rotateTowards; 63 | return this; 64 | } 65 | 66 | public LookControlJSBuilder setLookAtEntity(Consumer setLookAtEntity) { 67 | this.setLookAtEntity = setLookAtEntity; 68 | return this; 69 | } 70 | 71 | public LookControlJSBuilder setLookAtEntityWithRotation(Consumer setLookAtEntityWithRotation) { 72 | this.setLookAtEntityWithRotation = setLookAtEntityWithRotation; 73 | return this; 74 | } 75 | 76 | public LookControlJSBuilder setLookAtCoords(Consumer setLookAtCoords) { 77 | this.setLookAtCoords = setLookAtCoords; 78 | return this; 79 | } 80 | 81 | public LookControlJSBuilder tick(Consumer tick) { 82 | this.tick = tick; 83 | return this; 84 | } 85 | 86 | public LookControlJSBuilder setClampHeadRotationToBody(Consumer clampHeadRotationToBody) { 87 | this.clampHeadRotationToBody = clampHeadRotationToBody; 88 | return this; 89 | } 90 | 91 | public LookControlJSBuilder setResetXRotOnTick(Function resetXRotOnTick) { 92 | this.resetXRotOnTick = resetXRotOnTick; 93 | return this; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/misc/MoveControlJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.misc; 2 | 3 | import net.liopyu.entityjs.util.ContextUtils; 4 | import net.minecraft.world.entity.Mob; 5 | 6 | import java.util.function.Consumer; 7 | import java.util.function.Function; 8 | 9 | public class MoveControlJSBuilder { 10 | 11 | public transient Function hasWanted; 12 | public transient Function getSpeedModifier; 13 | public transient Consumer setWantedPosition; 14 | public transient Consumer strafe; 15 | public transient Consumer tick; 16 | public transient Function rotlerp; 17 | public transient Function isWalkable; 18 | 19 | public MoveControlJSBuilder setHasWanted(Function hasWanted) { 20 | this.hasWanted = hasWanted; 21 | return this; 22 | } 23 | 24 | public MoveControlJSBuilder setSpeedModifier(Function getSpeedModifier) { 25 | this.getSpeedModifier = getSpeedModifier; 26 | return this; 27 | } 28 | 29 | public MoveControlJSBuilder setWantedPosition(Consumer setWantedPosition) { 30 | this.setWantedPosition = setWantedPosition; 31 | return this; 32 | } 33 | 34 | public MoveControlJSBuilder setStrafe(Consumer strafe) { 35 | this.strafe = strafe; 36 | return this; 37 | } 38 | 39 | public MoveControlJSBuilder tick(Consumer tick) { 40 | this.tick = tick; 41 | return this; 42 | } 43 | 44 | public MoveControlJSBuilder setRotlerp(Function rotlerp) { 45 | this.rotlerp = rotlerp; 46 | return this; 47 | } 48 | 49 | public MoveControlJSBuilder setIsWalkable(Function isWalkable) { 50 | this.isWalkable = isWalkable; 51 | return this; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/modification/ModifyAgeableMobBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.modification; 2 | 3 | import net.minecraft.world.entity.EntityType; 4 | 5 | public class ModifyAgeableMobBuilder extends ModifyPathfinderMobBuilder { 6 | public ModifyAgeableMobBuilder(EntityType entity) { 7 | super(entity); 8 | } 9 | } -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/modification/ModifyAnimalBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.modification; 2 | 3 | import net.minecraft.world.entity.EntityType; 4 | 5 | public class ModifyAnimalBuilder extends ModifyAgeableMobBuilder { 6 | public ModifyAnimalBuilder(EntityType entity) { 7 | super(entity); 8 | } 9 | } -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/modification/ModifyPathfinderMobBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.modification; 2 | 3 | import dev.latvian.mods.kubejs.typings.Info; 4 | import net.liopyu.entityjs.util.ContextUtils; 5 | import net.minecraft.world.entity.EntityType; 6 | import net.minecraft.world.entity.Mob; 7 | 8 | import java.util.function.Function; 9 | 10 | public class ModifyPathfinderMobBuilder extends ModifyMobBuilder { 11 | public transient Function shouldStayCloseToLeashHolder; 12 | public transient Double followLeashSpeed; 13 | public transient Function walkTargetValue; 14 | 15 | public ModifyPathfinderMobBuilder(EntityType entity) { 16 | super(entity); 17 | } 18 | 19 | @Info(value = """ 20 | Sets the function to determine whether the entity should stay close to its leash holder. 21 | 22 | @param predicate A Function accepting a {@link Mob} parameter, 23 | defining the condition for the entity to stay close to its leash holder. 24 | 25 | Example usage: 26 | ```javascript 27 | mobBuilder.shouldStayCloseToLeashHolder(entity => { 28 | // Custom logic to determine whether the entity should stay close to its leash holder. 29 | return true; 30 | }); 31 | ``` 32 | """) 33 | public ModifyPathfinderMobBuilder shouldStayCloseToLeashHolder(Function predicate) { 34 | this.shouldStayCloseToLeashHolder = predicate; 35 | return this; 36 | } 37 | 38 | @Info(value = """ 39 | Sets the follow leash speed for the entity. 40 | 41 | @param speed The follow leash speed. 42 | 43 | Example usage: 44 | ```javascript 45 | mobBuilder.followLeashSpeed(1.5); 46 | ``` 47 | """) 48 | public ModifyPathfinderMobBuilder followLeashSpeed(double speed) { 49 | this.followLeashSpeed = speed; 50 | return this; 51 | } 52 | 53 | @Info(value = """ 54 | Sets the walk target value function for the entity. 55 | 56 | @param function A Function accepting a {@link ContextUtils.EntityBlockPosLevelContext} parameter, 57 | defining the walk target value based on the entity's interaction with a specific block. 58 | 59 | Example usage: 60 | ```javascript 61 | mobBuilder.walkTargetValue(context => { 62 | // Custom logic to calculate the walk target value based on the provided context. 63 | // Access information about the block position and level using the provided context. 64 | return 10; 65 | }); 66 | ``` 67 | """) 68 | public ModifyPathfinderMobBuilder walkTargetValue(Function function) { 69 | this.walkTargetValue = function; 70 | return this; 71 | } 72 | } -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/modification/ModifyProjectileBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.modification; 2 | 3 | import dev.latvian.mods.kubejs.typings.Info; 4 | import net.liopyu.entityjs.builders.nonliving.entityjs.ProjectileEntityBuilder; 5 | import net.liopyu.entityjs.util.ContextUtils; 6 | import net.minecraft.world.entity.Entity; 7 | import net.minecraft.world.entity.EntityType; 8 | 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | import java.util.function.Consumer; 12 | import java.util.function.Function; 13 | 14 | public class ModifyProjectileBuilder extends ModifyEntityBuilder { 15 | public transient Consumer onHitEntity; 16 | public transient Consumer onHitBlock; 17 | public transient Function canHitEntity; 18 | 19 | public ModifyProjectileBuilder(EntityType entityType) { 20 | super(entityType); 21 | } 22 | 23 | 24 | @Info(value = """ 25 | Sets a callback function to be executed when the projectile hits an entity. 26 | The provided Consumer accepts a {@link ContextUtils.ProjectileEntityHitContext} parameter, 27 | representing the context of the projectile's interaction with a specific entity. 28 | 29 | Example usage: 30 | ```javascript 31 | projectileBuilder.onHitEntity(context -> { 32 | // Custom logic to handle the projectile hitting an entity. 33 | // Access information about the entity and projectile using the provided context. 34 | }); 35 | ``` 36 | """) 37 | public ModifyProjectileBuilder onHitEntity(Consumer consumer) { 38 | onHitEntity = consumer; 39 | return this; 40 | } 41 | 42 | 43 | @Info(value = """ 44 | Sets a callback function to be executed when the projectile hits a block. 45 | The provided Consumer accepts a {@link ContextUtils.ProjectileBlockHitContext} parameter, 46 | representing the context of the projectile's interaction with a specific block. 47 | 48 | Example usage: 49 | ```javascript 50 | projectileBuilder.onHitBlock(context -> { 51 | // Custom logic to handle the projectile hitting a block. 52 | // Access information about the block and projectile using the provided context. 53 | }); 54 | ``` 55 | """) 56 | public ModifyProjectileBuilder onHitBlock(Consumer consumer) { 57 | onHitBlock = consumer; 58 | return this; 59 | } 60 | 61 | @Info(value = """ 62 | Sets a function to determine if the projectile entity can hit a specific entity. 63 | 64 | @param canHitEntity The predicate to check if the arrow can hit the entity. 65 | 66 | Example usage: 67 | ```javascript 68 | projectileEntityBuilder.canHitEntity(entity -> { 69 | // Custom logic to determine if the projectile can hit the specified entity 70 | // Return true if the arrow can hit, false otherwise. 71 | }); 72 | ``` 73 | """) 74 | public ModifyProjectileBuilder canHitEntity(Function function) { 75 | canHitEntity = function; 76 | return this; 77 | } 78 | } -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/modification/ModifyTamableAnimalBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.modification; 2 | 3 | import net.minecraft.world.entity.EntityType; 4 | 5 | public class ModifyTamableAnimalBuilder extends ModifyAnimalBuilder { 6 | public ModifyTamableAnimalBuilder(EntityType entity) { 7 | super(entity); 8 | } 9 | } -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/nonliving/EntityTypeBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.nonliving; 2 | 3 | import dev.latvian.mods.kubejs.util.UtilsJS; 4 | import net.liopyu.entityjs.builders.nonliving.BaseEntityBuilder; 5 | import net.liopyu.entityjs.entities.nonliving.entityjs.IAnimatableJSNL; 6 | import net.minecraft.world.entity.Entity; 7 | import net.minecraft.world.entity.EntityType; 8 | import net.minecraft.world.level.block.Block; 9 | import net.minecraftforge.registries.ForgeRegistries; 10 | 11 | 12 | public class EntityTypeBuilder { 13 | 14 | private final BaseEntityBuilder builder; 15 | 16 | public > EntityTypeBuilder(T builder) { 17 | this.builder = builder; 18 | } 19 | 20 | 21 | public EntityType get() { 22 | var js = this.builder; 23 | var builder = EntityType.Builder.of(js.factory(), js.mobCategory); 24 | builder 25 | .sized(js.width, js.height) 26 | .clientTrackingRange(js.clientTrackingRange) 27 | .updateInterval(js.updateInterval); 28 | if (js.spawnFarFromPlayer) { 29 | builder.canSpawnFarFromPlayer(); 30 | } 31 | if (js.fireImmune) { 32 | builder.fireImmune(); 33 | } 34 | if (!js.save) { 35 | builder.noSave(); 36 | } 37 | if (js.immuneTo.length > 0) { 38 | final Block[] blocks = new Block[js.immuneTo.length]; 39 | for (int i = 0; i < js.immuneTo.length; i++) { 40 | blocks[i] = ForgeRegistries.BLOCKS.getValue(js.immuneTo[i]); 41 | } 42 | builder.immuneTo(blocks); 43 | } 44 | if (!js.summonable) { 45 | builder.noSummon(); 46 | } 47 | return UtilsJS.cast(builder.build(js.id.toString())); // If this fails, uh... do better? 48 | } 49 | 50 | } 51 | 52 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/nonliving/NonAnimatableEntityTypeBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.nonliving; 2 | 3 | import dev.latvian.mods.kubejs.util.UtilsJS; 4 | import net.minecraft.world.entity.Entity; 5 | import net.minecraft.world.entity.EntityType; 6 | import net.minecraft.world.level.block.Block; 7 | import net.minecraftforge.registries.ForgeRegistries; 8 | 9 | public class NonAnimatableEntityTypeBuilder { 10 | private final BaseNonAnimatableEntityBuilder builder; 11 | 12 | public > NonAnimatableEntityTypeBuilder(T builder) { 13 | this.builder = builder; 14 | } 15 | 16 | public EntityType get() { 17 | var js = this.builder; 18 | var builder = EntityType.Builder.of(js.factory(), js.mobCategory); 19 | builder 20 | .sized(js.width, js.height) 21 | .clientTrackingRange(js.clientTrackingRange) 22 | .updateInterval(js.updateInterval); 23 | if (js.spawnFarFromPlayer) { 24 | builder.canSpawnFarFromPlayer(); 25 | } 26 | if (js.fireImmune) { 27 | builder.fireImmune(); 28 | } 29 | if (!js.save) { 30 | builder.noSave(); 31 | } 32 | if (js.immuneTo.length > 0) { 33 | final Block[] blocks = new Block[js.immuneTo.length]; 34 | for (int i = 0; i < js.immuneTo.length; i++) { 35 | blocks[i] = ForgeRegistries.BLOCKS.getValue(js.immuneTo[i]); 36 | } 37 | builder.immuneTo(blocks); 38 | } 39 | if (!js.summonable) { 40 | builder.noSummon(); 41 | } 42 | return UtilsJS.cast(builder.build(js.id.toString())); // If this fails, uh... do better? 43 | } 44 | 45 | } 46 | 47 | 48 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/nonliving/entityjs/ArrowEntityJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.nonliving.entityjs; 2 | 3 | import dev.latvian.mods.kubejs.registry.RegistryInfo; 4 | import dev.latvian.mods.kubejs.typings.Generics; 5 | import dev.latvian.mods.kubejs.typings.Info; 6 | import net.liopyu.entityjs.entities.nonliving.entityjs.ArrowEntityJS; 7 | import net.liopyu.entityjs.item.ArrowItemBuilder; 8 | import net.minecraft.resources.ResourceLocation; 9 | import net.minecraft.world.entity.EntityType; 10 | 11 | import java.util.function.Consumer; 12 | 13 | public class ArrowEntityJSBuilder extends ArrowEntityBuilder { 14 | 15 | public transient ArrowItemBuilder item; 16 | public transient boolean noItem; 17 | 18 | public ArrowEntityJSBuilder(ResourceLocation i) { 19 | super(i); 20 | this.item = (ArrowItemBuilder) new ArrowItemBuilder(id, this) 21 | .canBePickedup(true) 22 | .texture(i.getNamespace() + ":item/" + i.getPath()) 23 | .tag(new ResourceLocation("minecraft:arrows")); 24 | } 25 | 26 | 27 | @Override 28 | public EntityType.EntityFactory factory() { 29 | return (type, level) -> new ArrowEntityJS(this, type, level); 30 | } 31 | 32 | @Info(value = "Indicates that no arrow item should be created for this entity type") 33 | public ArrowEntityJSBuilder noItem() { 34 | this.noItem = true; 35 | return this; 36 | } 37 | 38 | @Info(value = "Creates the arrow item for this entity type") 39 | @Generics(value = ArrowEntityBuilder.class) 40 | public ArrowEntityJSBuilder item(Consumer item) { 41 | 42 | this.item = new ArrowItemBuilder(id, this); 43 | item.accept(this.item); 44 | 45 | return this; 46 | } 47 | 48 | @Override 49 | public void createAdditionalObjects() { 50 | if (!noItem) { 51 | RegistryInfo.ITEM.addBuilder(item); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/nonliving/entityjs/BaseEntityJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.nonliving.entityjs; 2 | 3 | 4 | import net.liopyu.entityjs.builders.nonliving.BaseEntityBuilder; 5 | import net.liopyu.entityjs.entities.nonliving.entityjs.BaseEntityJS; 6 | import net.liopyu.entityjs.entities.living.entityjs.BaseLivingEntityJS; 7 | import net.minecraft.resources.ResourceLocation; 8 | import net.minecraft.world.entity.EntityType; 9 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 10 | import net.minecraft.world.entity.ai.attributes.Attributes; 11 | 12 | public class BaseEntityJSBuilder extends BaseEntityBuilder { 13 | 14 | public BaseEntityJSBuilder(ResourceLocation i) { 15 | super(i); 16 | } 17 | 18 | @Override 19 | public EntityType.EntityFactory factory() { 20 | return (type, level) -> new BaseEntityJS(this, type, level); 21 | } 22 | 23 | @Override 24 | public AttributeSupplier.Builder getAttributeBuilder() { 25 | //final AttributeSupplier.Builder builder = BaseEntityJS.createLivingAttributes(); 26 | return null; //BaseEntityJS.createLivingAttributes(); 27 | } 28 | } -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/nonliving/entityjs/ProjectileEntityJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.nonliving.entityjs; 2 | 3 | import dev.latvian.mods.kubejs.registry.RegistryInfo; 4 | import dev.latvian.mods.kubejs.typings.Generics; 5 | import dev.latvian.mods.kubejs.typings.Info; 6 | import net.liopyu.entityjs.builders.nonliving.BaseEntityBuilder; 7 | import net.liopyu.entityjs.entities.nonliving.entityjs.ProjectileEntityJS; 8 | import net.liopyu.entityjs.item.ProjectileItemBuilder; 9 | import net.minecraft.resources.ResourceLocation; 10 | import net.minecraft.world.entity.EntityType; 11 | import net.minecraft.world.level.Level; 12 | 13 | import java.util.function.Consumer; 14 | 15 | 16 | public class ProjectileEntityJSBuilder extends ProjectileEntityBuilder { 17 | 18 | public transient ProjectileItemBuilder item; 19 | public transient boolean noItem; 20 | 21 | public ProjectileEntityJSBuilder(ResourceLocation i) { 22 | super(i); 23 | this.item = (ProjectileItemBuilder) new ProjectileItemBuilder(id, this) 24 | .canThrow(true) 25 | .texture(i.getNamespace() + ":item/" + i.getPath()); 26 | } 27 | 28 | public transient Level level; 29 | 30 | 31 | @Override 32 | public EntityType.EntityFactory factory() { 33 | return (type, level) -> new ProjectileEntityJS(this, type, level); 34 | } 35 | 36 | @Info(value = "Indicates that no projectile item should be created for this entity type") 37 | public ProjectileEntityJSBuilder noItem() { 38 | this.noItem = true; 39 | return this; 40 | } 41 | 42 | @Info(value = "Creates the arrow item for this entity type") 43 | @Generics(value = BaseEntityBuilder.class) 44 | public ProjectileEntityJSBuilder item(Consumer item) { 45 | 46 | this.item = new ProjectileItemBuilder(id, this); 47 | item.accept(this.item); 48 | 49 | return this; 50 | } 51 | 52 | @Override 53 | public void createAdditionalObjects() { 54 | if (!noItem) { 55 | RegistryInfo.ITEM.addBuilder(item); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/nonliving/vanilla/BoatEntityBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.nonliving.vanilla; 2 | 3 | import dev.latvian.mods.kubejs.typings.Info; 4 | import net.liopyu.entityjs.builders.nonliving.BaseEntityBuilder; 5 | import net.liopyu.entityjs.builders.nonliving.entityjs.ArrowEntityBuilder; 6 | import net.liopyu.entityjs.entities.nonliving.entityjs.IAnimatableJSNL; 7 | import net.liopyu.entityjs.entities.nonliving.vanilla.BoatEntityJS; 8 | import net.minecraft.resources.ResourceLocation; 9 | import net.minecraft.world.entity.Entity; 10 | import net.minecraft.world.entity.EntityType; 11 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 12 | import net.minecraft.world.entity.vehicle.Boat; 13 | 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | import java.util.function.Function; 17 | 18 | public abstract class BoatEntityBuilder extends BaseEntityBuilder { 19 | public transient Function getDropItem; 20 | public transient float setShadowRadius; 21 | public static final List> thisList = new ArrayList<>(); 22 | public transient Function turningBoatSpeed; 23 | public transient Function forwardBoatSpeed; 24 | public transient Function backwardsBoatSpeed; 25 | 26 | public BoatEntityBuilder(ResourceLocation i) { 27 | super(i); 28 | thisList.add(this); 29 | this.setShadowRadius = 0.3F; 30 | } 31 | 32 | @Info(value = """ 33 | Sets a function to determine the speed of the boat when it turns. 34 | Example usage: 35 | ```javascript 36 | builder.turningBoatSpeed(entity => { 37 | // Use information about the entity provided by the context. 38 | return 1 // Some Float 39 | }); 40 | ``` 41 | """) 42 | public BoatEntityBuilder turningBoatSpeed(Function function) { 43 | this.turningBoatSpeed = function; 44 | return this; 45 | } 46 | 47 | @Info(value = """ 48 | Sets a function to determine the speed of the boat when going forward. 49 | Example usage: 50 | ```javascript 51 | builder.forwardBoatSpeed(entity => { 52 | // Use information about the entity provided by the context. 53 | return 1 // Some Float 54 | }); 55 | ``` 56 | """) 57 | public BoatEntityBuilder forwardBoatSpeed(Function function) { 58 | this.forwardBoatSpeed = function; 59 | return this; 60 | } 61 | 62 | @Info(value = """ 63 | Sets a function to determine the speed of the boat when in reverse. 64 | Example usage: 65 | ```javascript 66 | builder.backwardsBoatSpeed(entity => { 67 | // Use information about the entity provided by the context. 68 | return 1 // Some Float 69 | }); 70 | ``` 71 | """) 72 | public BoatEntityBuilder backwardsBoatSpeed(Function function) { 73 | this.backwardsBoatSpeed = function; 74 | return this; 75 | } 76 | 77 | @Info(value = """ 78 | Sets the shadow radius of the entity. 79 | Defaults to 0.3. 80 | Example usage: 81 | ```javascript 82 | builder.setShadowRadius(0.8); 83 | ``` 84 | """) 85 | public BoatEntityBuilder setShadowRadius(float f) { 86 | this.setShadowRadius = f; 87 | return this; 88 | } 89 | 90 | @Info(value = """ 91 | Sets a function to determine the Item the entity drops when it 92 | turns back into an item. 93 | Defaults to Boat super method. 94 | Example usage: 95 | ```javascript 96 | builder.getDropItem(entity => { 97 | // Use information about the entity provided by the context. 98 | return Item.of('amethyst_block').item // Some Item 99 | }); 100 | ``` 101 | """) 102 | public BoatEntityBuilder getDropItem(Function function) { 103 | this.getDropItem = function; 104 | return this; 105 | } 106 | } -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/nonliving/vanilla/BoatJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.nonliving.vanilla; 2 | 3 | import net.liopyu.entityjs.builders.nonliving.EntityTypeBuilder; 4 | import net.liopyu.entityjs.builders.nonliving.NonAnimatableEntityTypeBuilder; 5 | import net.liopyu.entityjs.entities.nonliving.vanilla.BoatEntityJS; 6 | import net.liopyu.entityjs.entities.nonliving.vanilla.EyeOfEnderEntityJS; 7 | import net.minecraft.resources.ResourceLocation; 8 | import net.minecraft.world.entity.EntityType; 9 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 10 | 11 | public class BoatJSBuilder extends BoatEntityBuilder { 12 | public BoatJSBuilder(ResourceLocation i) { 13 | super(i); 14 | } 15 | 16 | @Override 17 | public EntityType createObject() { 18 | return new EntityTypeBuilder<>(this).get(); 19 | } 20 | 21 | @Override 22 | public EntityType.EntityFactory factory() { 23 | return (type, level) -> new BoatEntityJS(this, type, level); 24 | } 25 | 26 | @Override 27 | public AttributeSupplier.Builder getAttributeBuilder() { 28 | return null; 29 | } 30 | } -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/builders/nonliving/vanilla/EyeOfEnderJSBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.builders.nonliving.vanilla; 2 | 3 | import dev.latvian.mods.kubejs.registry.RegistryInfo; 4 | import dev.latvian.mods.kubejs.typings.Generics; 5 | import dev.latvian.mods.kubejs.typings.Info; 6 | import net.liopyu.entityjs.builders.nonliving.BaseEntityBuilder; 7 | import net.liopyu.entityjs.builders.nonliving.BaseNonAnimatableEntityBuilder; 8 | import net.liopyu.entityjs.builders.nonliving.NonAnimatableEntityTypeBuilder; 9 | import net.liopyu.entityjs.entities.nonliving.vanilla.EyeOfEnderEntityJS; 10 | import net.liopyu.entityjs.item.EyeOfEnderItemBuilder; 11 | import net.minecraft.resources.ResourceLocation; 12 | import net.minecraft.world.entity.Entity; 13 | import net.minecraft.world.entity.EntityType; 14 | import net.minecraft.world.entity.projectile.EyeOfEnder; 15 | 16 | import java.util.function.Consumer; 17 | import java.util.function.Function; 18 | 19 | public class EyeOfEnderJSBuilder extends EyeOfEnderEntityBuilder { 20 | 21 | public transient Function getItem; 22 | public transient EyeOfEnderItemBuilder item; 23 | public transient boolean noItem; 24 | public transient boolean disableTrailParticles; 25 | public transient boolean disableDefaultDeathLogic; 26 | public transient Float survivalChance; 27 | 28 | public EyeOfEnderJSBuilder(ResourceLocation i) { 29 | super(i); 30 | this.item = (EyeOfEnderItemBuilder) new EyeOfEnderItemBuilder(id, this) 31 | .texture(i.getNamespace() + ":item/" + i.getPath()); 32 | this.disableTrailParticles = false; 33 | this.disableDefaultDeathLogic = false; 34 | } 35 | 36 | @Info(value = """ 37 | @param survivalChance A float value from 0 to 1 representing the chance that the Eye of Ender will not break after use. 38 | 39 | Example usage: 40 | ```javascript 41 | eyeOfEnderBuilder.setSurvivalChance(0.8); 42 | ``` 43 | """) 44 | public EyeOfEnderJSBuilder setSurvivalChance(float survivalChance) { 45 | this.survivalChance = survivalChance; 46 | return this; 47 | } 48 | 49 | 50 | @Info(value = "Disables the default ender eye break sound as well as the death particles.") 51 | public EyeOfEnderJSBuilder disableDefaultDeathLogic() { 52 | this.disableDefaultDeathLogic = true; 53 | return this; 54 | } 55 | 56 | @Info(value = "The default trail particles will be disabled") 57 | public EyeOfEnderJSBuilder disableTrailParticles() { 58 | this.disableTrailParticles = true; 59 | return this; 60 | } 61 | 62 | @Override 63 | public EntityType createObject() { 64 | return new NonAnimatableEntityTypeBuilder<>(this).get(); 65 | } 66 | 67 | @Info(value = """ 68 | Sets a function to determine the itemstack the entity drops when it 69 | turns back into an item 70 | Defaults to eye of ender. 71 | Example usage: 72 | ```javascript 73 | builder.getItem(entity => { 74 | // Use information about the entity provided by the context. 75 | return Item.of('kubejs:eye_of_ender')// Some ItemStack 76 | }); 77 | ``` 78 | """) 79 | public EyeOfEnderJSBuilder getItem(Function function) { 80 | this.getItem = function; 81 | return this; 82 | } 83 | 84 | @Info(value = "Indicates that no item should be created for this entity type") 85 | public EyeOfEnderJSBuilder noItem() { 86 | this.noItem = true; 87 | return this; 88 | } 89 | 90 | @Info(value = "Creates the item for this entity type") 91 | @Generics(value = BaseEntityBuilder.class) 92 | public EyeOfEnderJSBuilder item(Consumer item) { 93 | this.item = new EyeOfEnderItemBuilder(id, this); 94 | item.accept(this.item); 95 | return this; 96 | } 97 | 98 | @Override 99 | public EntityType.EntityFactory factory() { 100 | return (type, level) -> new EyeOfEnderEntityJS(this, type, level); 101 | } 102 | 103 | @Override 104 | public void createAdditionalObjects() { 105 | if (!noItem) { 106 | RegistryInfo.ITEM.addBuilder(item); 107 | } 108 | } 109 | } 110 | 111 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/client/ClientEventHandlers.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.client; 2 | 3 | import dev.latvian.mods.kubejs.util.UtilsJS; 4 | import net.liopyu.entityjs.EntityJSMod; 5 | import net.liopyu.entityjs.builders.nonliving.BaseEntityBuilder; 6 | import net.liopyu.entityjs.builders.nonliving.entityjs.ArrowEntityBuilder; 7 | import net.liopyu.entityjs.builders.living.BaseLivingEntityBuilder; 8 | import net.liopyu.entityjs.builders.nonliving.entityjs.ProjectileEntityBuilder; 9 | import net.liopyu.entityjs.builders.nonliving.vanilla.BoatEntityBuilder; 10 | import net.liopyu.entityjs.builders.nonliving.vanilla.EyeOfEnderEntityBuilder; 11 | import net.liopyu.entityjs.client.living.KubeJSEntityRenderer; 12 | import net.liopyu.entityjs.client.nonliving.*; 13 | import net.liopyu.entityjs.util.ModKeybinds; 14 | import net.minecraftforge.api.distmarker.Dist; 15 | import net.minecraftforge.client.event.EntityRenderersEvent; 16 | import net.minecraftforge.client.event.RegisterKeyMappingsEvent; 17 | import net.minecraftforge.eventbus.api.IEventBus; 18 | import net.minecraftforge.eventbus.api.SubscribeEvent; 19 | import net.minecraftforge.fml.common.Mod; 20 | import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; 21 | 22 | public class ClientEventHandlers { 23 | @Mod.EventBusSubscriber(modid = EntityJSMod.MOD_ID, value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.MOD) 24 | public static class ClientModBusEvents { 25 | @SubscribeEvent 26 | public static void onKeyRegister(RegisterKeyMappingsEvent event) { 27 | event.register(ModKeybinds.mount_jump); 28 | //event.register(ModKeybinds.mount_inventory); 29 | } 30 | } 31 | 32 | public static void init() { 33 | final IEventBus modBus = FMLJavaModLoadingContext.get().getModEventBus(); 34 | modBus.addListener(ClientEventHandlers::registerEntityRenders); 35 | } 36 | 37 | private static void registerEntityRenders(EntityRenderersEvent.RegisterRenderers event) { 38 | for (BaseLivingEntityBuilder builder : BaseLivingEntityBuilder.thisList) { 39 | event.registerEntityRenderer(UtilsJS.cast(builder.get()), renderManager -> new KubeJSEntityRenderer<>(renderManager, builder)); 40 | } 41 | for (ArrowEntityBuilder builder : ArrowEntityBuilder.thisList) { 42 | event.registerEntityRenderer(UtilsJS.cast(builder.get()), renderManager -> new KubeJSArrowEntityRenderer<>(renderManager, builder)); 43 | } 44 | for (ProjectileEntityBuilder builder : ProjectileEntityBuilder.thisList) { 45 | event.registerEntityRenderer(UtilsJS.cast(builder.get()), renderManager -> new KubeJSProjectileEntityRenderer<>(renderManager, builder)); 46 | } 47 | for (EyeOfEnderEntityBuilder builder : EyeOfEnderEntityBuilder.thisList) { 48 | event.registerEntityRenderer(UtilsJS.cast(builder.get()), renderManager -> new KubeJSEnderEyeRenderer<>(renderManager, builder)); 49 | } 50 | for (BaseEntityBuilder builder : BaseEntityBuilder.thisList) { 51 | event.registerEntityRenderer(UtilsJS.cast(builder.get()), renderManager -> new KubeJSNLEntityRenderer<>(renderManager, builder)); 52 | } 53 | for (BoatEntityBuilder builder : BoatEntityBuilder.thisList) { 54 | event.registerEntityRenderer(UtilsJS.cast(builder.get()), renderManager -> new KubeJSBoatRenderer<>(renderManager, builder)); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/client/living/model/EntityModelJS.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.client.living.model; 2 | 3 | import net.liopyu.entityjs.builders.living.BaseLivingEntityBuilder; 4 | import net.liopyu.entityjs.entities.living.entityjs.IAnimatableJS; 5 | import net.liopyu.liolib.model.GeoModel; 6 | import net.minecraft.resources.ResourceLocation; 7 | import net.minecraft.world.entity.LivingEntity; 8 | 9 | /** 10 | * The default implementation of GeckoLib's {@link GeoModel} which delegates model, texture, 11 | * and animation handling to {@code Function}s in the entity type's builder 12 | */ 13 | public class EntityModelJS extends GeoModel { 14 | 15 | private final BaseLivingEntityBuilder builder; 16 | 17 | public EntityModelJS(BaseLivingEntityBuilder builder) { 18 | this.builder = builder; 19 | } 20 | 21 | @Override 22 | public ResourceLocation getModelResource(T object) { 23 | return (ResourceLocation) builder.modelResource.apply(object); 24 | } 25 | 26 | @Override 27 | public ResourceLocation getTextureResource(T object) { 28 | return (ResourceLocation) builder.textureResource.apply(object); 29 | } 30 | 31 | @Override 32 | public ResourceLocation getAnimationResource(T animatable) { 33 | return (ResourceLocation) builder.animationResource.apply(animatable); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/client/living/model/GeoLayerJS.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.client.living.model; 2 | 3 | import com.mojang.blaze3d.vertex.PoseStack; 4 | import com.mojang.blaze3d.vertex.VertexConsumer; 5 | import net.liopyu.entityjs.builders.living.BaseLivingEntityBuilder; 6 | import net.liopyu.entityjs.client.living.KubeJSEntityRenderer; 7 | import net.liopyu.entityjs.entities.living.entityjs.IAnimatableJS; 8 | import net.liopyu.entityjs.util.ContextUtils; 9 | import net.liopyu.entityjs.util.EntityJSHelperClass; 10 | import net.liopyu.liolib.cache.object.BakedGeoModel; 11 | import net.liopyu.liolib.renderer.layer.GeoRenderLayer; 12 | import net.minecraft.client.renderer.MultiBufferSource; 13 | import net.minecraft.client.renderer.RenderType; 14 | import net.minecraft.client.renderer.texture.OverlayTexture; 15 | import net.minecraft.resources.ResourceLocation; 16 | import net.minecraft.world.entity.LivingEntity; 17 | 18 | import java.util.function.Function; 19 | 20 | public class GeoLayerJS extends GeoRenderLayer { 21 | public T entity; 22 | public final GeoLayerJSBuilder geoBuilder; 23 | public final KubeJSEntityRenderer renderer; 24 | public final BaseLivingEntityBuilder builder; 25 | 26 | public GeoLayerJS(KubeJSEntityRenderer entityRendererIn, GeoLayerJSBuilder geoBuilder, BaseLivingEntityBuilder builder) { 27 | super(entityRendererIn); 28 | this.geoBuilder = geoBuilder; 29 | this.renderer = entityRendererIn; 30 | this.builder = builder; 31 | } 32 | 33 | public String entityName() { 34 | return builder.get().toString(); 35 | } 36 | 37 | @Override 38 | protected ResourceLocation getTextureResource(T animatable) { 39 | if (geoBuilder.textureResource != null) { 40 | Object obj = geoBuilder.textureResource.apply(animatable); 41 | if (obj instanceof ResourceLocation r) return r; 42 | EntityJSHelperClass.logErrorMessageOnce("[EntityJS]: Invalid return value for textureResource in newGeoLayer builder. Value: " + obj + ". Must be a ResourceLocation. Defaulting to " + super.getTextureResource(animatable)); 43 | } 44 | return super.getTextureResource(animatable); 45 | } 46 | 47 | @Override 48 | public void preRender(PoseStack poseStack, T animatable, BakedGeoModel bakedModel, RenderType renderType, MultiBufferSource bufferSource, VertexConsumer buffer, float partialTick, int packedLight, int packedOverlay) { 49 | if (geoBuilder.preRender != null && animatable != null) { 50 | final ContextUtils.PreRenderContext context = new ContextUtils.PreRenderContext<>(poseStack, animatable, bakedModel, renderType, bufferSource, buffer, partialTick, packedLight, packedOverlay); 51 | EntityJSHelperClass.consumerCallback(geoBuilder.preRender, context, "[EntityJS]: Error in " + entityName() + "builder for field: preRender"); 52 | super.preRender(poseStack, animatable, bakedModel, renderType, bufferSource, buffer, partialTick, packedLight, packedOverlay); 53 | } else { 54 | super.preRender(poseStack, animatable, bakedModel, renderType, bufferSource, buffer, partialTick, packedLight, packedOverlay); 55 | } 56 | } 57 | 58 | @Override 59 | public void render(PoseStack poseStack, T animatable, BakedGeoModel bakedModel, RenderType renderType, 60 | MultiBufferSource bufferSource, VertexConsumer buffer, float partialTicks, 61 | int packedLightIn, int packedOverlay) { 62 | if (geoBuilder.render != null && animatable != null) { 63 | final ContextUtils.PreRenderContext context = new ContextUtils.PreRenderContext<>(poseStack, animatable, bakedModel, renderType, bufferSource, buffer, partialTicks, packedLightIn, packedOverlay); 64 | EntityJSHelperClass.consumerCallback(geoBuilder.render, context, "[EntityJS]: Error in " + entityName() + "builder for field: render"); 65 | RenderType renderLayer = RenderType.entityCutoutNoCull(getTextureResource(animatable)); 66 | getRenderer().reRender(getDefaultBakedModel(animatable), poseStack, bufferSource, animatable, renderLayer, bufferSource.getBuffer(renderLayer), partialTicks, packedLightIn, OverlayTexture.NO_OVERLAY, 1, 1, 1, 1); 67 | } else { 68 | RenderType renderLayer = RenderType.entityCutoutNoCull(getTextureResource(animatable)); 69 | getRenderer().reRender(getDefaultBakedModel(animatable), poseStack, bufferSource, animatable, renderLayer, bufferSource.getBuffer(renderLayer), partialTicks, packedLightIn, OverlayTexture.NO_OVERLAY, 1, 1, 1, 1); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/client/living/model/GlowingGeoLayerJS.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.client.living.model; 2 | 3 | import com.mojang.blaze3d.vertex.PoseStack; 4 | import com.mojang.blaze3d.vertex.VertexConsumer; 5 | import net.liopyu.entityjs.builders.living.BaseLivingEntityBuilder; 6 | import net.liopyu.entityjs.client.living.KubeJSEntityRenderer; 7 | import net.liopyu.entityjs.entities.living.entityjs.IAnimatableJS; 8 | import net.liopyu.entityjs.util.ContextUtils; 9 | import net.liopyu.entityjs.util.EntityJSHelperClass; 10 | import net.liopyu.liolib.cache.object.BakedGeoModel; 11 | import net.liopyu.liolib.renderer.layer.AutoGlowingGeoLayer; 12 | import net.minecraft.client.renderer.MultiBufferSource; 13 | import net.minecraft.client.renderer.RenderType; 14 | import net.minecraft.client.renderer.texture.OverlayTexture; 15 | import net.minecraft.resources.ResourceLocation; 16 | import net.minecraft.world.entity.LivingEntity; 17 | 18 | import java.util.function.Function; 19 | 20 | public class GlowingGeoLayerJS extends AutoGlowingGeoLayer { 21 | public T entity; 22 | public final GeoLayerJSBuilder geoBuilder; 23 | public final KubeJSEntityRenderer renderer; 24 | public final BaseLivingEntityBuilder builder; 25 | 26 | public GlowingGeoLayerJS(KubeJSEntityRenderer entityRendererIn, GeoLayerJSBuilder geoBuilder, BaseLivingEntityBuilder builder) { 27 | super(entityRendererIn); 28 | this.geoBuilder = geoBuilder; 29 | this.renderer = entityRendererIn; 30 | this.builder = builder; 31 | //this.entity = entityRendererIn.getAnimatable(); 32 | } 33 | 34 | public String entityName() { 35 | return builder.get().toString(); 36 | } 37 | 38 | @Override 39 | protected ResourceLocation getTextureResource(T animatable) { 40 | if (geoBuilder.textureResource != null) { 41 | Object obj = geoBuilder.textureResource.apply(animatable); 42 | if (obj instanceof ResourceLocation r) return r; 43 | EntityJSHelperClass.logErrorMessageOnce("[EntityJS]: Invalid return value for textureResource in newGeoLayer builder. Value: " + obj + ". Must be a ResourceLocation. Defaulting to " + super.getTextureResource(animatable)); 44 | } 45 | return super.getTextureResource(animatable); 46 | } 47 | 48 | @Override 49 | public void preRender(PoseStack poseStack, T animatable, BakedGeoModel bakedModel, RenderType renderType, MultiBufferSource bufferSource, VertexConsumer buffer, float partialTick, int packedLight, int packedOverlay) { 50 | if (geoBuilder.preRender != null && animatable != null) { 51 | final ContextUtils.PreRenderContext context = new ContextUtils.PreRenderContext<>(poseStack, animatable, bakedModel, renderType, bufferSource, buffer, partialTick, packedLight, packedOverlay); 52 | EntityJSHelperClass.consumerCallback(geoBuilder.preRender, context, "[EntityJS]: Error in " + entityName() + "builder for field: preRender"); 53 | super.preRender(poseStack, animatable, bakedModel, renderType, bufferSource, buffer, partialTick, packedLight, packedOverlay); 54 | } else { 55 | super.preRender(poseStack, animatable, bakedModel, renderType, bufferSource, buffer, partialTick, packedLight, packedOverlay); 56 | } 57 | } 58 | 59 | @Override 60 | public void render(PoseStack poseStack, T animatable, BakedGeoModel bakedModel, RenderType renderType, 61 | MultiBufferSource bufferSource, VertexConsumer buffer, float partialTicks, 62 | int packedLightIn, int packedOverlay) { 63 | if (geoBuilder.render != null && animatable != null) { 64 | final ContextUtils.PreRenderContext context = new ContextUtils.PreRenderContext<>(poseStack, animatable, bakedModel, renderType, bufferSource, buffer, partialTicks, packedLightIn, packedOverlay); 65 | EntityJSHelperClass.consumerCallback(geoBuilder.render, context, "[EntityJS]: Error in " + entityName() + "builder for field: render"); 66 | RenderType renderLayer = RenderType.entityCutoutNoCull(getTextureResource(animatable)); 67 | getRenderer().reRender(getDefaultBakedModel(animatable), poseStack, bufferSource, animatable, renderLayer, bufferSource.getBuffer(renderLayer), partialTicks, 15728880, OverlayTexture.NO_OVERLAY, 1, 1, 1, 1); 68 | } else { 69 | RenderType renderLayer = RenderType.entityCutoutNoCull(getTextureResource(animatable)); 70 | getRenderer().reRender(getDefaultBakedModel(animatable), poseStack, bufferSource, animatable, renderLayer, bufferSource.getBuffer(renderLayer), partialTicks, 15728880, OverlayTexture.NO_OVERLAY, 1, 1, 1, 1); 71 | } 72 | } 73 | } -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/client/nonliving/KubeJSArrowEntityRenderer.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.client.nonliving; 2 | 3 | 4 | import com.mojang.blaze3d.vertex.PoseStack; 5 | import net.liopyu.entityjs.builders.nonliving.entityjs.ArrowEntityBuilder; 6 | import net.liopyu.entityjs.entities.nonliving.entityjs.IArrowEntityJS; 7 | import net.liopyu.entityjs.util.ContextUtils; 8 | import net.liopyu.entityjs.util.EntityJSHelperClass; 9 | import net.minecraft.client.renderer.MultiBufferSource; 10 | import net.minecraft.client.renderer.entity.ArrowRenderer; 11 | import net.minecraft.client.renderer.entity.EntityRendererProvider; 12 | import net.minecraft.resources.ResourceLocation; 13 | import net.minecraft.world.entity.projectile.AbstractArrow; 14 | 15 | 16 | public class KubeJSArrowEntityRenderer extends ArrowRenderer { 17 | 18 | private final ArrowEntityBuilder builder; 19 | 20 | public KubeJSArrowEntityRenderer(EntityRendererProvider.Context renderManager, ArrowEntityBuilder builder) { 21 | super(renderManager); 22 | this.builder = builder; 23 | } 24 | 25 | @Override 26 | public void render(T pEntity, float pEntityYaw, float pPartialTicks, PoseStack pMatrixStack, MultiBufferSource pBuffer, int pPackedLight) { 27 | if (builder.render != null) { 28 | var context = new ContextUtils.NLRenderContext<>(pEntity, pEntityYaw, pPartialTicks, pMatrixStack, pBuffer, pPackedLight); 29 | EntityJSHelperClass.consumerCallback(builder.render, context, "[EntityJS]: Error in " + pEntity.getType() + "builder for field: render."); 30 | } 31 | super.render(pEntity, pEntityYaw, pPartialTicks, pMatrixStack, pBuffer, pPackedLight); 32 | } 33 | 34 | @Override 35 | public ResourceLocation getTextureLocation(T entity) { 36 | return (ResourceLocation) builder.textureLocation.apply(entity); 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/client/nonliving/KubeJSBoatRenderer.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.client.nonliving; 2 | 3 | import com.mojang.blaze3d.vertex.PoseStack; 4 | import com.mojang.math.Quaternion; 5 | import com.mojang.math.Vector3f; 6 | import net.liopyu.entityjs.builders.nonliving.vanilla.BoatEntityBuilder; 7 | import net.liopyu.entityjs.client.nonliving.model.BoatEntityModel; 8 | import net.liopyu.entityjs.entities.nonliving.entityjs.IAnimatableJSNL; 9 | import net.liopyu.entityjs.util.ContextUtils; 10 | import net.liopyu.entityjs.util.EntityJSHelperClass; 11 | import net.minecraft.client.renderer.MultiBufferSource; 12 | import net.minecraft.client.renderer.RenderType; 13 | import net.minecraft.client.renderer.entity.EntityRendererProvider; 14 | import net.minecraft.resources.ResourceLocation; 15 | import net.minecraft.util.Mth; 16 | import net.minecraft.world.entity.vehicle.Boat; 17 | import net.liopyu.liolib.renderer.GeoEntityRenderer; 18 | 19 | import javax.annotation.Nullable; 20 | 21 | public class KubeJSBoatRenderer extends GeoEntityRenderer { 22 | private final BoatEntityBuilder builder; 23 | 24 | public KubeJSBoatRenderer(EntityRendererProvider.Context pContext, BoatEntityBuilder builder) { 25 | super(pContext, new BoatEntityModel<>(builder)); 26 | this.builder = (BoatEntityBuilder) builder; 27 | this.shadowRadius = getShadowRadius(); 28 | } 29 | 30 | private float getShadowRadius() { 31 | return builder.setShadowRadius; 32 | } 33 | 34 | @Override 35 | public ResourceLocation getTextureLocation(T entity) { 36 | return (ResourceLocation) builder.textureResource.apply(entity); 37 | } 38 | 39 | @Override 40 | public RenderType getRenderType(T animatable, ResourceLocation texture, @Nullable MultiBufferSource bufferSource, float partialTick) { 41 | return switch (animatable.getBuilder().renderType) { 42 | case SOLID -> RenderType.entitySolid(texture); 43 | case CUTOUT -> RenderType.entityCutout(texture); 44 | case TRANSLUCENT -> RenderType.entityTranslucent(texture); 45 | 46 | }; 47 | } 48 | 49 | public void render(T pEntity, float pEntityYaw, float pPartialTicks, PoseStack pPoseStack, MultiBufferSource pBuffer, int pPackedLight) { 50 | if (builder.render != null) { 51 | var context = new ContextUtils.NLRenderContext<>(pEntity, pEntityYaw, pPartialTicks, pPoseStack, pBuffer, pPackedLight); 52 | EntityJSHelperClass.consumerCallback(builder.render, context, "[EntityJS]: Error in " + pEntity.getType() + "builder for field: render."); 53 | } 54 | pPoseStack.pushPose(); 55 | pPoseStack.translate(0.0, 0.375, 0.0); 56 | pPoseStack.mulPose(Vector3f.YP.rotationDegrees(180.0F - pEntityYaw)); 57 | pPoseStack.mulPose(Vector3f.YP.rotationDegrees(180.0F)); 58 | float f = (float) pEntity.getHurtTime() - pPartialTicks; 59 | float f1 = pEntity.getDamage() - pPartialTicks; 60 | if (f1 < 0.0F) { 61 | f1 = 0.0F; 62 | } 63 | 64 | if (f > 0.0F) { 65 | pPoseStack.mulPose(Vector3f.XP.rotationDegrees(Mth.sin(f) * f * f1 / 10.0F * (float) pEntity.getHurtDir())); 66 | } 67 | 68 | float f2 = pEntity.getBubbleAngle(pPartialTicks); 69 | if (!Mth.equal(f2, 0.0F)) { 70 | pPoseStack.mulPose(new Quaternion(new Vector3f(1.0F, 0.0F, 1.0F), pEntity.getBubbleAngle(pPartialTicks), true)); 71 | } 72 | 73 | super.render(pEntity, pEntityYaw, pPartialTicks, pPoseStack, pBuffer, pPackedLight); 74 | 75 | pPoseStack.popPose(); 76 | } 77 | 78 | } -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/client/nonliving/model/BoatEntityModel.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.client.nonliving.model; 2 | 3 | import net.liopyu.entityjs.builders.nonliving.vanilla.BoatEntityBuilder; 4 | import net.liopyu.entityjs.entities.nonliving.entityjs.IAnimatableJSNL; 5 | import net.minecraft.resources.ResourceLocation; 6 | import net.minecraft.world.entity.vehicle.Boat; 7 | import net.liopyu.liolib.model.GeoModel; 8 | 9 | public class BoatEntityModel extends GeoModel { 10 | private final BoatEntityBuilder builder; 11 | 12 | public BoatEntityModel(BoatEntityBuilder builder) { 13 | this.builder = (BoatEntityBuilder) builder; 14 | } 15 | 16 | @Override 17 | public ResourceLocation getModelResource(T object) { 18 | return (ResourceLocation) builder.modelResource.apply(object); 19 | } 20 | 21 | @Override 22 | public ResourceLocation getTextureResource(T object) { 23 | return (ResourceLocation) builder.textureResource.apply(object); 24 | } 25 | 26 | @Override 27 | public ResourceLocation getAnimationResource(T animatable) { 28 | return (ResourceLocation) builder.animationResource.apply(animatable); 29 | } 30 | } -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/client/nonliving/model/NonLivingEntityModel.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.client.nonliving.model; 2 | 3 | import net.liopyu.entityjs.builders.nonliving.BaseEntityBuilder; 4 | import net.liopyu.entityjs.entities.nonliving.entityjs.IAnimatableJSNL; 5 | import net.minecraft.resources.ResourceLocation; 6 | import net.minecraft.world.entity.Entity; 7 | import net.liopyu.liolib.model.GeoModel; 8 | 9 | public class NonLivingEntityModel extends GeoModel { 10 | private final BaseEntityBuilder builder; 11 | 12 | public NonLivingEntityModel(BaseEntityBuilder builder) { 13 | this.builder = builder; 14 | } 15 | 16 | @Override 17 | public ResourceLocation getModelResource(T object) { 18 | return (ResourceLocation) builder.modelResource.apply(object); 19 | } 20 | 21 | @Override 22 | public ResourceLocation getTextureResource(T object) { 23 | return (ResourceLocation) builder.textureResource.apply(object); 24 | } 25 | 26 | @Override 27 | public ResourceLocation getAnimationResource(T animatable) { 28 | return (ResourceLocation) builder.animationResource.apply(animatable); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/client/utils/VertexModifier.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.client.utils; 2 | 3 | import com.mojang.blaze3d.vertex.VertexConsumer; 4 | 5 | public class VertexModifier implements VertexConsumer { 6 | private final VertexConsumer original; 7 | 8 | public VertexModifier(VertexConsumer original) { 9 | this.original = original; 10 | } 11 | 12 | @Override 13 | public VertexConsumer vertex(double v, double v1, double v2) { 14 | return original.vertex(v, v1, v2); 15 | } 16 | 17 | @Override 18 | public VertexConsumer color(int red, int green, int blue, int alpha) { 19 | return original.color(red, green, blue, alpha); 20 | } 21 | 22 | @Override 23 | public VertexConsumer uv(float u, float v) { 24 | float newU = u; 25 | float newV = v; 26 | return original.uv(newU, newV); 27 | } 28 | 29 | @Override 30 | public VertexConsumer overlayCoords(int u, int v) { 31 | return original.overlayCoords(u, v); 32 | } 33 | 34 | @Override 35 | public VertexConsumer uv2(int u, int v) { 36 | return original.uv2(u, v); 37 | } 38 | 39 | @Override 40 | public VertexConsumer normal(float x, float y, float z) { 41 | return original.normal(x, y, z); 42 | } 43 | 44 | @Override 45 | public void endVertex() { 46 | original.endVertex(); 47 | } 48 | 49 | @Override 50 | public void defaultColor(int red, int green, int blue, int alpha) { 51 | original.defaultColor(red, green, blue, alpha); 52 | } 53 | 54 | @Override 55 | public void unsetDefaultColor() { 56 | original.unsetDefaultColor(); 57 | } 58 | } -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/entities/living/entityjs/ContainerTameableEntityJS.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.entities.living.entityjs; 2 | 3 | import net.liopyu.entityjs.builders.living.BaseLivingEntityBuilder; 4 | import net.liopyu.entityjs.builders.living.entityjs.ContainerTameableJSBuilder; 5 | import net.liopyu.entityjs.util.ModKeybinds; 6 | import net.liopyu.liolib.core.animatable.instance.AnimatableInstanceCache; 7 | import net.liopyu.liolib.util.GeckoLibUtil; 8 | import net.minecraft.client.Minecraft; 9 | import net.minecraft.server.level.ServerLevel; 10 | import net.minecraft.sounds.SoundSource; 11 | import net.minecraft.world.Container; 12 | import net.minecraft.world.ContainerListener; 13 | import net.minecraft.world.entity.*; 14 | import net.minecraft.world.entity.player.Player; 15 | import net.minecraft.world.level.Level; 16 | import org.jetbrains.annotations.Nullable; 17 | 18 | public class ContainerTameableEntityJS extends TamableAnimal implements ContainerListener, HasCustomInventoryScreen, Saddleable, IAnimatableJS { 19 | protected final ContainerTameableJSBuilder builder; 20 | private final AnimatableInstanceCache getAnimatableInstanceCache; 21 | 22 | public ContainerTameableEntityJS(ContainerTameableJSBuilder builder, EntityType pEntityType, Level pLevel) { 23 | super(pEntityType, pLevel); 24 | this.builder = builder; 25 | getAnimatableInstanceCache = GeckoLibUtil.createInstanceCache(this); 26 | } 27 | 28 | //Builder and Animatable logic 29 | @Override 30 | public BaseLivingEntityBuilder getBuilder() { 31 | return builder; 32 | } 33 | 34 | 35 | @Override 36 | public AnimatableInstanceCache getAnimatableInstanceCache() { 37 | return getAnimatableInstanceCache; 38 | } 39 | 40 | @Nullable 41 | @Override 42 | public AgeableMob getBreedOffspring(ServerLevel serverLevel, AgeableMob ageableMob) { 43 | return builder.get().create(serverLevel); 44 | } 45 | 46 | @Override 47 | public void tick() { 48 | super.tick(); 49 | /*if (ModKeybinds.mount_inventory.consumeClick()) { 50 | Player player = Minecraft.getInstance().player; 51 | if (player != null && player.isPassenger() && player.getVehicle() == this) { 52 | openCustomInventoryScreen(player); 53 | } 54 | }*/ 55 | } 56 | 57 | @Override 58 | public void containerChanged(Container container) { 59 | 60 | } 61 | 62 | @Override 63 | public void openCustomInventoryScreen(Player player) { 64 | 65 | } 66 | 67 | @Override 68 | public boolean isSaddleable() { 69 | return false; 70 | } 71 | 72 | @Override 73 | public void equipSaddle(@Nullable SoundSource soundSource) { 74 | 75 | } 76 | 77 | @Override 78 | public boolean isSaddled() { 79 | return false; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/entities/nonliving/entityjs/IArrowEntityJS.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.entities.nonliving.entityjs; 2 | 3 | import net.liopyu.entityjs.builders.nonliving.entityjs.ArrowEntityBuilder; 4 | import net.minecraft.world.item.ItemStack; 5 | 6 | public interface IArrowEntityJS { 7 | ArrowEntityBuilder getArrowBuilder(); 8 | 9 | void setPickUpItem(ItemStack stack); 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/entities/nonliving/entityjs/IProjectileEntityJS.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.entities.nonliving.entityjs; 2 | 3 | import net.liopyu.entityjs.builders.nonliving.BaseNonAnimatableEntityBuilder; 4 | import net.liopyu.entityjs.builders.nonliving.entityjs.ProjectileEntityBuilder; 5 | 6 | public interface IProjectileEntityJS { 7 | BaseNonAnimatableEntityBuilder getProjectileBuilder(); 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/events/BiomeSpawnsEventJS.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.events; 2 | 3 | import com.mojang.datafixers.util.Either; 4 | import dev.latvian.mods.kubejs.event.EventJS; 5 | import dev.latvian.mods.kubejs.typings.Generics; 6 | import dev.latvian.mods.kubejs.typings.Info; 7 | import dev.latvian.mods.kubejs.typings.Param; 8 | import dev.latvian.mods.rhino.util.HideFromJS; 9 | import net.minecraft.resources.ResourceLocation; 10 | import net.minecraft.tags.TagKey; 11 | import net.minecraft.util.random.Weight; 12 | import net.minecraft.world.entity.Entity; 13 | import net.minecraft.world.entity.EntityType; 14 | import net.minecraft.world.level.biome.Biome; 15 | import net.minecraft.world.level.biome.MobSpawnSettings; 16 | import net.minecraftforge.registries.ForgeRegistries; 17 | 18 | import java.util.ArrayList; 19 | import java.util.List; 20 | 21 | public class BiomeSpawnsEventJS extends EventJS { 22 | 23 | @HideFromJS 24 | public final List additions = new ArrayList<>(); 25 | @HideFromJS 26 | public final List removals = new ArrayList<>(); 27 | 28 | @Info(value = "Adds a spawn to the given entity type in the given biomes", params = { 29 | @Param(name = "entityType", value = "The entity type to add a spawn to"), 30 | @Param(name = "biomes", value = "A list of biomes and biome tags to spawn in"), 31 | @Param(name = "weight", value = "The spawn weight"), 32 | @Param(name = "minCount", value = "The minimum number of entities to spawn"), 33 | @Param(name = "maxCount", value = "The maximum number of entities to spawn") 34 | }) 35 | @Generics(value = {Entity.class, String.class}) 36 | public void addSpawn(EntityType entityType, List biomes, int weight, int minCount, int maxCount) { 37 | additions.add(new Addition(entityType, new MobSpawnSettings.SpawnerData(entityType, Weight.of(weight), minCount, maxCount), processBiomes(biomes))); 38 | } 39 | 40 | @Info(value = "Removes the given entity type spawns from the given biomes", params = { 41 | @Param(name = "entityType", value = "The entity type to remove spawns from"), 42 | @Param(name = "biomes", value = "A list of biomes and biome tags to remove the spawns from") 43 | }) 44 | @Generics(value = {Entity.class, String.class}) 45 | public void removeSpawn(EntityType entityType, List biomes) { 46 | removals.add(new Removal(entityType, processBiomes(biomes))); 47 | } 48 | 49 | @HideFromJS 50 | public static List>> processBiomes(List biomes) { 51 | final List>> biomeList = new ArrayList<>(); 52 | for (String biome : biomes) { 53 | if (biome.charAt(0) == '#') { 54 | biomeList.add(Either.right(TagKey.create(ForgeRegistries.Keys.BIOMES, new ResourceLocation(biome.substring(1))))); 55 | } else { 56 | biomeList.add(Either.left(new ResourceLocation(biome))); 57 | } 58 | } 59 | return biomeList; 60 | } 61 | 62 | public record Addition(EntityType entityType, MobSpawnSettings.SpawnerData spawnData, List>> biomes) {} 63 | 64 | public record Removal(EntityType entityType, List>> biomes) {} 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/events/BuildBrainEventJS.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.events; 2 | 3 | import com.google.common.collect.ImmutableList; 4 | import dev.latvian.mods.kubejs.event.EventJS; 5 | import net.liopyu.entityjs.util.ai.Behaviors; 6 | import net.minecraft.world.entity.LivingEntity; 7 | import net.minecraft.world.entity.ai.Brain; 8 | import net.minecraft.world.entity.ai.behavior.Behavior; 9 | import net.minecraft.world.entity.schedule.Activity; 10 | 11 | import java.util.List; 12 | import java.util.Set; 13 | 14 | public class BuildBrainEventJS extends EventJS { 15 | 16 | private final Brain base; 17 | 18 | public final Behaviors behaviors = Behaviors.INSTANCE; 19 | 20 | public BuildBrainEventJS(Brain base) { 21 | this.base = base; 22 | } 23 | 24 | public void coreActivity(int i, List> behaviors) { 25 | base.addActivity(Activity.CORE, i, ImmutableList.copyOf(behaviors)); 26 | base.setCoreActivities(Set.of(Activity.CORE)); 27 | } 28 | 29 | public void idleActivity(int i, List> behaviors) { 30 | base.addActivity(Activity.IDLE, i, ImmutableList.copyOf(behaviors)); 31 | base.setDefaultActivity(Activity.IDLE); 32 | } 33 | 34 | public void addActivity(Activity activity, int i, List> behaviors) { 35 | base.addActivity(activity, i, ImmutableList.copyOf(behaviors)); 36 | } 37 | } -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/events/BuildBrainProviderEventJS.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.events; 2 | 3 | import dev.latvian.mods.kubejs.event.EventJS; 4 | import dev.latvian.mods.kubejs.typings.Info; 5 | import net.minecraft.world.entity.LivingEntity; 6 | import net.minecraft.world.entity.ai.Brain; 7 | import net.minecraft.world.entity.ai.memory.MemoryModuleType; 8 | import net.minecraft.world.entity.ai.sensing.Sensor; 9 | import net.minecraft.world.entity.ai.sensing.SensorType; 10 | import net.minecraft.world.entity.animal.allay.Allay; 11 | 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | 15 | @Info(value = """ 16 | This event is fired during entity creation and is responsible 17 | for adding the `MemoryModuleType` and `SensorType`s the used 18 | by the entity. 19 | 20 | This is only posted for entities made through a builder 21 | """) 22 | public class BuildBrainProviderEventJS extends EventJS { 23 | 24 | private final List> memories; 25 | private final List>> sensors; 26 | 27 | public BuildBrainProviderEventJS() { 28 | memories = new ArrayList<>(); 29 | sensors = new ArrayList<>(); 30 | } 31 | 32 | @Info(value = "Adds the provided `MemoryModuleType` to the entity type's memories") 33 | public void addMemory(MemoryModuleType memory) { 34 | memories.add(memory); 35 | } 36 | 37 | @Info(value = "Adds the provided `SensorType` to the entity type's sensors") 38 | public void addSensor(SensorType> sensor) { 39 | sensors.add(sensor); 40 | } 41 | 42 | public Brain.Provider provide() { 43 | return Brain.provider(memories, sensors); 44 | } 45 | } -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/events/GoalEventJS.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.events; 2 | 3 | import dev.latvian.mods.kubejs.event.EventJS; 4 | import net.minecraft.world.entity.Mob; 5 | import net.minecraft.world.entity.NeutralMob; 6 | import net.minecraft.world.entity.PathfinderMob; 7 | import net.minecraft.world.entity.TamableAnimal; 8 | import net.minecraft.world.entity.ai.goal.GoalSelector; 9 | import net.minecraft.world.entity.animal.Animal; 10 | import net.minecraft.world.entity.animal.horse.AbstractHorse; 11 | import net.minecraft.world.entity.monster.RangedAttackMob; 12 | 13 | public abstract class GoalEventJS extends EventJS { 14 | 15 | protected final T mob; 16 | protected final GoalSelector selector; 17 | protected final boolean isPathFinder; 18 | protected final boolean isAnimal; 19 | protected final boolean isTamable; 20 | protected final boolean isRangedAttack; 21 | protected final boolean isHorse; 22 | protected final boolean isNeutral; 23 | 24 | public GoalEventJS(T mob, GoalSelector selector) { 25 | this.mob = mob; 26 | this.selector = selector; 27 | isPathFinder = mob instanceof PathfinderMob; 28 | isAnimal = mob instanceof Animal; 29 | isTamable = mob instanceof TamableAnimal; 30 | isRangedAttack = mob instanceof RangedAttackMob; 31 | isHorse = mob instanceof AbstractHorse; 32 | isNeutral = mob instanceof NeutralMob; 33 | } 34 | 35 | public Mob getEntity() { 36 | return this.mob; 37 | } 38 | } -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/events/ModifyAttributeEventJS.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.events; 2 | 3 | import dev.latvian.mods.kubejs.event.EventJS; 4 | import dev.latvian.mods.kubejs.typings.Info; 5 | import dev.latvian.mods.kubejs.typings.Param; 6 | import dev.latvian.mods.rhino.util.HideFromJS; 7 | import net.liopyu.entityjs.util.EntityJSHelperClass; 8 | import net.minecraft.resources.ResourceLocation; 9 | import net.minecraft.world.entity.EntityType; 10 | import net.minecraft.world.entity.LivingEntity; 11 | import net.minecraft.world.entity.ai.attributes.Attribute; 12 | import net.minecraftforge.event.entity.EntityAttributeModificationEvent; 13 | import net.minecraftforge.registries.ForgeRegistries; 14 | 15 | import java.util.ArrayList; 16 | import java.util.List; 17 | import java.util.function.Consumer; 18 | 19 | public class ModifyAttributeEventJS extends EventJS { 20 | 21 | private final EntityAttributeModificationEvent event; 22 | 23 | public ModifyAttributeEventJS(EntityAttributeModificationEvent event) { 24 | this.event = event; 25 | } 26 | 27 | @Info(value = "Modifies the given entity type's attributes", params = { 28 | @Param(name = "entityType", value = "The entity type whose default attributes are to be modified"), 29 | @Param(name = "attributes", value = "A consumer for setting the default attributes and their values") 30 | }) 31 | public void modify(EntityType entityType, Consumer attributes) { 32 | final AttributeModificationHelper helper = new AttributeModificationHelper(entityType, event); 33 | attributes.accept(helper); 34 | } 35 | 36 | @Info(value = "Returns a list of all entity types that can have their attributes modified by this event") 37 | public List> getAllTypes() { 38 | return event.getTypes(); 39 | } 40 | 41 | @Info(value = "Returns a list of all attributes the given entity type has by default") 42 | public List getAttributes(EntityType entityType) { 43 | final List present = new ArrayList<>(); 44 | for (Attribute attribute : ForgeRegistries.ATTRIBUTES.getValues()) { 45 | if (event.has(entityType, attribute)) { 46 | present.add(attribute); 47 | } 48 | } 49 | return present; 50 | } 51 | 52 | public record AttributeModificationHelper(@HideFromJS EntityType type, 53 | @HideFromJS EntityAttributeModificationEvent event) { 54 | 55 | @Info(value = """ 56 | Adds the given attribute to the entity type, using its default value 57 | 58 | It is safe to add an attribute that an entity type already has 59 | """) 60 | public void add(Attribute attribute) { 61 | event.add(type, attribute); 62 | } 63 | 64 | @Info(value = """ 65 | Adds the given attribute to the entity type, using the provided default value 66 | 67 | It is safe to add an attribute that an entity type already has 68 | """, params = { 69 | @Param(name = "attribute", value = "The attribute to add"), 70 | @Param(name = "defaultValue", value = "The default value of the attribute") 71 | }) 72 | public void add(Object attribute, double defaultValue) { 73 | if (attribute instanceof String string) { 74 | ResourceLocation stringLocation = new ResourceLocation(string.toLowerCase()); 75 | Attribute att = ForgeRegistries.ATTRIBUTES.getValue(stringLocation); 76 | if (att != null) { 77 | event.add(type, att, defaultValue); 78 | } else { 79 | EntityJSHelperClass.logErrorMessageOnce("[EntityJS]: Unable to add attribute, attribute " + attribute + " does not exist"); 80 | } 81 | } else if (attribute instanceof Attribute att) { 82 | event.add(type, att, defaultValue); 83 | } else 84 | EntityJSHelperClass.logErrorMessageOnce("[EntityJS]: Unable to add attribute, attribute: " + attribute + ". Must be of type Attribute or resource location. Example: \"minecraft:generic.max_health\""); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/events/RegisterMobCategoryEventJS.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.events; 2 | 3 | import dev.latvian.mods.kubejs.event.EventJS; 4 | import net.liopyu.entityjs.EntityJSMod; 5 | import net.minecraftforge.event.entity.EntityAttributeModificationEvent; 6 | import net.minecraftforge.eventbus.api.Event; 7 | import net.minecraftforge.eventbus.api.SubscribeEvent; 8 | import net.minecraftforge.fml.common.Mod; 9 | 10 | import java.util.function.Consumer; 11 | 12 | //TODO: Eventually add custom Mob Categories 13 | @Mod.EventBusSubscriber(modid = EntityJSMod.MOD_ID, bus = Mod.EventBusSubscriber.Bus.FORGE) 14 | public class RegisterMobCategoryEventJS extends EventJS { 15 | private RegisterMobCategoryEvent event; 16 | 17 | public RegisterMobCategoryEventJS(RegisterMobCategoryEvent event) { 18 | this.event = event; 19 | } 20 | 21 | @SubscribeEvent 22 | public void registerMobCategories(RegisterMobCategoryEvent event) { 23 | this.event = event; 24 | } 25 | 26 | public static class RegisterMobCategoryEvent extends Event { 27 | private final Consumer registrationHelperConsumer; 28 | 29 | public RegisterMobCategoryEvent(Consumer registrationHelperConsumer) { 30 | this.registrationHelperConsumer = registrationHelperConsumer; 31 | } 32 | 33 | public void registerCategories(String name, String displayName, int max, boolean isFriendly, boolean isPersistent, int despawnDistance) { 34 | registrationHelperConsumer.accept(new MobCategoryRegistrationHelper(name, displayName, max, isFriendly, isPersistent, despawnDistance)); 35 | } 36 | } 37 | 38 | public static class MobCategoryRegistrationHelper { 39 | private final String name; 40 | private final String displayName; 41 | private final int max; 42 | private final boolean isFriendly; 43 | private final boolean isPersistent; 44 | private final int despawnDistance; 45 | 46 | public MobCategoryRegistrationHelper(String name, String displayName, int max, boolean isFriendly, boolean isPersistent, int despawnDistance) { 47 | this.name = name; 48 | this.displayName = displayName; 49 | this.max = max; 50 | this.isFriendly = isFriendly; 51 | this.isPersistent = isPersistent; 52 | this.despawnDistance = despawnDistance; 53 | } 54 | 55 | public String getName() { 56 | return name; 57 | } 58 | 59 | public String getDisplayName() { 60 | return displayName; 61 | } 62 | 63 | public int getMax() { 64 | return max; 65 | } 66 | 67 | public boolean isFriendly() { 68 | return isFriendly; 69 | } 70 | 71 | public boolean isPersistent() { 72 | return isPersistent; 73 | } 74 | 75 | public int getDespawnDistance() { 76 | return despawnDistance; 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/events/RegisterSpawnPlacementsEventJS.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.events; 2 | 3 | import dev.latvian.mods.kubejs.event.EventJS; 4 | import dev.latvian.mods.kubejs.typings.Info; 5 | import dev.latvian.mods.kubejs.typings.Param; 6 | import net.minecraft.world.entity.Entity; 7 | import net.minecraft.world.entity.EntityType; 8 | import net.minecraft.world.entity.SpawnPlacements; 9 | import net.minecraft.world.level.levelgen.Heightmap; 10 | import net.minecraftforge.event.entity.SpawnPlacementRegisterEvent; 11 | 12 | public class RegisterSpawnPlacementsEventJS extends EventJS { 13 | 14 | private final SpawnPlacementRegisterEvent event; 15 | 16 | public RegisterSpawnPlacementsEventJS(SpawnPlacementRegisterEvent event) { 17 | this.event = event; 18 | } 19 | 20 | @Info(value = "Replaces the given entity type's spawn rules", params = { 21 | @Param(name = "entityType", value = "The entity type whose spawn placement is being replaced"), 22 | @Param(name = "placementType", value = "The spawn placement type to use"), 23 | @Param(name = "heightmap", value = "The heightmap to use"), 24 | @Param(name = "predicate", value = "The spawn predicate for the entity type's spawning") 25 | }) 26 | public void replace(EntityType entityType, SpawnPlacements.Type placementType, Heightmap.Types heightmap, SpawnPlacements.SpawnPredicate predicate) { 27 | event.register(entityType, placementType, heightmap, predicate, SpawnPlacementRegisterEvent.Operation.REPLACE); 28 | } 29 | 30 | @Info(value = "ANDs the given spawn predicate with the existing spawn predicates of the given entity type", params = { 31 | @Param(name = "entityType", value = "The entity type whose spawn placement is being modified"), 32 | @Param(name = "predicate", value = "The spawn predicate that will be ANDed with the entity type's existing spawn predicates") 33 | }) 34 | public void and(EntityType entityType, SpawnPlacements.SpawnPredicate predicate) { 35 | event.register(entityType, predicate, SpawnPlacementRegisterEvent.Operation.AND); 36 | } 37 | 38 | @Info(value = "ORs the given spawn predicate with the existing spawn predicate of the given entity type", params = { 39 | @Param(name = "entityType", value = "The entity type whose spawn placement is being modified"), 40 | @Param(name = "predicate", value = "The spawn predicate that will be ORed with the entity type's existing spawn predicates") 41 | }) 42 | public void or(EntityType entityType, SpawnPlacements.SpawnPredicate predicate) { 43 | event.register(entityType, predicate, SpawnPlacementRegisterEvent.Operation.OR); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/inventory/ContainerJS.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.inventory; 2 | 3 | import net.liopyu.entityjs.builders.living.entityjs.ContainerTameableJSBuilder; 4 | import net.minecraft.world.Container; 5 | import net.minecraft.world.entity.player.Player; 6 | import net.minecraft.world.inventory.AbstractContainerMenu; 7 | import net.minecraft.world.inventory.MenuType; 8 | import net.minecraft.world.item.ItemStack; 9 | import org.jetbrains.annotations.Nullable; 10 | 11 | public class ContainerJS extends AbstractContainerMenu { 12 | private final Container mobInventory; 13 | private final ContainerTameableJSBuilder mob; 14 | 15 | protected ContainerJS(Container mobInventory, 16 | ContainerTameableJSBuilder mob, 17 | @Nullable MenuType pMenuType, 18 | int pContainerId) { 19 | super(pMenuType, pContainerId); 20 | this.mobInventory = mobInventory; 21 | this.mob = mob; 22 | } 23 | 24 | @Override 25 | public ItemStack quickMoveStack(Player player, int i) { 26 | return null; 27 | } 28 | 29 | @Override 30 | public boolean stillValid(Player player) { 31 | return false; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/item/ArrowItemBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.item; 2 | 3 | import dev.latvian.mods.kubejs.item.ItemBuilder; 4 | import dev.latvian.mods.kubejs.typings.Info; 5 | import net.liopyu.entityjs.builders.nonliving.entityjs.ArrowEntityJSBuilder; 6 | import net.liopyu.entityjs.entities.nonliving.entityjs.ArrowEntityJS; 7 | import net.minecraft.resources.ResourceLocation; 8 | import net.minecraft.world.entity.LivingEntity; 9 | import net.minecraft.world.entity.projectile.AbstractArrow; 10 | import net.minecraft.world.item.ArrowItem; 11 | import net.minecraft.world.item.Item; 12 | import net.minecraft.world.item.ItemStack; 13 | import net.minecraft.world.level.Level; 14 | 15 | 16 | public class ArrowItemBuilder extends ItemBuilder { 17 | public transient final ArrowEntityJSBuilder parent; 18 | public transient boolean canBePickedUp; 19 | 20 | public ArrowItemBuilder(ResourceLocation i, ArrowEntityJSBuilder parent) { 21 | super(i); 22 | this.parent = parent; 23 | canBePickedUp = true; 24 | texture = i.getNamespace() + ":item/" + i.getPath(); 25 | } 26 | 27 | @Info(value = "Sets if the arrow can be picked up") 28 | public ArrowItemBuilder canBePickedup(boolean canBePickedUp) { 29 | this.canBePickedUp = canBePickedUp; 30 | return this; 31 | } 32 | 33 | @Override 34 | public Item createObject() { 35 | return new ArrowItem(createItemProperties()) { 36 | @Override 37 | public AbstractArrow createArrow(Level pLevel, ItemStack pStack, LivingEntity pShooter) { 38 | final ArrowEntityJS arrow = new ArrowEntityJS(pLevel, pShooter, parent); 39 | if (canBePickedUp) { 40 | final ItemStack stack = new ItemStack(pStack.getItem()); 41 | stack.setTag(pStack.getTag()); 42 | arrow.setPickUpItem(stack); 43 | } 44 | return arrow; 45 | } 46 | }; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/item/CGMProjectileItemBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.item; 2 | 3 | import com.mrcrayfish.guns.item.AmmoItem; 4 | import dev.latvian.mods.kubejs.item.ItemBuilder; 5 | import net.liopyu.entityjs.builders.nonliving.modded.CGMProjectileEntityJSBuilder; 6 | import net.minecraft.resources.ResourceLocation; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | 12 | public class CGMProjectileItemBuilder extends ItemBuilder { 13 | public static final List thisList = new ArrayList<>(); 14 | public transient final CGMProjectileEntityJSBuilder parent; 15 | 16 | public CGMProjectileItemBuilder(ResourceLocation i, CGMProjectileEntityJSBuilder parent) { 17 | super(i); 18 | thisList.add(this); 19 | this.parent = parent; 20 | texture = i.getNamespace() + ":item/" + i.getPath(); 21 | } 22 | 23 | @Override 24 | public AmmoItem createObject() { 25 | return new AmmoItem(createItemProperties()); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/item/SpawnEggItemBuilder.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.item; 2 | 3 | import dev.latvian.mods.kubejs.generator.AssetJsonGenerator; 4 | import dev.latvian.mods.kubejs.item.ItemBuilder; 5 | import dev.latvian.mods.kubejs.typings.Info; 6 | import net.liopyu.entityjs.builders.living.entityjs.MobBuilder; 7 | import net.minecraft.resources.ResourceLocation; 8 | import net.minecraft.world.item.Item; 9 | import net.minecraftforge.common.ForgeSpawnEggItem; 10 | 11 | 12 | public class SpawnEggItemBuilder extends ItemBuilder { 13 | 14 | public transient int backgroundColor; 15 | public transient int highlightColor; 16 | public transient final MobBuilder parent; 17 | 18 | public SpawnEggItemBuilder(ResourceLocation i, MobBuilder parent) { 19 | super(i); 20 | backgroundColor = 0xFFFFFFFF; 21 | highlightColor = 0XFFFFFFFF; 22 | this.parent = parent; 23 | } 24 | 25 | @Info(value = "Sets the background color of the egg item") 26 | public SpawnEggItemBuilder backgroundColor(int i) { 27 | backgroundColor = i; 28 | return this; 29 | } 30 | 31 | @Info(value = "Sets the highlight color of the egg item") 32 | public SpawnEggItemBuilder highlightColor(int i) { 33 | highlightColor = i; 34 | return this; 35 | } 36 | 37 | @Override 38 | public Item createObject() { 39 | return new ForgeSpawnEggItem(parent, backgroundColor, highlightColor, createItemProperties()); 40 | } 41 | 42 | @Override 43 | public void generateAssetJsons(AssetJsonGenerator generator) { 44 | if (modelJson != null) { 45 | generator.json(AssetJsonGenerator.asItemModelLocation(id), modelJson); 46 | return; 47 | } 48 | 49 | generator.itemModel(id, m -> { 50 | if (!parentModel.isEmpty()) { 51 | m.parent(parentModel); 52 | 53 | if (textureJson.size() == 0) { 54 | texture(newID("item/", "").toString()); 55 | } 56 | m.textures(textureJson); 57 | } else { 58 | m.parent("item/template_spawn_egg"); 59 | 60 | if (textureJson.size() != 0) { 61 | m.textures(textureJson); 62 | } 63 | } 64 | }); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/mixin/AnimationControllerMixin.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.mixin; 2 | 3 | import net.liopyu.entityjs.util.implementation.IAnimationControllerJS; 4 | import net.liopyu.liolib.cache.object.GeoBone; 5 | import net.liopyu.liolib.core.animatable.GeoAnimatable; 6 | import net.liopyu.liolib.core.animatable.model.CoreGeoBone; 7 | import net.liopyu.liolib.core.animatable.model.CoreGeoModel; 8 | import net.liopyu.liolib.core.animation.AnimationController; 9 | import net.liopyu.liolib.core.animation.AnimationState; 10 | import net.liopyu.liolib.core.state.BoneSnapshot; 11 | import net.liopyu.liolib.model.GeoModel; 12 | import org.spongepowered.asm.mixin.Final; 13 | import org.spongepowered.asm.mixin.Mixin; 14 | import org.spongepowered.asm.mixin.Shadow; 15 | import org.spongepowered.asm.mixin.Unique; 16 | import org.spongepowered.asm.mixin.injection.At; 17 | import org.spongepowered.asm.mixin.injection.Inject; 18 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 19 | 20 | import java.util.Map; 21 | import java.util.function.Function; 22 | 23 | @Mixin(value = AnimationController.class, remap = false) 24 | public class AnimationControllerMixin implements IAnimationControllerJS { 25 | @Unique 26 | private double entityJs$currentAnimationTick = 0; 27 | @Unique 28 | private AnimationController entityJs$self = (AnimationController) (Object) this; 29 | @Shadow 30 | protected boolean shouldResetTick; 31 | @Shadow 32 | protected Function animationSpeedModifier; 33 | @Final 34 | @Shadow 35 | protected T animatable; 36 | @Shadow 37 | protected double tickOffset; 38 | 39 | @Unique 40 | protected double entityJs$adjustTick(double tick) { 41 | if (!this.shouldResetTick) 42 | return this.animationSpeedModifier.apply(this.animatable) * Math.max(tick - this.tickOffset, 0); 43 | return 0; 44 | } 45 | 46 | @Inject(method = "process", at = @At(value = "HEAD")) 47 | private void entityJs$onProcess(CoreGeoModel model, AnimationState state, Map bones, Map snapshots, double seekTime, boolean crashWhenCantFindBone, CallbackInfo ci) { 48 | 49 | this.entityJs$currentAnimationTick = this.entityJs$adjustTick(seekTime); 50 | } 51 | 52 | public double entityJs$getCurrentAnimationTick() { 53 | return this.entityJs$currentAnimationTick; 54 | } 55 | 56 | 57 | } 58 | 59 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/mixin/KubeJSCommandsMixin.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.mixin; 2 | 3 | import dev.latvian.mods.kubejs.command.KubeJSCommands; 4 | import net.liopyu.entityjs.util.EntityJSHelperClass; 5 | import net.minecraft.commands.CommandSourceStack; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.Inject; 9 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 10 | 11 | /** 12 | * Mixin class to reload error messages on each startup script reload. 13 | * This ensures that scripters can see error messages again after reloading startup scripts, 14 | * as startup scripts are the only possible way to trigger a reload for most entity methods. 15 | */ 16 | @Mixin(KubeJSCommands.class) 17 | public abstract class KubeJSCommandsMixin { 18 | @Inject(method = "reloadStartup", at = @At(value = "RETURN", ordinal = 0), remap = false) 19 | private static void entityjs$onReloadStartup(CommandSourceStack source, CallbackInfoReturnable cir) { 20 | EntityJSHelperClass.errorMessagesLogged.clear(); 21 | EntityJSHelperClass.warningMessagesLogged.clear(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/mixin/ProjectileMixin.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.mixin; 2 | 3 | import net.liopyu.entityjs.builders.modification.ModifyEntityBuilder; 4 | import net.liopyu.entityjs.builders.modification.ModifyProjectileBuilder; 5 | import net.liopyu.entityjs.util.ContextUtils; 6 | import net.liopyu.entityjs.util.EntityJSHelperClass; 7 | import net.liopyu.entityjs.util.EventHandlers; 8 | import net.minecraft.world.entity.Entity; 9 | import net.minecraft.world.entity.EntityType; 10 | import net.minecraft.world.entity.projectile.Projectile; 11 | import net.minecraft.world.level.Level; 12 | import net.minecraft.world.phys.BlockHitResult; 13 | import net.minecraft.world.phys.EntityHitResult; 14 | import org.spongepowered.asm.mixin.Mixin; 15 | import org.spongepowered.asm.mixin.Unique; 16 | import org.spongepowered.asm.mixin.injection.At; 17 | import org.spongepowered.asm.mixin.injection.Inject; 18 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 19 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 20 | 21 | import static net.liopyu.entityjs.events.EntityModificationEventJS.getOrCreate; 22 | 23 | @Mixin(value = Projectile.class, remap = true) 24 | public class ProjectileMixin { 25 | @Unique 26 | private Object entityJs$builder; 27 | 28 | @Unique 29 | private Object entityJs$entityObject = this; 30 | 31 | 32 | @Unique 33 | private Projectile entityJs$getLivingEntity() { 34 | return (Projectile) entityJs$entityObject; 35 | } 36 | 37 | @Unique 38 | private String entityJs$entityName() { 39 | return entityJs$getLivingEntity().getType().toString(); 40 | } 41 | 42 | @Inject(method = "", at = @At("RETURN"), remap = true) 43 | private void entityjs$onEntityInit(EntityType pEntityType, Level pLevel, CallbackInfo ci) { 44 | var entityType = entityJs$getLivingEntity().getType(); 45 | if (EventHandlers.modifyEntity.hasListeners()) { 46 | var eventJS = getOrCreate(entityType, entityJs$getLivingEntity()); 47 | EventHandlers.modifyEntity.post(eventJS); 48 | entityJs$builder = eventJS.getBuilder(); 49 | } 50 | } 51 | 52 | @Inject(method = "onHitEntity", at = @At("HEAD"), remap = true, cancellable = true) 53 | protected void onHitEntity(EntityHitResult pResult, CallbackInfo ci) { 54 | if (entityJs$builder != null && entityJs$builder instanceof ModifyProjectileBuilder builder) { 55 | if (builder != null && builder.onHitEntity != null) { 56 | final ContextUtils.ProjectileEntityHitContext context = new ContextUtils.ProjectileEntityHitContext(pResult, entityJs$getLivingEntity()); 57 | EntityJSHelperClass.consumerCallback(builder.onHitEntity, context, "[EntityJS]: Error in " + entityJs$entityName() + "builder for field: onHitEntity."); 58 | } 59 | } 60 | 61 | } 62 | 63 | @Inject(method = "onHitBlock", at = @At("HEAD"), remap = true, cancellable = true) 64 | protected void onHitBlock(BlockHitResult pResult, CallbackInfo ci) { 65 | if (entityJs$builder != null && entityJs$builder instanceof ModifyProjectileBuilder builder) { 66 | if (builder != null && builder.onHitBlock != null) { 67 | final ContextUtils.ProjectileBlockHitContext context = new ContextUtils.ProjectileBlockHitContext(pResult, entityJs$getLivingEntity()); 68 | EntityJSHelperClass.consumerCallback(builder.onHitBlock, context, "[EntityJS]: Error in " + entityJs$entityName() + "builder for field: onHitBlock."); 69 | } 70 | } 71 | 72 | } 73 | 74 | @Inject(method = "canHitEntity", at = @At("HEAD"), remap = true, cancellable = true) 75 | protected void canHitEntity(Entity pTarget, CallbackInfoReturnable cir) { 76 | if (entityJs$builder != null && entityJs$builder instanceof ModifyProjectileBuilder builder) { 77 | if (builder != null && builder.canHitEntity != null) { 78 | Object obj = builder.canHitEntity.apply(pTarget); 79 | if (obj instanceof Boolean b) { 80 | boolean bool = cir.getReturnValue() && b; 81 | cir.setReturnValue(bool); 82 | return; 83 | } 84 | EntityJSHelperClass.logErrorMessageOnce("[EntityJS]: Invalid canHitEntity for arrow builder: " + obj + ". Must be a boolean. Defaulting to super method: " + cir.getReturnValue()); 85 | } 86 | } 87 | } 88 | } -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/mixin/ServerScriptManagerMixin.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.mixin; 2 | 3 | import com.llamalad7.mixinextras.injector.wrapoperation.Operation; 4 | import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; 5 | import dev.latvian.mods.kubejs.generator.DataJsonGenerator; 6 | import dev.latvian.mods.kubejs.script.data.VirtualKubeJSDataPack; 7 | import dev.latvian.mods.kubejs.server.ServerScriptManager; 8 | import net.liopyu.entityjs.util.EventHandlers; 9 | import net.minecraft.server.packs.resources.CloseableResourceManager; 10 | import net.minecraft.server.packs.resources.MultiPackResourceManager; 11 | import net.minecraft.server.packs.resources.ResourceManager; 12 | import org.spongepowered.asm.mixin.Mixin; 13 | import org.spongepowered.asm.mixin.Unique; 14 | import org.spongepowered.asm.mixin.injection.At; 15 | import org.spongepowered.asm.mixin.injection.Inject; 16 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 17 | 18 | import java.util.LinkedList; 19 | 20 | /** 21 | * A 'simple' mixin into Kube's {@link ServerScriptManager} to ensure our data 22 | * is added before forge runs its biome modifiers, which are 23 | * read before {@link dev.latvian.mods.kubejs.registry.BuilderBase#generateDataJsons(DataJsonGenerator) BuilderBase#generateDataJsons()} 24 | * and {@link dev.latvian.mods.kubejs.KubeJSPlugin#generateDataJsons(DataJsonGenerator) KubeJSPlugin#generateDataJsons()}'s data is realized. 25 | *

26 | * This is taken from KubeJS TFC 27 | * and modified to use Mixin Extra's {@link WrapOperation} annotation 28 | */ 29 | // Currently unused but keeping it around just in case 30 | @Mixin(value = ServerScriptManager.class, remap = false) 31 | public abstract class ServerScriptManagerMixin { 32 | 33 | @Unique 34 | private MultiPackResourceManager entityjs$WrappedManager; 35 | @Unique 36 | private VirtualKubeJSDataPack entityjs$VirtualDataPack; 37 | 38 | @WrapOperation(method = "wrapResourceManager", at = @At(value = "INVOKE", target = "Ldev/latvian/mods/kubejs/server/ServerScriptManager;reloadScriptManager(Lnet/minecraft/server/packs/resources/ResourceManager;)V"), remap = false) 39 | private void entityjs$captureMultiManager(ServerScriptManager instance, ResourceManager resourceManager, Operation original) { 40 | if (resourceManager instanceof MultiPackResourceManager multiManager) { 41 | entityjs$WrappedManager = multiManager; 42 | } 43 | original.call(instance, resourceManager); 44 | } 45 | 46 | @WrapOperation(method = "wrapResourceManager", at = @At(value = "INVOKE", target = "Ljava/util/LinkedList;addFirst(Ljava/lang/Object;)V"), remap = false) 47 | private void entityjs$captureVirtualDataPack(LinkedList instance, E e, Operation original) { 48 | if (e instanceof VirtualKubeJSDataPack pack) { 49 | entityjs$VirtualDataPack = pack; 50 | } 51 | original.call(instance, e); // The annotation parser isn't very happy about this despite it being correct (seemingly) 52 | } 53 | 54 | @Inject(method = "wrapResourceManager", at = @At(target = "Ldev/latvian/mods/kubejs/event/EventHandler;post(Ldev/latvian/mods/kubejs/script/ScriptTypeHolder;Ldev/latvian/mods/kubejs/event/EventJS;)Ldev/latvian/mods/kubejs/event/EventResult;", shift = At.Shift.AFTER, value = "INVOKE", ordinal = 1), remap = false) 55 | private void entityjs$postEvent(CloseableResourceManager original, CallbackInfoReturnable cir) { 56 | EventHandlers.postDataEvent(entityjs$VirtualDataPack, entityjs$WrappedManager); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/util/EntityJSUtils.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.util; 2 | 3 | import dev.latvian.mods.kubejs.registry.BuilderBase; 4 | import dev.latvian.mods.kubejs.typings.Info; 5 | import net.liopyu.entityjs.builders.misc.JumpControlJSBuilder; 6 | import net.liopyu.entityjs.builders.misc.LookControlJSBuilder; 7 | import net.liopyu.entityjs.builders.misc.MoveControlJSBuilder; 8 | import net.liopyu.entityjs.util.ai.JumpControlJS; 9 | import net.liopyu.entityjs.util.ai.LookControlJS; 10 | import net.liopyu.entityjs.util.ai.MoveControlJS; 11 | import net.minecraft.world.entity.EntityType; 12 | import net.minecraft.world.entity.Mob; 13 | import net.minecraft.world.entity.ai.navigation.*; 14 | import net.minecraft.world.level.Level; 15 | import net.liopyu.entityjs.builders.living.BaseLivingEntityBuilder; 16 | import net.liopyu.entityjs.builders.nonliving.BaseEntityBuilder; 17 | import net.liopyu.entityjs.builders.nonliving.entityjs.ArrowEntityBuilder; 18 | import net.liopyu.entityjs.builders.nonliving.entityjs.ProjectileEntityBuilder; 19 | import net.liopyu.entityjs.builders.nonliving.vanilla.BoatEntityBuilder; 20 | import net.liopyu.entityjs.builders.nonliving.vanilla.EyeOfEnderEntityBuilder; 21 | 22 | import java.util.function.Consumer; 23 | 24 | public interface EntityJSUtils { 25 | @Info("Helper method to get the entity's builder for the type.") 26 | static > T getEntityBuilder(EntityType type) { 27 | for (ArrowEntityBuilder builder : ArrowEntityBuilder.thisList) { 28 | if (builder.get() == type) return (T) builder; 29 | } 30 | for (ProjectileEntityBuilder builder : ProjectileEntityBuilder.thisList) { 31 | if (builder.get() == type) return (T) builder; 32 | } 33 | for (EyeOfEnderEntityBuilder builder : EyeOfEnderEntityBuilder.thisList) { 34 | if (builder.get() == type) return (T) builder; 35 | } 36 | for (BoatEntityBuilder builder : BoatEntityBuilder.thisList) { 37 | if (builder.get() == type) return (T) builder; 38 | } 39 | for (BaseEntityBuilder builder : BaseEntityBuilder.thisList) { 40 | if (builder.get() == type) return (T) builder; 41 | } 42 | for (BaseLivingEntityBuilder builder : BaseLivingEntityBuilder.thisList) { 43 | if (builder.get() == type) return (T) builder; 44 | } 45 | return null; 46 | } 47 | 48 | @Info("Creates a custom Jump Control builder and returns it.") 49 | static JumpControlJS createJumpControl(Mob pMob, Consumer consumer) { 50 | var builder = new JumpControlJSBuilder(); 51 | EntityJSHelperClass.consumerCallback(consumer, builder, "[EntityJS]: Error in " + pMob.getType() + "builder for field: createJumpControl."); 52 | return new JumpControlJS(pMob, builder); 53 | } 54 | 55 | @Info("Creates a custom Move Control builder and returns it.") 56 | static MoveControlJS createMoveControl(Mob pMob, Consumer consumer) { 57 | var builder = new MoveControlJSBuilder(); 58 | EntityJSHelperClass.consumerCallback(consumer, builder, "[EntityJS]: Error in " + pMob.getType() + "builder for field: createMoveControl."); 59 | return new MoveControlJS(pMob, builder); 60 | } 61 | 62 | @Info("Creates a custom Look Control builder and returns it.") 63 | static LookControlJS createLookControl(Mob pMob, Consumer consumer) { 64 | var builder = new LookControlJSBuilder(); 65 | EntityJSHelperClass.consumerCallback(consumer, builder, "[EntityJS]: Error in " + pMob.getType() + "builder for field: createLookControl."); 66 | return new LookControlJS(pMob, builder); 67 | } 68 | 69 | @Info("Ground entity path navigation") 70 | static GroundPathNavigation createGroundPathNavigation(Mob pMob, Level pLevel) { 71 | return new GroundPathNavigation(pMob, pLevel); 72 | } 73 | 74 | @Info("Flying entity path navigation") 75 | static FlyingPathNavigation createFlyingPathNavigation(Mob pMob, Level pLevel) { 76 | return new FlyingPathNavigation(pMob, pLevel); 77 | } 78 | 79 | @Info("Amphibious entity path navigation") 80 | static AmphibiousPathNavigation createAmphibiousPathNavigation(Mob pMob, Level pLevel) { 81 | return new AmphibiousPathNavigation(pMob, pLevel); 82 | } 83 | 84 | @Info("Wall climbing entity path navigation") 85 | static WallClimberNavigation createWallClimberNavigation(Mob pMob, Level pLevel) { 86 | return new WallClimberNavigation(pMob, pLevel); 87 | } 88 | 89 | @Info("Water bound entity path navigation") 90 | static WaterBoundPathNavigation createWaterBoundPathNavigation(Mob pMob, Level pLevel) { 91 | return new WaterBoundPathNavigation(pMob, pLevel); 92 | } 93 | } -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/util/EventHandlers.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.util; 2 | 3 | import dev.latvian.mods.kubejs.event.EventGroup; 4 | import dev.latvian.mods.kubejs.event.EventHandler; 5 | import dev.latvian.mods.kubejs.event.Extra; 6 | import dev.latvian.mods.kubejs.script.data.VirtualKubeJSDataPack; 7 | import dev.latvian.mods.kubejs.util.UtilsJS; 8 | import net.liopyu.entityjs.builders.living.BaseLivingEntityBuilder; 9 | import net.liopyu.entityjs.events.*; 10 | import net.minecraft.server.packs.resources.MultiPackResourceManager; 11 | import net.minecraftforge.event.entity.EntityAttributeCreationEvent; 12 | import net.minecraftforge.event.entity.EntityAttributeModificationEvent; 13 | import net.minecraftforge.event.entity.SpawnPlacementRegisterEvent; 14 | import net.minecraftforge.eventbus.api.EventPriority; 15 | import net.minecraftforge.eventbus.api.IEventBus; 16 | import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; 17 | 18 | public class EventHandlers { 19 | 20 | public static final EventGroup EntityJSEvents = EventGroup.of("EntityJSEvents"); 21 | 22 | public static final EventHandler addGoalTargets = EntityJSEvents.server("addGoals", () -> AddGoalTargetsEventJS.class).extra(Extra.REQUIRES_ID); // Possibly a modify goals event for editing other entities 23 | public static final EventHandler addGoalSelectors = EntityJSEvents.server("addGoalSelectors", () -> AddGoalSelectorsEventJS.class).extra(Extra.REQUIRES_ID); 24 | public static final EventHandler buildBrain = EntityJSEvents.server("buildBrain", () -> BuildBrainEventJS.class).extra(Extra.REQUIRES_ID); 25 | public static final EventHandler buildBrainProvider = EntityJSEvents.server("buildBrainProvider", () -> BuildBrainProviderEventJS.class).extra(Extra.REQUIRES_ID); 26 | public static final EventHandler biomeSpawns = EntityJSEvents.server("biomeSpawns", () -> BiomeSpawnsEventJS.class); 27 | 28 | public static final EventHandler editAttributes = EntityJSEvents.startup("attributes", () -> ModifyAttributeEventJS.class); 29 | public static final EventHandler spawnPlacement = EntityJSEvents.startup("spawnPlacement", () -> RegisterSpawnPlacementsEventJS.class); 30 | public static final EventHandler modifyEntity = EntityJSEvents.startup("modifyEntity", () -> EntityModificationEventJS.class); 31 | 32 | public static void init() { 33 | 34 | final IEventBus modBus = FMLJavaModLoadingContext.get().getModEventBus(); 35 | modBus.addListener(EventHandlers::attributeCreation); 36 | modBus.addListener(EventHandlers::attributeModification); 37 | modBus.addListener(EventPriority.LOW, EventHandlers::registerSpawnPlacements); // Low to allow REPLACE to work and addons to effect the result 38 | 39 | } 40 | 41 | private static void attributeCreation(EntityAttributeCreationEvent event) { 42 | for (BaseLivingEntityBuilder builder : BaseLivingEntityBuilder.thisList) { 43 | event.put(builder.get(), builder.getAttributeBuilder().build()); 44 | } 45 | } 46 | 47 | private static void registerSpawnPlacements(SpawnPlacementRegisterEvent event) { 48 | for (BaseLivingEntityBuilder builder : BaseLivingEntityBuilder.spawnList) { 49 | event.register(UtilsJS.cast(builder.get()), builder.placementType, builder.heightMap, builder.spawnPredicate, SpawnPlacementRegisterEvent.Operation.REPLACE); // Cast because the '?' generics makes the event unhappy 50 | } 51 | if (spawnPlacement.hasListeners()) { 52 | spawnPlacement.post(new RegisterSpawnPlacementsEventJS(event)); 53 | } 54 | } 55 | 56 | private static void attributeModification(EntityAttributeModificationEvent event) { 57 | if (editAttributes.hasListeners()) { 58 | editAttributes.post(new ModifyAttributeEventJS(event)); 59 | } 60 | } 61 | 62 | public static void postDataEvent(VirtualKubeJSDataPack pack, MultiPackResourceManager multiManager) { 63 | if (pack != null && multiManager != null) { 64 | // Unused 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/util/ModKeybinds.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.util; 2 | 3 | import net.minecraft.client.KeyMapping; 4 | 5 | public class ModKeybinds { 6 | public static final KeyMapping mount_jump = new KeyMapping("key.mount_jump", 296, "key.categories.misc"); 7 | //public static final KeyMapping mount_inventory = new KeyMapping("key.mount_inventory", 296, "key.categories.misc"); 8 | //Call where needed with ModKeybinds.mount_jump.isDown() 9 | } -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/util/RegistryUtil.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.util; 2 | 3 | import com.mojang.serialization.Codec; 4 | import net.liopyu.entityjs.EntityJSMod; 5 | import net.liopyu.entityjs.util.implementation.EventBasedSpawnModifier; 6 | import net.minecraftforge.common.world.BiomeModifier; 7 | import net.minecraftforge.eventbus.api.IEventBus; 8 | import net.minecraftforge.registries.DeferredRegister; 9 | import net.minecraftforge.registries.ForgeRegistries; 10 | import net.minecraftforge.registries.RegistryObject; 11 | 12 | public class RegistryUtil { 13 | 14 | public static void init(IEventBus modBus) { 15 | BIOME_MODIFIERS.register(modBus); 16 | } 17 | 18 | private static final DeferredRegister> BIOME_MODIFIERS = DeferredRegister.create(ForgeRegistries.Keys.BIOME_MODIFIER_SERIALIZERS, EntityJSMod.MOD_ID); 19 | 20 | public static final RegistryObject> EVENT_SPAWN_MODIFIER = BIOME_MODIFIERS.register("event_based", () -> Codec.unit(EventBasedSpawnModifier::new)); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/util/ai/CustomGoal.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.util.ai; 2 | 3 | import net.minecraft.world.entity.Mob; 4 | import net.minecraft.world.entity.ai.goal.Goal; 5 | import org.jetbrains.annotations.Nullable; 6 | 7 | import java.util.function.Consumer; 8 | import java.util.function.Predicate; 9 | 10 | public class CustomGoal extends Goal { 11 | 12 | private final String name; 13 | private final T mob; 14 | private final Predicate canUse; 15 | @Nullable 16 | private final Predicate canContinueToUse; 17 | private final boolean isInterruptable; 18 | private final Consumer start; 19 | private final Consumer stop; 20 | private final boolean requiresUpdateEveryTick; 21 | private final Consumer tick; 22 | 23 | public CustomGoal( 24 | String name, 25 | T mob, 26 | Predicate canUse, 27 | @Nullable Predicate canContinueToUse, 28 | boolean isInterruptable, 29 | Consumer start, 30 | Consumer stop, 31 | boolean requiresUpdateEveryTick, 32 | Consumer tick 33 | ) { 34 | this.name = name; 35 | this.mob = mob; 36 | this.canUse = canUse; 37 | this.canContinueToUse = canContinueToUse; 38 | this.isInterruptable = isInterruptable; 39 | this.start = start; 40 | this.stop = stop; 41 | this.requiresUpdateEveryTick = requiresUpdateEveryTick; 42 | this.tick = tick; 43 | } 44 | @Override 45 | public boolean canUse() { 46 | return canUse.test(mob); 47 | } 48 | 49 | @Override 50 | public boolean canContinueToUse() { 51 | return canContinueToUse == null ? super.canContinueToUse() : canContinueToUse.test(mob); 52 | } 53 | 54 | @Override 55 | public boolean isInterruptable() { 56 | return isInterruptable; 57 | } 58 | 59 | @Override 60 | public void start() { 61 | start.accept(mob); 62 | } 63 | 64 | @Override 65 | public void stop() { 66 | stop.accept(mob); 67 | } 68 | 69 | @Override 70 | public boolean requiresUpdateEveryTick() { 71 | return requiresUpdateEveryTick; 72 | } 73 | 74 | @Override 75 | public void tick() { 76 | tick.accept(mob); 77 | } 78 | 79 | @Override 80 | public String toString() { 81 | return "CustomGoal[" + name + "]"; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/util/ai/JumpControlJS.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.util.ai; 2 | 3 | import net.liopyu.entityjs.builders.misc.JumpControlJSBuilder; 4 | import net.liopyu.entityjs.util.EntityJSHelperClass; 5 | import net.minecraft.world.entity.Mob; 6 | import net.minecraft.world.entity.ai.control.JumpControl; 7 | 8 | public class JumpControlJS extends JumpControl { 9 | 10 | private final JumpControlJSBuilder builder; 11 | 12 | private String entityName() { 13 | return mob.getType().toString(); 14 | } 15 | 16 | public JumpControlJS(Mob mob, JumpControlJSBuilder builder) { 17 | super(mob); 18 | this.builder = builder; 19 | } 20 | 21 | @Override 22 | public void jump() { 23 | if (builder.jump != null) { 24 | EntityJSHelperClass.consumerCallback(builder.jump, mob, "[EntityJS]: Error in " + entityName() + " Look Control builder for field: jump."); 25 | } else { 26 | super.jump(); 27 | } 28 | } 29 | 30 | @Override 31 | public void tick() { 32 | if (builder.tick != null) { 33 | EntityJSHelperClass.consumerCallback(builder.tick, mob, "[EntityJS]: Error in " + entityName() + " Jump Control builder for field: tick."); 34 | } else { 35 | super.tick(); 36 | } 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/util/implementation/IAnimationControllerJS.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.util.implementation; 2 | 3 | import dev.latvian.mods.rhino.util.RemapPrefixForJS; 4 | 5 | @RemapPrefixForJS("entityJs$") 6 | public interface IAnimationControllerJS { 7 | double entityJs$getCurrentAnimationTick(); 8 | } -------------------------------------------------------------------------------- /src/main/java/net/liopyu/entityjs/util/implementation/IEntityJS.java: -------------------------------------------------------------------------------- 1 | package net.liopyu.entityjs.util.implementation; 2 | 3 | 4 | import dev.latvian.mods.rhino.util.RemapPrefixForJS; 5 | 6 | @RemapPrefixForJS("entityJs$") 7 | public interface IEntityJS { 8 | boolean entityJs$isMoving(); 9 | } -------------------------------------------------------------------------------- /src/main/resources/META-INF/mods.toml: -------------------------------------------------------------------------------- 1 | # This is an example mods.toml file. It contains the data relating to the loading mods. 2 | # There are several mandatory fields (#mandatory), and many more that are optional (#optional). 3 | # The overall format is standard TOML format, v0.5.0. 4 | # Note that there are a couple of TOML lists in this file. 5 | # Find more information on toml format here: https://github.com/toml-lang/toml 6 | # The name of the mod loader type to load - for regular FML @Mod mods it should be javafml 7 | modLoader = "javafml" #mandatory 8 | # A version range to match for said mod loader - for regular FML @Mod it will be the forge version 9 | loaderVersion = "${loader_version_range}" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions. 10 | # The license for you mod. This is mandatory metadata and allows for easier comprehension of your redistributive properties. 11 | # Review your options at https://choosealicense.com/. All rights reserved is the default copyright stance, and is thus the default here. 12 | license = "${mod_license}" 13 | # A URL to refer people to when problems occur with this mod 14 | issueTrackerURL = "https://github.com/liopyu/EntityJS/issues" 15 | [[mods]] #mandatory 16 | # The modid of the mod 17 | modId = "entityjs" #mandatory 18 | # The version number of the mod 19 | version = "${mod_version}" #mandatory 20 | # A display name for the mod 21 | displayName = "${mod_name}" #mandatory 22 | # A URL to query for updates for this mod. See the JSON update specification https://docs.minecraftforge.net/en/latest/misc/updatechecker/ 23 | #updateJSONURL="https://change.me.example.invalid/updates.json" #optional 24 | # A URL for the "homepage" for this mod, displayed in the mod UI 25 | #displayURL="https://change.me.to.your.mods.homepage.example.invalid/" #optional 26 | # A file name (in the root of the mod JAR) containing a logo for display 27 | #logoFile="examplemod.png" #optional 28 | # A text field displayed in the mod UI 29 | #credits="" #optional 30 | # A text field displayed in the mod UI 31 | authors = "${mod_authors}" #optional 32 | # Display Test controls the display for your mod in the server connection screen 33 | # MATCH_VERSION means that your mod will cause a red X if the versions on client and server differ. This is the default behaviour and should be what you choose if you have server and client elements to your mod. 34 | # IGNORE_SERVER_VERSION means that your mod will not cause a red X if it's present on the server but not on the client. This is what you should use if you're a server only mod. 35 | # IGNORE_ALL_VERSION means that your mod will not cause a red X if it's present on the client or the server. This is a special case and should only be used if your mod has no server component. 36 | # NONE means that no display test is set on your mod. You need to do this yourself, see IExtensionPoint.DisplayTest for more information. You can define any scheme you wish with this value. 37 | # IMPORTANT NOTE: this is NOT an instruction as to which environments (CLIENT or DEDICATED SERVER) your mod loads on. Your mod should load (and maybe do nothing!) whereever it finds itself. 38 | #displayTest="MATCH_VERSION" # MATCH_VERSION is the default if nothing is specified (#optional) 39 | 40 | # The description text for the mod (multi line!) (#mandatory) 41 | description = '''${mod_description}''' 42 | # A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional. 43 | [[dependencies.entityjs]] #optional 44 | # the modid of the dependency 45 | modId = "forge" #mandatory 46 | # Does this dependency have to exist - if not, ordering below must be specified 47 | mandatory = true #mandatory 48 | # The version range of the dependency 49 | versionRange = "${forge_version_range}" #mandatory 50 | # An ordering relationship for the dependency - BEFORE or AFTER required if the dependency is not mandatory 51 | # BEFORE - This mod is loaded BEFORE the dependency 52 | # AFTER - This mod is loaded AFTER the dependency 53 | ordering = "NONE" 54 | # Side this dependency is applied on - BOTH, CLIENT, or SERVER 55 | side = "BOTH" 56 | # Here's another dependency 57 | [[dependencies.entityjs]] 58 | modId = "minecraft" 59 | mandatory = true 60 | # This version range declares a minimum of the current minecraft version up to but not including the next major version 61 | versionRange = "${minecraft_version_range}" 62 | ordering = "NONE" 63 | side = "BOTH" 64 | 65 | [[dependencies.entityjs]] 66 | modId = "kubejs" 67 | mandatory = true 68 | versionRange = "[1902.6.0-build.130,)" 69 | ordering = "NONE" 70 | side = "BOTH" 71 | 72 | [[dependencies.entityjs]] 73 | modId = "liolib" 74 | mandatory = true 75 | versionRange = "[1.19-0.0.1,)" 76 | ordering = "NONE" 77 | side = "BOTH" 78 | -------------------------------------------------------------------------------- /src/main/resources/assets/entityjs/lang/en_us.json: -------------------------------------------------------------------------------- 1 | { 2 | "key.mount_jump": "Jump key for EntityJS mobs" 3 | } -------------------------------------------------------------------------------- /src/main/resources/assets/kubejs/textures/entity/projectiles/arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liopyu/EntityJS/e8e0d1b94daf96e7a2c78b26396f229f31254081/src/main/resources/assets/kubejs/textures/entity/projectiles/arrow.png -------------------------------------------------------------------------------- /src/main/resources/assets/kubejs/textures/entity/projectiles/projectile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liopyu/EntityJS/e8e0d1b94daf96e7a2c78b26396f229f31254081/src/main/resources/assets/kubejs/textures/entity/projectiles/projectile.png -------------------------------------------------------------------------------- /src/main/resources/assets/kubejs/textures/entity/sasuke.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liopyu/EntityJS/e8e0d1b94daf96e7a2c78b26396f229f31254081/src/main/resources/assets/kubejs/textures/entity/sasuke.png -------------------------------------------------------------------------------- /src/main/resources/assets/kubejs/textures/entity/wyrm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liopyu/EntityJS/e8e0d1b94daf96e7a2c78b26396f229f31254081/src/main/resources/assets/kubejs/textures/entity/wyrm.png -------------------------------------------------------------------------------- /src/main/resources/assets/kubejs/textures/item/arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liopyu/EntityJS/e8e0d1b94daf96e7a2c78b26396f229f31254081/src/main/resources/assets/kubejs/textures/item/arrow.png -------------------------------------------------------------------------------- /src/main/resources/assets/kubejs/textures/item/projectile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liopyu/EntityJS/e8e0d1b94daf96e7a2c78b26396f229f31254081/src/main/resources/assets/kubejs/textures/item/projectile.png -------------------------------------------------------------------------------- /src/main/resources/assets/kubejs/textures/models/entity/projectile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liopyu/EntityJS/e8e0d1b94daf96e7a2c78b26396f229f31254081/src/main/resources/assets/kubejs/textures/models/entity/projectile.png -------------------------------------------------------------------------------- /src/main/resources/data/entityjs/forge/biome_modifier/event_based.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "entityjs:event_based" 3 | } -------------------------------------------------------------------------------- /src/main/resources/entityjs.mixins.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": false, 3 | "minVersion": "0.8", 4 | "package": "net.liopyu.entityjs.mixin", 5 | "compatibilityLevel": "JAVA_17", 6 | "mixins": [ 7 | "AnimationControllerMixin", 8 | "EntityMixin", 9 | "KubeJSCommandsMixin", 10 | "LivingEntityMixin", 11 | "MobMixin", 12 | "PathfinderMobMixin", 13 | "ProjectileMixin", 14 | "ServerScriptManagerMixin" 15 | ], 16 | "client": [ 17 | "EntityRendererMixin", 18 | "LivingEntityRendererMixin" 19 | ], 20 | "refmap": "entityjs.refmap.json" 21 | } -------------------------------------------------------------------------------- /src/main/resources/kubejs.plugins.txt: -------------------------------------------------------------------------------- 1 | net.liopyu.entityjs.EntityJSPlugin -------------------------------------------------------------------------------- /src/main/resources/pack.mcmeta: -------------------------------------------------------------------------------- 1 | { 2 | "pack": { 3 | "description": "${mod_id} resources", 4 | "pack_format": 9, 5 | "forge:resource_pack_format": 9, 6 | "forge:data_pack_format": 10 7 | } 8 | } 9 | --------------------------------------------------------------------------------