From 019b4787bd115e15a35bc4d9eaf7bb645fbf7a17 Mon Sep 17 00:00:00 2001 From: Jack Papel Date: Fri, 19 Aug 2022 01:37:03 -0400 Subject: [PATCH 1/8] Fix build --- build.gradle.kts | 20 +++++++++---------- gradle.properties | 20 +++++++++---------- .../id/aether/entities/AetherEntityTypes.java | 3 +-- .../entities/block/FloatingBlockEntity.java | 2 +- .../java/net/id/aether/items/AetherItems.java | 4 ++-- .../client/render/CloudRendererMixin.java | 8 ++++---- .../world/dimension/AetherDimension.java | 2 +- 7 files changed, 29 insertions(+), 30 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index a4f341d11..cffea479c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -68,11 +68,6 @@ repositories { url = uri("https://maven.jamieswhiteshirt.com/libs-release/") } - maven { - name = "Gudenau" - url = uri("https://maven.gudenau.net") - } - maven { name = "Modrinth" url = uri("https://api.modrinth.com/maven") @@ -82,6 +77,11 @@ repositories { name = "Jitpack" url = uri("https://jitpack.io") } + + maven { + name = "Gudenau" + url = uri("https://maven.gudenau.net") + } } dependencies { @@ -176,11 +176,11 @@ dependencies { version = modmenuVersion, ) - modRuntimeOnly( - group = "me.shedaniel", - name = "RoughlyEnoughItems-fabric", - version = reiVersion, - ) +// modRuntimeOnly( +// group = "me.shedaniel", +// name = "RoughlyEnoughItems-fabric", +// version = reiVersion, +// ) include( group = "maven.modrinth", diff --git a/gradle.properties b/gradle.properties index 4df1dba03..fc5943e81 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,20 +3,20 @@ org.gradle.jvmargs=-Xmx2G paradiseLostVersion=0.2.0-beta+1.19 -minecraftVersion=1.19 -yarnVersion=1.19+build.1 -loaderVersion=0.14.6 +minecraftVersion=1.19.2 +yarnVersion=1.19.2+build.4 +loaderVersion=0.14.9 javaVersion=17 -fabricApiVersion=0.55.1+1.19 -incubusCoreVersion=1.19-SNAPSHOT -customportalapiVersion=0.0.1-beta51-1.19 -cardinalComponentsVersion=5.0.0-beta.1 +fabricApiVersion=0.60.0+1.19.2 +incubusCoreVersion=1.7.0 +customportalapiVersion=0.0.1-beta54-1.19 +cardinalComponentsVersion=5.0.1 trinketsVersion=3.4.0 -crowdinTranslateVersion=1.18.2 +crowdinTranslateVersion=1.19.2 entityAttributesVersion=2.3.0 -modmenuVersion=4.0.0 -reiVersion=9.0.484 +modmenuVersion=4.0.6 +reiVersion=9.1.530 moreTagsVersion=3.0.5 recipeConfidenceVersion=1.0.2 satinVersion=1.8.0 diff --git a/src/main/java/net/id/aether/entities/AetherEntityTypes.java b/src/main/java/net/id/aether/entities/AetherEntityTypes.java index f0c423aca..f4b121a2a 100644 --- a/src/main/java/net/id/aether/entities/AetherEntityTypes.java +++ b/src/main/java/net/id/aether/entities/AetherEntityTypes.java @@ -2,7 +2,6 @@ import net.fabricmc.fabric.api.object.builder.v1.entity.FabricDefaultAttributeRegistry; import net.fabricmc.fabric.api.object.builder.v1.entity.FabricEntityTypeBuilder; -import net.fabricmc.fabric.mixin.object.builder.SpawnRestrictionAccessor; import net.id.aether.entities.block.FloatingBlockEntity; import net.id.aether.entities.block.SliderEntity; import net.id.aether.entities.hostile.AechorPlantEntity; @@ -79,7 +78,7 @@ private static Action> attributes(Sup } private static Action> spawnRestrictions(SpawnRestriction.Location location, Heightmap.Type heightmapType, SpawnRestriction.SpawnPredicate predicate) { - return (id, entityType) -> SpawnRestrictionAccessor.callRegister(entityType, location, heightmapType, predicate); + return (id, entityType) -> SpawnRestriction.register(entityType, location, heightmapType, predicate); } private static Action> spawnRestrictions(SpawnRestriction.Location location, SpawnRestriction.SpawnPredicate predicate) { diff --git a/src/main/java/net/id/aether/entities/block/FloatingBlockEntity.java b/src/main/java/net/id/aether/entities/block/FloatingBlockEntity.java index 8e64d9fbe..3e1b0b63a 100644 --- a/src/main/java/net/id/aether/entities/block/FloatingBlockEntity.java +++ b/src/main/java/net/id/aether/entities/block/FloatingBlockEntity.java @@ -44,7 +44,7 @@ public void postTickMoveEntities() { List otherEntities = this.world.getOtherEntities(this, getBoundingBox().union(getBoundingBox().offset(0, 3 * (this.prevY - this.getY()), 0))); for (Entity entity : otherEntities) { - if (!(entity instanceof BlockLikeEntity) && !entity.noClip && this.collides()) { + if (!(entity instanceof BlockLikeEntity) && !entity.noClip && this.collides) { entity.move(MovementType.SHULKER_BOX, this.getVelocity()); entity.setOnGround(true); diff --git a/src/main/java/net/id/aether/items/AetherItems.java b/src/main/java/net/id/aether/items/AetherItems.java index c9354e508..7b82a87d5 100644 --- a/src/main/java/net/id/aether/items/AetherItems.java +++ b/src/main/java/net/id/aether/items/AetherItems.java @@ -652,8 +652,8 @@ protected AetherHoeItem(ToolMaterial material, int attackDamage, float attackSpe } private static class AetherMusicDiscItem extends MusicDiscItem { - protected AetherMusicDiscItem(int comparatorValueIn, SoundEvent soundIn, Settings settings) { - super(comparatorValueIn, soundIn, settings); + protected AetherMusicDiscItem(int comparatorValueIn, SoundEvent soundIn, Settings settings, int length) { + super(comparatorValueIn, soundIn, settings, length); } } } diff --git a/src/main/java/net/id/aether/mixin/client/render/CloudRendererMixin.java b/src/main/java/net/id/aether/mixin/client/render/CloudRendererMixin.java index 853fa4d92..0844f8caa 100644 --- a/src/main/java/net/id/aether/mixin/client/render/CloudRendererMixin.java +++ b/src/main/java/net/id/aether/mixin/client/render/CloudRendererMixin.java @@ -32,7 +32,7 @@ public final class CloudRendererMixin { @Shadow private int lastCloudsBlockY; @Shadow private int lastCloudsBlockZ; @Shadow @NotNull private Vec3d lastCloudsColor; - @Shadow @NotNull private CloudRenderMode lastCloudsRenderMode; + @Shadow @NotNull private CloudRenderMode lastCloudRenderMode; @Shadow private boolean cloudsDirty; @Shadow @Nullable private VertexBuffer cloudsBuffer; @@ -74,12 +74,12 @@ private void internalCloudRender(MatrixStack matrices, Matrix4f projectionMatrix int floorX = (int) Math.floor(posX); int floorY = (int) Math.floor(posY / 4.0D); int floorZ = (int) Math.floor(posZ); - if (floorX != this.lastCloudsBlockX || floorY != this.lastCloudsBlockY || floorZ != this.lastCloudsBlockZ || this.client.options.getCloudRenderMode() != this.lastCloudsRenderMode || this.lastCloudsColor.squaredDistanceTo(cloudColor) > 2.0E-4D) { + if (floorX != this.lastCloudsBlockX || floorY != this.lastCloudsBlockY || floorZ != this.lastCloudsBlockZ || this.client.options.getCloudRenderMode().getValue() != this.lastCloudRenderMode || this.lastCloudsColor.squaredDistanceTo(cloudColor) > 2.0E-4D) { this.lastCloudsBlockX = floorX; this.lastCloudsBlockY = floorY; this.lastCloudsBlockZ = floorZ; this.lastCloudsColor = cloudColor; - this.lastCloudsRenderMode = this.client.options.getCloudRenderMode(); + this.lastCloudRenderMode = this.client.options.getCloudRenderMode().getValue(); this.cloudsDirty = true; } @@ -109,7 +109,7 @@ private void internalCloudRender(MatrixStack matrices, Matrix4f projectionMatrix cloudsBuffer.bind(); //TODO Double check bytecode, this feels really weird. If this is correct, pure Mojank. - int passes = lastCloudsRenderMode == CloudRenderMode.FANCY ? 0 : 1; + int passes = lastCloudRenderMode == CloudRenderMode.FANCY ? 0 : 1; for (int pass = passes; pass < 2; pass++) { if (pass == 0) { RenderSystem.colorMask(false, false, false, false); diff --git a/src/main/java/net/id/aether/world/dimension/AetherDimension.java b/src/main/java/net/id/aether/world/dimension/AetherDimension.java index cafdb8170..47b19d2c4 100755 --- a/src/main/java/net/id/aether/world/dimension/AetherDimension.java +++ b/src/main/java/net/id/aether/world/dimension/AetherDimension.java @@ -8,7 +8,7 @@ import net.id.aether.util.AetherSoundEvents; import net.id.aether.util.MiscUtil; import net.kyrptonaught.customportalapi.api.CustomPortalBuilder; -import net.kyrptonaught.customportalapi.util.CPASoundEventData; +import net.kyrptonaught.customportalapi.event.CPASoundEventData; import net.minecraft.block.Blocks; import net.minecraft.util.dynamic.RegistryOps; import net.minecraft.util.registry.*; From 36b248592c7e391b152d36c79b0f8896906025a3 Mon Sep 17 00:00:00 2001 From: Jack Papel <64770632+Jack-Papel@users.noreply.github.com> Date: Thu, 25 Aug 2022 14:20:20 -0400 Subject: [PATCH 2/8] Fix license information --- README.md | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 3b620b9b8..320f684cd 100644 --- a/README.md +++ b/README.md @@ -41,25 +41,9 @@ Paradise Lost makes use of crowd sourced translations. ## License information Created by Immortal Devs.\ -Originally made by [Gilded Games](https://gildedgames.com/) under GNU GPLv3 license.\ -New assets are unlicensed and all rights are reserved to them by Immortal Devs. - -``` - Copyright (C) 2021 Immortal Devs - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -``` -You can find more about GNU GPLv3 on [this website](https://www.gnu.org/licenses/gpl-3.0.en.html). +Inspired by [Gilded Games' The Aether](https://github.com/Gilded-Games/The-Aether), which uses the GNU GPLv3 license.\ +Assets are all rights are reserved by Immortal Devs. + +You can find out more information about the license [here](https://github.com/devs-immortal/Paradise-Lost/LICENSE.md). Fabric API - Mods - Minecraft - CurseForge  Trinkets (Fabric) - Mods - Minecraft - CurseForge From 0afdd0415e4ed454ac0e62734aba43a913d7ff74 Mon Sep 17 00:00:00 2001 From: Jack Papel <64770632+Jack-Papel@users.noreply.github.com> Date: Thu, 25 Aug 2022 14:30:32 -0400 Subject: [PATCH 3/8] Fix broken links --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 320f684cd..e5170f337 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Paradise Lost -[![Code license (GNU GPL 3.0)](https://img.shields.io/badge/code%20license-GNU%20GPLv3-green.svg?style=flat)](https://www.gnu.org/licenses/gpl-3.0.en.html) +[![Code license (GNU GPL 3.0)](https://img.shields.io/github/license/devs-immortal/Paradise-Lost)](https://github.com/devs-immortal/Paradise-Lost/blob/0.2.0/1.19/master/LICENSE.md) [![Asset license (Unlicensed)](https://img.shields.io/badge/assets%20license-All%20Rights%20Reserved-red.svg?style=flat)](https://creativecommons.org/licenses/by-sa/4.0/) [![Github all releases](https://img.shields.io/github/downloads/kalucky0/The-Aether/total.svg?logoColor=FFFFFF&logo=github)](https://github.com/devs-immortal/The-Aether/releases/) @@ -14,9 +14,9 @@ The Aether is a dimension high in the sky composed of floating islands. Ascend through a Glowstone portal and begin a new survival adventure packed with new ores, structures to explore, mythical creatures, and perilous dungeons. Build a Glowstone frame and add water to light the mystical portal, step in and be transported to the beautiful but hostile paradise known as the Aether. This tranquil oasis is the polar opposite of the Nether, filled with lush trees and foliage, and populated by unique and exotic mobs, both hostile and friendly. The Aether is deceptively charming, and the further you explore, the darker its secrets get. Mine new ores, craft new gear, explore hidden temples and dungeons, and battle to claim The Aether as your own. -You can download the mod on [Modrinth](https://modrinth.com/mod/aether), [CurseForge](https://www.curseforge.com/minecraft/mc-mods/paradise-lost), or in the [releases tab](https://github.com/devs-immortal/Paradise-Lost/releases) on Github. +You can download the mod on [Modrinth](https://modrinth.com/mod/paradise-lost), [CurseForge](https://www.curseforge.com/minecraft/mc-mods/paradise-lost), or in the [releases tab](https://github.com/devs-immortal/Paradise-Lost/releases) on Github. -**Original repo:** [GildedGames/The-Aether](https://gitea.gildedgames.com/GildedGames/The-Aether) +**Original repo:** [GildedGames/The-Aether](https://github.com/Gilded-Games/The-Aether) ## Support [![Discord](https://img.shields.io/discord/770691727568404521.svg?logoColor=FFFFFF&logo=discord&color=7289DA)](https://discord.com/invite/wmMa47n) @@ -44,6 +44,6 @@ Created by Immortal Devs.\ Inspired by [Gilded Games' The Aether](https://github.com/Gilded-Games/The-Aether), which uses the GNU GPLv3 license.\ Assets are all rights are reserved by Immortal Devs. -You can find out more information about the license [here](https://github.com/devs-immortal/Paradise-Lost/LICENSE.md). +You can find out more information about the license [here](https://github.com/devs-immortal/Paradise-Lost/blob/0.2.0/1.19/master/LICENSE.md). -Fabric API - Mods - Minecraft - CurseForge  Trinkets (Fabric) - Mods - Minecraft - CurseForge +Fabric API - Mods - Minecraft - CurseForge  Trinkets (Fabric) - Mods - Minecraft - CurseForge From 1cc1e8164d5ba4ba42174db875979947c185963c Mon Sep 17 00:00:00 2001 From: Jack Papel <64770632+Jack-Papel@users.noreply.github.com> Date: Thu, 25 Aug 2022 14:47:49 -0400 Subject: [PATCH 4/8] Update contribution guidelines --- CONTRIBUTING.md | 50 +++++++++---------------------------------------- 1 file changed, 9 insertions(+), 41 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3cc64a498..5ff32bf15 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -20,56 +20,24 @@ * Open a new GitHub pull request with the patch. -* Ensure the PR description clearly describes the problem and solution. Use the PR template. Include the relevant issue number if applicable. +* Ensure the PR description clearly describes the problem (or a link to the relevant issue, if applicable) and solution. Use the PR template. + +* Before submitting, please check that your code matches our code style. The repo contains a checkstyle, which you should try to follow. -* Before submitting, please check that your code matches our code style (Example): -```java - /** - * This code is actually gibberish. It's a mishmash of things intended to show our code style. - *
~ Jack - */ - @Inject( - method = "tickEntities", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/world/ClientWorld;tickBlockEntities()V" - ), - cancellable = true - ) - private void postEntityTick(CallbackInfo ci) { - for (Entity entity : entityList) { - if (entity instanceof PostTickEntity postTickEntity) { - postTickEntity.postTick(); - ci.cancel(); - } - } - BlockLikeSet.getAllStructures().forEachRemaining(BlockLikeSet::postTick); - } - // Oh, and use spaces, not tabs. -``` #### **Do you have write access to the repo and want to make a change?** * **MAKE A PULL REQUEST FOR NEW FEATURES**. -* Refer to CDA's details on contribution and branch names: +* Refer to these details on contribution and branch names: ``` -****: Assume these are production/live branches unless otherwise written or stated. +**//master**: Assume these are production/live branches unless otherwise written or stated. - Only push code here that is tested and expected to ship in the next applicable update -**experimental/**: Experimental Snapshot branches (Separate category due to mojang typically using different baseline versions) - - Only port changes are allowed to be pushed here, as this branch is typically rebased off the latest stable/matching **** baseline. -**snapshots**: Primary snapshot branch, typically the next short-term minecraft update - - Same regulations as **experimental/**, only port changes should be in this branch. - -**feature//**: Feature branches designated for the specified upcoming release - - These branches get merged into **next** when applicable, ready, and tested enough to be accepted into **next** - -**next**: Branch designated for the next major revision to project, typically baselined off the latest game version (Or pre-release if applicable) - - Segment into **next/** if multiple releases are in active development - - In the case of the baseline being a snapshot/pre-releases, **Do not push port changes here -- they will eventually be baselined into next via rebase or merging the baseline into next** + +**//**: Feature branches designated for the specified upcoming release + - These branches get merged into **//master** when applicable, ready, and tested enough to be accepted. ``` #### **Did you fix whitespace, format code, or make a purely cosmetic patch?** * Changes that are cosmetic in nature and do not add anything substantial to the project will likely not be accepted. - * Documentation changes may be accepted if the changes are not just grammar fixes. #### **Do you intend to add a new feature or change an existing one?** @@ -87,7 +55,7 @@ /** * Write reasonable documentation for non-obvious methods. * For public facing APIs, like {@link net.id.aether.api.MoaAPI} or {@link net.id.aether.api.FloatingBlockHelper}, - * fully document everything that is public. ^ (Also, use these @link tags when possible) + * fully document everything that is public. ^ (Also, use these @link tags to other things public) *
Use @param and @return tags if non-obvious or if specific values may give strange results. *
If you didn't write the code and you're just adding docs, end your docs with a tilde and your * name/username. If you did write it, then just the @author tag is alright. From fa2fa89ea9d13c4ccf100c6916601e8072d9aa2c Mon Sep 17 00:00:00 2001 From: Jack Papel <64770632+Jack-Papel@users.noreply.github.com> Date: Thu, 25 Aug 2022 14:54:51 -0400 Subject: [PATCH 5/8] Delete eclipse specific files (1) --- The-Aether_client.launch | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 The-Aether_client.launch diff --git a/The-Aether_client.launch b/The-Aether_client.launch deleted file mode 100644 index 12dc39872..000000000 --- a/The-Aether_client.launch +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - From 3ad7746ba476cd1daecb1bcd9b799822208f4241 Mon Sep 17 00:00:00 2001 From: Jack Papel <64770632+Jack-Papel@users.noreply.github.com> Date: Thu, 25 Aug 2022 14:55:03 -0400 Subject: [PATCH 6/8] Delete eclipse specific files (2) --- The-Aether_server.launch | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 The-Aether_server.launch diff --git a/The-Aether_server.launch b/The-Aether_server.launch deleted file mode 100644 index 472595fec..000000000 --- a/The-Aether_server.launch +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - From fdffc1e76b21e3f8e683c374997070c8929df831 Mon Sep 17 00:00:00 2001 From: kalucky0 Date: Thu, 8 Sep 2022 08:24:33 +0200 Subject: [PATCH 7/8] Merge branch 'feature/b1.7/ambysts' into 0.2.0/1.19/master --- .../client/model/AetherModelLayers.java | 1 + .../client/model/entity/AmbystModel.java | 273 ++++++++++++++++++ .../entity/AetherEntityRenderers.java | 3 +- .../entity/passive/AmbystRenderer.java | 23 ++ .../id/aether/entities/AetherEntityTypes.java | 37 ++- .../entities/passive/ambyst/AmbystBrain.java | 58 ++++ .../entities/passive/ambyst/AmbystEntity.java | 115 ++++++++ .../passive/ambyst/FindLogSensor.java | 84 ++++++ .../entities/passive/ambyst/RunToLogTask.java | 82 ++++++ .../passive/ambyst/StayInLogTask.java | 50 ++++ .../aether/mixin/brain/ActivityInvoker.java | 14 + .../mixin/brain/MemoryModuleTypeInvoker.java | 22 ++ .../aether/mixin/brain/SensorTypeInvoker.java | 17 ++ src/main/resources/paradise_lost.mixins.json | 5 +- 14 files changed, 781 insertions(+), 3 deletions(-) create mode 100644 src/main/java/net/id/aether/client/model/entity/AmbystModel.java create mode 100644 src/main/java/net/id/aether/client/rendering/entity/passive/AmbystRenderer.java create mode 100644 src/main/java/net/id/aether/entities/passive/ambyst/AmbystBrain.java create mode 100644 src/main/java/net/id/aether/entities/passive/ambyst/AmbystEntity.java create mode 100644 src/main/java/net/id/aether/entities/passive/ambyst/FindLogSensor.java create mode 100644 src/main/java/net/id/aether/entities/passive/ambyst/RunToLogTask.java create mode 100644 src/main/java/net/id/aether/entities/passive/ambyst/StayInLogTask.java create mode 100644 src/main/java/net/id/aether/mixin/brain/ActivityInvoker.java create mode 100644 src/main/java/net/id/aether/mixin/brain/MemoryModuleTypeInvoker.java create mode 100644 src/main/java/net/id/aether/mixin/brain/SensorTypeInvoker.java diff --git a/src/main/java/net/id/aether/client/model/AetherModelLayers.java b/src/main/java/net/id/aether/client/model/AetherModelLayers.java index 79f3c1045..00ec8f4be 100644 --- a/src/main/java/net/id/aether/client/model/AetherModelLayers.java +++ b/src/main/java/net/id/aether/client/model/AetherModelLayers.java @@ -26,6 +26,7 @@ public class AetherModelLayers { public static final EntityModelLayer MOA = register("moa", "main", MoaModel.getTexturedModelData()); public static final EntityModelLayer ROOK = register("rook", "main", RookModel.getTexturedModelData()); public static final EntityModelLayer ROOK_GLOW = register("rook_glow", "glow", RookModel.getTexturedModelData()); + public static final EntityModelLayer AMBYST = register("ambyst", "main", AmbystModel.getTexturedModelData()); public static final EntityModelLayer PHOENIX_ARMOR = register("phoenix_armor", "main", PhoenixArmorModel.getTexturedModelData()); public static final EntityModelLayer DUNGEON_SWITCH = register("dungeon_switch", "main", DungeonSwitchModel.getTexturedModelData()); diff --git a/src/main/java/net/id/aether/client/model/entity/AmbystModel.java b/src/main/java/net/id/aether/client/model/entity/AmbystModel.java new file mode 100644 index 000000000..89e550d58 --- /dev/null +++ b/src/main/java/net/id/aether/client/model/entity/AmbystModel.java @@ -0,0 +1,273 @@ +package net.id.aether.client.model.entity; + +import com.google.common.collect.ImmutableList; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.id.aether.entities.passive.ambyst.AmbystEntity; +import net.minecraft.client.model.*; +import net.minecraft.client.render.entity.model.AnimalModel; +import net.minecraft.client.render.entity.model.EntityModelPartNames; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3f; + +import java.util.Map; + +@Environment(EnvType.CLIENT) +public class AmbystModel extends AnimalModel { + + public static final float MOVING_IN_WATER_LEG_PITCH = 1.8849558F; + private final ModelPart tail; + private final ModelPart leftHindLeg; + private final ModelPart rightHindLeg; + private final ModelPart leftFrontLeg; + private final ModelPart rightFrontLeg; + private final ModelPart body; + private final ModelPart head; + private final ModelPart topGills; + private final ModelPart leftGills; + private final ModelPart rightGills; + + public AmbystModel(ModelPart root) { + super(true, 8.0F, 3.35F); + this.body = root.getChild(EntityModelPartNames.BODY); + this.head = this.body.getChild(EntityModelPartNames.HEAD); + this.rightHindLeg = this.body.getChild(EntityModelPartNames.RIGHT_HIND_LEG); + this.leftHindLeg = this.body.getChild(EntityModelPartNames.LEFT_HIND_LEG); + this.rightFrontLeg = this.body.getChild(EntityModelPartNames.RIGHT_FRONT_LEG); + this.leftFrontLeg = this.body.getChild(EntityModelPartNames.LEFT_FRONT_LEG); + this.tail = this.body.getChild(EntityModelPartNames.TAIL); + this.topGills = this.head.getChild(EntityModelPartNames.TOP_GILLS); + this.leftGills = this.head.getChild(EntityModelPartNames.LEFT_GILLS); + this.rightGills = this.head.getChild(EntityModelPartNames.RIGHT_GILLS); + } + + public static TexturedModelData getTexturedModelData() { + ModelData modelData = new ModelData(); + ModelPartData modelPartData = modelData.getRoot(); + ModelPartData modelPartData2 = modelPartData.addChild(EntityModelPartNames.BODY, ModelPartBuilder.create().uv(0, 11).cuboid(-4.0F, -2.0F, -9.0F, 8.0F, 4.0F, 10.0F).uv(2, 17).cuboid(0.0F, -3.0F, -8.0F, 0.0F, 5.0F, 9.0F), ModelTransform.pivot(0.0F, 20.0F, 5.0F)); + Dilation dilation = new Dilation(0.001F); + ModelPartData modelPartData3 = modelPartData2.addChild(EntityModelPartNames.HEAD, ModelPartBuilder.create().uv(0, 1).cuboid(-4.0F, -3.0F, -5.0F, 8.0F, 5.0F, 5.0F, dilation), ModelTransform.pivot(0.0F, 0.0F, -9.0F)); + ModelPartBuilder modelPartBuilder = ModelPartBuilder.create().uv(3, 37).cuboid(-4.0F, -3.0F, 0.0F, 8.0F, 3.0F, 0.0F, dilation); + ModelPartBuilder modelPartBuilder2 = ModelPartBuilder.create().uv(0, 40).cuboid(-3.0F, -5.0F, 0.0F, 3.0F, 7.0F, 0.0F, dilation); + ModelPartBuilder modelPartBuilder3 = ModelPartBuilder.create().uv(11, 40).cuboid(0.0F, -5.0F, 0.0F, 3.0F, 7.0F, 0.0F, dilation); + modelPartData3.addChild(EntityModelPartNames.TOP_GILLS, modelPartBuilder, ModelTransform.pivot(0.0F, -3.0F, -1.0F)); + modelPartData3.addChild(EntityModelPartNames.LEFT_GILLS, modelPartBuilder2, ModelTransform.pivot(-4.0F, 0.0F, -1.0F)); + modelPartData3.addChild(EntityModelPartNames.RIGHT_GILLS, modelPartBuilder3, ModelTransform.pivot(4.0F, 0.0F, -1.0F)); + ModelPartBuilder modelPartBuilder4 = ModelPartBuilder.create().uv(2, 13).cuboid(-1.0F, 0.0F, 0.0F, 3.0F, 5.0F, 0.0F, dilation); + ModelPartBuilder modelPartBuilder5 = ModelPartBuilder.create().uv(2, 13).cuboid(-2.0F, 0.0F, 0.0F, 3.0F, 5.0F, 0.0F, dilation); + modelPartData2.addChild(EntityModelPartNames.RIGHT_HIND_LEG, modelPartBuilder5, ModelTransform.pivot(-3.5F, 1.0F, -1.0F)); + modelPartData2.addChild(EntityModelPartNames.LEFT_HIND_LEG, modelPartBuilder4, ModelTransform.pivot(3.5F, 1.0F, -1.0F)); + modelPartData2.addChild(EntityModelPartNames.RIGHT_FRONT_LEG, modelPartBuilder5, ModelTransform.pivot(-3.5F, 1.0F, -8.0F)); + modelPartData2.addChild(EntityModelPartNames.LEFT_FRONT_LEG, modelPartBuilder4, ModelTransform.pivot(3.5F, 1.0F, -8.0F)); + modelPartData2.addChild(EntityModelPartNames.TAIL, ModelPartBuilder.create().uv(2, 19).cuboid(0.0F, -3.0F, 0.0F, 0.0F, 5.0F, 12.0F), ModelTransform.pivot(0.0F, 0.0F, 1.0F)); + return TexturedModelData.of(modelData, 64, 64); + } + + protected Iterable getHeadParts() { + return ImmutableList.of(); + } + + protected Iterable getBodyParts() { + return ImmutableList.of(this.body); + } + + public void setAngles(AmbystEntity axolotlEntity, float f, float g, float h, float i, float j) { + this.resetAngles(axolotlEntity, i, j); + if (true == false/*axolotlEntity.isPlayingDead()*/) { + this.setPlayingDeadAngles(i); + this.updateAnglesCache(axolotlEntity); + } else { + boolean bl = axolotlEntity.getVelocity().horizontalLengthSquared() > 1.0E-7D || axolotlEntity.getPitch() != axolotlEntity.prevPitch || axolotlEntity.getYaw() != axolotlEntity.prevYaw || axolotlEntity.lastRenderX != axolotlEntity.getX() || axolotlEntity.lastRenderZ != axolotlEntity.getZ(); + if (axolotlEntity.isInsideWaterOrBubbleColumn()) { + if (bl) { + this.setMovingInWaterAngles(h, j); + } else { + this.setStandingInWaterAngles(h); + } + + this.updateAnglesCache(axolotlEntity); + } else { + if (axolotlEntity.isOnGround()) { + if (bl) { + this.setMovingOnGroundAngles(h, i); + } else { + this.setStandingOnGroundAngles(h, i); + } + } + + this.updateAnglesCache(axolotlEntity); + } + } + } + + private void updateAnglesCache(AmbystEntity ambyst) { + Map map = ambyst.getModelAngles(); + map.put("body", this.getAngles(this.body)); + map.put("head", this.getAngles(this.head)); + map.put("right_hind_leg", this.getAngles(this.rightHindLeg)); + map.put("left_hind_leg", this.getAngles(this.leftHindLeg)); + map.put("right_front_leg", this.getAngles(this.rightFrontLeg)); + map.put("left_front_leg", this.getAngles(this.leftFrontLeg)); + map.put("tail", this.getAngles(this.tail)); + map.put("top_gills", this.getAngles(this.topGills)); + map.put("left_gills", this.getAngles(this.leftGills)); + map.put("right_gills", this.getAngles(this.rightGills)); + } + + private Vec3f getAngles(ModelPart part) { + return new Vec3f(part.pitch, part.yaw, part.roll); + } + + private void setAngles(ModelPart part, Vec3f angles) { + part.setAngles(angles.getX(), angles.getY(), angles.getZ()); + } + + /** + * Resets the angles of the axolotl model. + */ + private void resetAngles(AmbystEntity ambyst, float headYaw, float headPitch) { + this.body.pivotX = 0.0F; + this.head.pivotY = 0.0F; + this.body.pivotY = 20.0F; + Map map = ambyst.getModelAngles(); + if (map.isEmpty()) { + this.body.setAngles(headPitch * 0.017453292F, headYaw * 0.017453292F, 0.0F); + this.head.setAngles(0.0F, 0.0F, 0.0F); + this.leftHindLeg.setAngles(0.0F, 0.0F, 0.0F); + this.rightHindLeg.setAngles(0.0F, 0.0F, 0.0F); + this.leftFrontLeg.setAngles(0.0F, 0.0F, 0.0F); + this.rightFrontLeg.setAngles(0.0F, 0.0F, 0.0F); + this.leftGills.setAngles(0.0F, 0.0F, 0.0F); + this.rightGills.setAngles(0.0F, 0.0F, 0.0F); + this.topGills.setAngles(0.0F, 0.0F, 0.0F); + this.tail.setAngles(0.0F, 0.0F, 0.0F); + } else { + this.setAngles(this.body, map.get("body")); + this.setAngles(this.head, map.get("head")); + this.setAngles(this.leftHindLeg, map.get("left_hind_leg")); + this.setAngles(this.rightHindLeg, map.get("right_hind_leg")); + this.setAngles(this.leftFrontLeg, map.get("left_front_leg")); + this.setAngles(this.rightFrontLeg, map.get("right_front_leg")); + this.setAngles(this.leftGills, map.get("left_gills")); + this.setAngles(this.rightGills, map.get("right_gills")); + this.setAngles(this.topGills, map.get("top_gills")); + this.setAngles(this.tail, map.get("tail")); + } + + } + + private float lerpAngleDegrees(float start, float end) { + return this.lerpAngleDegrees(0.05F, start, end); + } + + private float lerpAngleDegrees(float delta, float start, float end) { + return MathHelper.lerpAngleDegrees(delta, start, end); + } + + private void setAngles(ModelPart part, float pitch, float yaw, float roll) { + part.setAngles(this.lerpAngleDegrees(part.pitch, pitch), this.lerpAngleDegrees(part.yaw, yaw), this.lerpAngleDegrees(part.roll, roll)); + } + + private void setStandingOnGroundAngles(float animationProgress, float headYaw) { + float f = animationProgress * 0.09F; + float g = MathHelper.sin(f); + float h = MathHelper.cos(f); + float i = g * g - 2.0F * g; + float j = h * h - 3.0F * g; + this.head.pitch = this.lerpAngleDegrees(this.head.pitch, -0.09F * i); + this.head.yaw = this.lerpAngleDegrees(this.head.yaw, 0.0F); + this.head.roll = this.lerpAngleDegrees(this.head.roll, -0.2F); + this.tail.yaw = this.lerpAngleDegrees(this.tail.yaw, -0.1F + 0.1F * i); + this.topGills.pitch = this.lerpAngleDegrees(this.topGills.pitch, 0.6F + 0.05F * j); + this.leftGills.yaw = this.lerpAngleDegrees(this.leftGills.yaw, -this.topGills.pitch); + this.rightGills.yaw = this.lerpAngleDegrees(this.rightGills.yaw, -this.leftGills.yaw); + this.setAngles(this.leftHindLeg, 1.1F, 1.0F, 0.0F); + this.setAngles(this.leftFrontLeg, 0.8F, 2.3F, -0.5F); + this.copyLegAngles(); + this.body.pitch = this.lerpAngleDegrees(0.2F, this.body.pitch, 0.0F); + this.body.yaw = this.lerpAngleDegrees(this.body.yaw, headYaw * 0.017453292F); + this.body.roll = this.lerpAngleDegrees(this.body.roll, 0.0F); + } + + private void setMovingOnGroundAngles(float animationProgress, float headYaw) { + float f = animationProgress * 0.11F; + float g = MathHelper.cos(f); + float h = (g * g - 2.0F * g) / 5.0F; + float i = 0.7F * g; + this.head.pitch = this.lerpAngleDegrees(this.head.pitch, 0.0F); + this.head.yaw = this.lerpAngleDegrees(this.head.yaw, 0.09F * g); + this.head.roll = this.lerpAngleDegrees(this.head.roll, 0.0F); + this.tail.yaw = this.lerpAngleDegrees(this.tail.yaw, this.head.yaw); + this.topGills.pitch = this.lerpAngleDegrees(this.topGills.pitch, 0.6F - 0.08F * (g * g + 2.0F * MathHelper.sin(f))); + this.leftGills.yaw = this.lerpAngleDegrees(this.leftGills.yaw, -this.topGills.pitch); + this.rightGills.yaw = this.lerpAngleDegrees(this.rightGills.yaw, -this.leftGills.yaw); + this.setAngles(this.leftHindLeg, 0.9424779F, 1.5F - h, -0.1F); + this.setAngles(this.leftFrontLeg, 1.0995574F, 1.5707964F - i, 0.0F); + this.setAngles(this.rightHindLeg, this.leftHindLeg.pitch, -1.0F - h, 0.0F); + this.setAngles(this.rightFrontLeg, this.leftFrontLeg.pitch, -1.5707964F - i, 0.0F); + this.body.pitch = this.lerpAngleDegrees(0.2F, this.body.pitch, 0.0F); + this.body.yaw = this.lerpAngleDegrees(this.body.yaw, headYaw * 0.017453292F); + this.body.roll = this.lerpAngleDegrees(this.body.roll, 0.0F); + } + + private void setStandingInWaterAngles(float animationProgress) { + float f = animationProgress * 0.075F; + float g = MathHelper.cos(f); + float h = MathHelper.sin(f) * 0.15F; + this.body.pitch = this.lerpAngleDegrees(this.body.pitch, -0.15F + 0.075F * g); + this.body.pivotY -= h; + this.head.pitch = this.lerpAngleDegrees(this.head.pitch, -this.body.pitch); + this.topGills.pitch = this.lerpAngleDegrees(this.topGills.pitch, 0.2F * g); + this.leftGills.yaw = this.lerpAngleDegrees(this.leftGills.yaw, -0.3F * g - 0.19F); + this.rightGills.yaw = this.lerpAngleDegrees(this.rightGills.yaw, -this.leftGills.yaw); + this.setAngles(this.leftHindLeg, 2.3561945F - g * 0.11F, 0.47123894F, 1.7278761F); + this.setAngles(this.leftFrontLeg, 0.7853982F - g * 0.2F, 2.042035F, 0.0F); + this.copyLegAngles(); + this.tail.yaw = this.lerpAngleDegrees(this.tail.yaw, 0.5F * g); + this.head.yaw = this.lerpAngleDegrees(this.head.yaw, 0.0F); + this.head.roll = this.lerpAngleDegrees(this.head.roll, 0.0F); + } + + private void setMovingInWaterAngles(float animationProgress, float headPitch) { + float f = animationProgress * 0.33F; + float g = MathHelper.sin(f); + float h = MathHelper.cos(f); + float i = 0.13F * g; + this.body.pitch = this.lerpAngleDegrees(0.1F, this.body.pitch, headPitch * 0.017453292F + i); + this.head.pitch = -i * 1.8F; + this.body.pivotY -= 0.45F * h; + this.topGills.pitch = this.lerpAngleDegrees(this.topGills.pitch, -0.5F * g - 0.8F); + this.leftGills.yaw = this.lerpAngleDegrees(this.leftGills.yaw, 0.3F * g + 0.9F); + this.rightGills.yaw = this.lerpAngleDegrees(this.rightGills.yaw, -this.leftGills.yaw); + this.tail.yaw = this.lerpAngleDegrees(this.tail.yaw, 0.3F * MathHelper.cos(f * 0.9F)); + this.setAngles(this.leftHindLeg, 1.8849558F, -0.4F * g, 1.5707964F); + this.setAngles(this.leftFrontLeg, 1.8849558F, -0.2F * h - 0.1F, 1.5707964F); + this.copyLegAngles(); + this.head.yaw = this.lerpAngleDegrees(this.head.yaw, 0.0F); + this.head.roll = this.lerpAngleDegrees(this.head.roll, 0.0F); + } + + private void setPlayingDeadAngles(float headYaw) { + this.setAngles(this.leftHindLeg, 1.4137167F, 1.0995574F, 0.7853982F); + this.setAngles(this.leftFrontLeg, 0.7853982F, 2.042035F, 0.0F); + this.body.pitch = this.lerpAngleDegrees(this.body.pitch, -0.15F); + this.body.roll = this.lerpAngleDegrees(this.body.roll, 0.35F); + this.copyLegAngles(); + this.body.yaw = this.lerpAngleDegrees(this.body.yaw, headYaw * 0.017453292F); + this.head.pitch = this.lerpAngleDegrees(this.head.pitch, 0.0F); + this.head.yaw = this.lerpAngleDegrees(this.head.yaw, 0.0F); + this.head.roll = this.lerpAngleDegrees(this.head.roll, 0.0F); + this.tail.yaw = this.lerpAngleDegrees(this.tail.yaw, 0.0F); + this.setAngles(this.topGills, 0.0F, 0.0F, 0.0F); + this.setAngles(this.leftGills, 0.0F, 0.0F, 0.0F); + this.setAngles(this.rightGills, 0.0F, 0.0F, 0.0F); + } + + /** + * Copies and mirrors the left leg angles to the right leg angles. + */ + private void copyLegAngles() { + this.setAngles(this.rightHindLeg, this.leftHindLeg.pitch, -this.leftHindLeg.yaw, -this.leftHindLeg.roll); + this.setAngles(this.rightFrontLeg, this.leftFrontLeg.pitch, -this.leftFrontLeg.yaw, -this.leftFrontLeg.roll); + } +} diff --git a/src/main/java/net/id/aether/client/rendering/entity/AetherEntityRenderers.java b/src/main/java/net/id/aether/client/rendering/entity/AetherEntityRenderers.java index abf576dc7..856f06a8a 100644 --- a/src/main/java/net/id/aether/client/rendering/entity/AetherEntityRenderers.java +++ b/src/main/java/net/id/aether/client/rendering/entity/AetherEntityRenderers.java @@ -9,6 +9,7 @@ import net.id.aether.client.rendering.entity.misc.RookRenderer; import net.id.aether.client.rendering.entity.passive.AerbunnyRenderer; import net.id.aether.client.rendering.entity.passive.AerwhaleRenderer; +import net.id.aether.client.rendering.entity.passive.AmbystRenderer; import net.id.aether.client.rendering.entity.passive.MoaEntityRenderer; import net.id.aether.client.rendering.entity.projectile.CockatriceSpitRenderer; import net.id.aether.client.rendering.entity.projectile.DartRenderer; @@ -41,7 +42,7 @@ public static void initClient() { register(AetherEntityTypes.MOA, MoaEntityRenderer::new); register(AetherEntityTypes.AERBUNNY, AerbunnyRenderer::new); register(AetherEntityTypes.AERWHALE, AerwhaleRenderer::new); - +// register(AetherEntityTypes.AMBYST, AmbystRenderer::new); // projectile register(AetherEntityTypes.COCKATRICE_SPIT, CockatriceSpitRenderer::new); register(DartRenderer::new, diff --git a/src/main/java/net/id/aether/client/rendering/entity/passive/AmbystRenderer.java b/src/main/java/net/id/aether/client/rendering/entity/passive/AmbystRenderer.java new file mode 100644 index 000000000..49a61b362 --- /dev/null +++ b/src/main/java/net/id/aether/client/rendering/entity/passive/AmbystRenderer.java @@ -0,0 +1,23 @@ +package net.id.aether.client.rendering.entity.passive; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.id.aether.client.model.AetherModelLayers; +import net.id.aether.client.model.entity.AmbystModel; +import net.id.aether.entities.passive.ambyst.AmbystEntity; +import net.minecraft.client.render.entity.EntityRendererFactory; +import net.minecraft.client.render.entity.MobEntityRenderer; +import net.minecraft.util.Identifier; + +@Environment(EnvType.CLIENT) +public class AmbystRenderer extends MobEntityRenderer { + + public AmbystRenderer(EntityRendererFactory.Context renderManager) { + super(renderManager, new AmbystModel(renderManager.getPart(AetherModelLayers.AMBYST)), 0.5f); + } + + @Override + public Identifier getTexture(AmbystEntity entity) { + return new Identifier("textures/entity/axolotl/axolotl_blue.png"); + } +} \ No newline at end of file diff --git a/src/main/java/net/id/aether/entities/AetherEntityTypes.java b/src/main/java/net/id/aether/entities/AetherEntityTypes.java index f4b121a2a..1ac1ad8a8 100644 --- a/src/main/java/net/id/aether/entities/AetherEntityTypes.java +++ b/src/main/java/net/id/aether/entities/AetherEntityTypes.java @@ -1,7 +1,10 @@ package net.id.aether.entities; +import com.google.common.collect.ImmutableSet; +import com.mojang.serialization.Codec; import net.fabricmc.fabric.api.object.builder.v1.entity.FabricDefaultAttributeRegistry; import net.fabricmc.fabric.api.object.builder.v1.entity.FabricEntityTypeBuilder; +import net.id.aether.Aether; import net.id.aether.entities.block.FloatingBlockEntity; import net.id.aether.entities.block.SliderEntity; import net.id.aether.entities.hostile.AechorPlantEntity; @@ -11,16 +14,28 @@ import net.id.aether.entities.passive.AerbunnyEntity; import net.id.aether.entities.passive.AerwhaleEntity; import net.id.aether.entities.passive.AetherAnimalEntity; +import net.id.aether.entities.passive.ambyst.FindLogSensor; import net.id.aether.entities.passive.moa.MoaEntity; import net.id.aether.entities.projectile.*; +import net.id.aether.mixin.brain.ActivityInvoker; +import net.id.aether.mixin.brain.MemoryModuleTypeInvoker; +import net.id.aether.mixin.brain.SensorTypeInvoker; import net.id.aether.registry.AetherRegistryQueues; import net.id.incubus_core.util.RegistryQueue.Action; import net.minecraft.entity.*; +import net.minecraft.entity.ai.brain.Activity; +import net.minecraft.entity.ai.brain.MemoryModuleType; +import net.minecraft.entity.ai.brain.sensor.Sensor; +import net.minecraft.entity.ai.brain.sensor.SensorType; import net.minecraft.entity.attribute.DefaultAttributeContainer; import net.minecraft.entity.mob.HostileEntity; import net.minecraft.entity.mob.MobEntity; +import net.minecraft.entity.passive.AnimalEntity; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.Heightmap; +import java.util.Set; import java.util.function.Supplier; import static net.id.aether.Aether.locate; @@ -63,9 +78,10 @@ public class AetherEntityTypes { attributes(AerbunnyEntity::createAerbunnyAttributes), spawnRestrictions(AetherAnimalEntity::isValidNaturalAetherSpawn)); public static final EntityType AERWHALE = add("aerwhale", of(AerwhaleEntity::new, CREATURE, changing(3.0F, 1.2F), 5), attributes(AerwhaleEntity::createAerwhaleAttributes), spawnRestrictions(MobEntity::canMobSpawn)); - public static final EntityType ROOK = add("rook", of(RookEntity::new, MISC, fixed(0.75F, 1.8F), 5), attributes(RookEntity::createRookAttributes), spawnRestrictions((type, world, spawnReason, pos, random) -> false)); +// public static final EntityType AMBYST = add("ambyst", of(AmbystEntity::new, CREATURE, changing(0.6F, 0.42F), 5), +// attributes(AmbystEntity::createAmbystAttributes), spawnRestrictions(AetherAnimalEntity::isValidNaturalAetherSpawn)); // projectile public static final EntityType COCKATRICE_SPIT = add("cockatrice_spit", of(CockatriceSpitEntity::new, MISC, changing(0.5F, 0.5F), 5)); public static final EntityType GOLDEN_DART = add("golden_dart", of(GoldenDartEntity::new, MISC, changing(0.5F, 0.5F), 5)); @@ -73,6 +89,25 @@ public class AetherEntityTypes { public static final EntityType POISON_DART = add("poison_dart", of(PoisonDartEntity::new, MISC, changing(0.5F, 0.5F), 5)); public static final EntityType POISON_NEEDLE = add("poison_needle", of(PoisonNeedleEntity::new, MISC, changing(0.5F, 0.5F), 5)); + + //Brain + public static final Activity HIDEINLOG = ActivityInvoker.invokeRegister(Aether.locate("hideinlog").toString()); + + public static final MemoryModuleType IS_RAINING_MEMORY = MemoryModuleTypeInvoker.invokeRegister(Aether.locate("is_raining").toString(), Codec.BOOL); + public static final MemoryModuleType LOG_MEMORY = MemoryModuleTypeInvoker.invokeRegister(Aether.locate("log").toString(), BlockPos.CODEC); + public static final MemoryModuleType LOG_OPENING_MEMORY = MemoryModuleTypeInvoker.invokeRegister(Aether.locate("log_opening").toString(), BlockPos.CODEC); + + public static final SensorType FINDLOG_SENSOR = SensorTypeInvoker.invokeRegister(Aether.locate("find_log").toString(),() -> new FindLogSensor(6,20)); + public static final SensorType> WEATHER_SENSOR = SensorTypeInvoker.invokeRegister(Aether.locate("weather").toString(), () -> new Sensor<>(100) { + protected void sense(ServerWorld world, AnimalEntity entity) { + entity.getBrain().remember(AetherEntityTypes.IS_RAINING_MEMORY, world.isRaining()); + } + + public Set> getOutputMemoryModules() { + return ImmutableSet.of(AetherEntityTypes.IS_RAINING_MEMORY); + } + }); + private static Action> attributes(Supplier builder) { return (id, entityType) -> FabricDefaultAttributeRegistry.register(entityType, builder.get()); } diff --git a/src/main/java/net/id/aether/entities/passive/ambyst/AmbystBrain.java b/src/main/java/net/id/aether/entities/passive/ambyst/AmbystBrain.java new file mode 100644 index 000000000..3c759362d --- /dev/null +++ b/src/main/java/net/id/aether/entities/passive/ambyst/AmbystBrain.java @@ -0,0 +1,58 @@ +package net.id.aether.entities.passive.ambyst; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.mojang.datafixers.util.Pair; +import net.id.aether.entities.AetherEntityTypes; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.ai.brain.*; +import net.minecraft.entity.ai.brain.task.*; +import net.minecraft.util.math.intprovider.UniformIntProvider; + +public class AmbystBrain { + + protected static Brain create(Brain brain) { + addCoreActivities(brain); + addIdleActivities(brain); + addHideActivities(brain); + brain.setCoreActivities(ImmutableSet.of(Activity.CORE)); + brain.setDefaultActivity(Activity.HIDE); + brain.resetPossibleActivities(); + return brain; + } + + private static void addCoreActivities(Brain brain) { + brain.setTaskList(Activity.CORE, 0, ImmutableList.of(new LookAroundTask(45, 90), new WanderAroundTask(), new TemptationCooldownTask(MemoryModuleType.TEMPTATION_COOLDOWN_TICKS))); + } + + private static void addIdleActivities(Brain brain) { + brain.setTaskList(Activity.IDLE, ImmutableList.of(Pair.of(0, new TimeLimitedTask(new FollowMobTask(EntityType.PLAYER, 6.0F), UniformIntProvider.create(30, 60))), Pair.of(1, new BreedTask(EntityType.AXOLOTL, 0.2F)), Pair.of(3, new SeekWaterTask(6, 0.15F)), Pair.of(4, new CompositeTask(ImmutableMap.of(MemoryModuleType.WALK_TARGET, MemoryModuleState.VALUE_ABSENT), ImmutableSet.of(), CompositeTask.Order.ORDERED, CompositeTask.RunMode.TRY_ALL, ImmutableList.of(Pair.of(new AquaticStrollTask(0.5F), 2), Pair.of(new StrollTask(0.15F, false), 2)))))); + } + + private static void addHideActivities(Brain brain) { + //Run and hide when not raining + brain.setTaskList(Activity.HIDE, 0, ImmutableList.of(new RunToLogTask())); + + //StayInLogTask will control the ambyst moving around inside the log while it's hiding there. Maybe cowering away when the player gets close + brain.setTaskList(AetherEntityTypes.HIDEINLOG, 0, ImmutableList.of(new StayInLogTask())); + } + /* + public static void updateActivities(AxolotlEntity axolotl) { + Brain brain = axolotl.getBrain(); + Activity activity = (Activity)brain.getFirstPossibleNonCoreActivity().orElse((Object)null); + if (activity != Activity.PLAY_DEAD) { + brain.resetPossibleActivities((List)ImmutableList.of(Activity.PLAY_DEAD, Activity.FIGHT, Activity.IDLE)); + if (activity == Activity.FIGHT && brain.getFirstPossibleNonCoreActivity().orElse((Object)null) != Activity.FIGHT) { + brain.remember(MemoryModuleType.HAS_HUNTING_COOLDOWN, true, 2400L); + } + } + + } + + public static Ingredient getTemptItems() { + return Ingredient.fromTag(ItemTags.AXOLOTL_TEMPT_ITEMS); + } + + */ +} \ No newline at end of file diff --git a/src/main/java/net/id/aether/entities/passive/ambyst/AmbystEntity.java b/src/main/java/net/id/aether/entities/passive/ambyst/AmbystEntity.java new file mode 100644 index 000000000..71d0c7338 --- /dev/null +++ b/src/main/java/net/id/aether/entities/passive/ambyst/AmbystEntity.java @@ -0,0 +1,115 @@ +package net.id.aether.entities.passive.ambyst; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Maps; +import com.mojang.serialization.Dynamic; +import net.id.aether.entities.AetherEntityTypes; +import net.id.aether.entities.passive.AetherAnimalEntity; +import net.minecraft.entity.*; +import net.minecraft.entity.ai.brain.Brain; +import net.minecraft.entity.ai.brain.MemoryModuleType; +import net.minecraft.entity.ai.brain.sensor.Sensor; +import net.minecraft.entity.ai.brain.sensor.SensorType; +import net.minecraft.entity.ai.control.AquaticMoveControl; +import net.minecraft.entity.ai.pathing.PathNodeType; +import net.minecraft.entity.attribute.DefaultAttributeContainer; +import net.minecraft.entity.attribute.EntityAttributes; +import net.minecraft.entity.passive.AnimalEntity; +import net.minecraft.entity.passive.PassiveEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.Vec3f; +import net.minecraft.world.World; +import org.jetbrains.annotations.Nullable; + +import java.util.Map; + +public class AmbystEntity extends AetherAnimalEntity implements AngledModelEntity { + protected static final ImmutableList>> SENSORS; + protected static final ImmutableList> MEMORY_MODULES; + private final Map modelAngles = Maps.newHashMap(); + + public AmbystEntity(EntityType entityType, World world) { + super(entityType, world); + this.setPathfindingPenalty(PathNodeType.WATER, 0.0F); + this.moveControl = new AquaticMoveControl(this, 20, 20, 1, 1, false); + //this.lookControl = new AquaticLookControl(this, 180); + //this.stepHeight = 1; + } + + protected float getActiveEyeHeight(EntityPose pose, EntityDimensions dimensions) { + return dimensions.height * 0.655F; + } + + public static DefaultAttributeContainer.Builder createAmbystAttributes() { + return createMobAttributes() + .add(EntityAttributes.GENERIC_MAX_HEALTH, 14.0D) + .add(EntityAttributes.GENERIC_MOVEMENT_SPEED, 1.0D) + .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, 2.0D); + } + + @Override + public boolean canBreatheInWater() { + return true; + } + + @Override + public boolean isPushedByFluids() { + return false; + } + + @Override + protected Brain.Profile createBrainProfile() { + return Brain.createProfile(MEMORY_MODULES, SENSORS); + } + + @Override + protected Brain deserializeBrain(Dynamic dynamic) { + return AmbystBrain.create(this.createBrainProfile().deserialize(dynamic)); + } + + @Override + public Brain getBrain() { + return (Brain) super.getBrain(); + } + + @Override + protected void mobTick() { + this.world.getProfiler().push("ambystBrain"); + this.getBrain().tick((ServerWorld) this.world, this); + this.world.getProfiler().pop(); + } + + @Override + public ActionResult interactAt(PlayerEntity player, Vec3d hitPos, Hand hand) { + //this.navigation.startMovingTo(player, .5); + //this.setBodyYaw(this.bodyYaw +10); + //this.setHeadYaw(this.getHeadYaw() + 10); + //this.setYaw(this.getYaw() +10); + this.lookControl.lookAt(player); + return ActionResult.SUCCESS; + } + + public EntityGroup getGroup() { + return EntityGroup.AQUATIC; + } + + @Nullable + @Override + public PassiveEntity createChild(ServerWorld world, PassiveEntity entity) { + return null; + } + + @Override + public Map getModelAngles() { + return this.modelAngles; + } + + static { + SENSORS = ImmutableList.of(SensorType.NEAREST_LIVING_ENTITIES, AetherEntityTypes.WEATHER_SENSOR, AetherEntityTypes.FINDLOG_SENSOR); + MEMORY_MODULES = ImmutableList.of(AetherEntityTypes.IS_RAINING_MEMORY, AetherEntityTypes.LOG_OPENING_MEMORY, AetherEntityTypes.LOG_MEMORY, MemoryModuleType.BREED_TARGET, MemoryModuleType.MOBS, MemoryModuleType.VISIBLE_MOBS, MemoryModuleType.NEAREST_VISIBLE_PLAYER, MemoryModuleType.NEAREST_VISIBLE_TARGETABLE_PLAYER, MemoryModuleType.LOOK_TARGET, MemoryModuleType.WALK_TARGET, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryModuleType.PATH, MemoryModuleType.ATTACK_TARGET, MemoryModuleType.ATTACK_COOLING_DOWN, MemoryModuleType.NEAREST_VISIBLE_ADULT, MemoryModuleType.HURT_BY_ENTITY, MemoryModuleType.PLAY_DEAD_TICKS, MemoryModuleType.NEAREST_ATTACKABLE, MemoryModuleType.TEMPTING_PLAYER, MemoryModuleType.TEMPTATION_COOLDOWN_TICKS, MemoryModuleType.IS_TEMPTED, MemoryModuleType.HAS_HUNTING_COOLDOWN); + } +} \ No newline at end of file diff --git a/src/main/java/net/id/aether/entities/passive/ambyst/FindLogSensor.java b/src/main/java/net/id/aether/entities/passive/ambyst/FindLogSensor.java new file mode 100644 index 000000000..577388909 --- /dev/null +++ b/src/main/java/net/id/aether/entities/passive/ambyst/FindLogSensor.java @@ -0,0 +1,84 @@ +package net.id.aether.entities.passive.ambyst; + +import com.google.common.collect.ImmutableSet; +import net.id.aether.blocks.AetherBlocks; +import net.id.aether.entities.AetherEntityTypes; +import net.minecraft.block.BlockState; +import net.minecraft.block.PillarBlock; +import net.minecraft.entity.ai.brain.Brain; +import net.minecraft.entity.ai.brain.MemoryModuleType; +import net.minecraft.entity.ai.brain.sensor.Sensor; +import net.minecraft.entity.passive.AnimalEntity; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.Vec3d; + +import java.util.Optional; +import java.util.Set; + +public class FindLogSensor extends Sensor { + private final int range; + + public FindLogSensor(int range, int updateInterval) { + super(updateInterval); + this.range = range; + } + + protected void sense(ServerWorld world, AnimalEntity entity) { + Brain brain = entity.getBrain(); + Optional previousOpenPos = brain.getOptionalMemory(AetherEntityTypes.LOG_OPENING_MEMORY); + Optional previousLogPos = brain.getOptionalMemory(AetherEntityTypes.LOG_MEMORY); + + if (previousOpenPos.isPresent() && isValidOpening(world, previousOpenPos.get()) && + previousLogPos.isPresent() && isLog(world, previousLogPos.get())) + return; + + for (BlockPos testLogPos : BlockPos.iterateOutwards(entity.getBlockPos(), this.range, this.range, this.range)) { + if (isLog(world, testLogPos)) { + BlockState logState = world.getBlockState(testLogPos); + Direction logDir = Direction.from(logState.get(PillarBlock.AXIS), Direction.AxisDirection.POSITIVE); + + BlockPos foundLogPos; + BlockPos openingPos = getLogOpening(world, logDir, testLogPos); + if (openingPos == null) { + logDir = logDir.getOpposite(); + openingPos = getLogOpening(world, logDir, testLogPos); + } + + if (openingPos != null) { + foundLogPos = openingPos.offset(logDir.getOpposite()); + entity.getBrain().remember(AetherEntityTypes.LOG_MEMORY, foundLogPos); + entity.getBrain().remember(AetherEntityTypes.LOG_OPENING_MEMORY, openingPos); + break; + } + } + } + } + + public BlockPos getLogOpening(ServerWorld world, Direction dir, BlockPos pos) { + BlockPos newPos = pos.offset(dir); + if (isLogSameRotation(world, newPos, dir)) { + return getLogOpening(world, dir, newPos); + } + if (isValidOpening(world, newPos)) + return newPos; + return null; + } + + public static boolean isLog(ServerWorld world, BlockPos testPos) { + return world.getBlockState(testPos).isOf(AetherBlocks.MOTTLED_SKYROOT_FALLEN_LOG) && world.getBlockState(testPos).get(PillarBlock.AXIS) != Direction.Axis.Y; + } + + public static boolean isLogSameRotation(ServerWorld world, BlockPos testPos,Direction dir) { + return world.getBlockState(testPos).isOf(AetherBlocks.MOTTLED_SKYROOT_FALLEN_LOG) && world.getBlockState(testPos).get(PillarBlock.AXIS) == dir.getAxis(); + } + + public static boolean isValidOpening(ServerWorld world, BlockPos testPos) { + return !world.getBlockState(testPos).getMaterial().isSolid() && !world.getBlockState(testPos).isSolidBlock(world, testPos); + } + + public Set> getOutputMemoryModules() { + return ImmutableSet.of(AetherEntityTypes.LOG_MEMORY, AetherEntityTypes.LOG_OPENING_MEMORY); + } +} diff --git a/src/main/java/net/id/aether/entities/passive/ambyst/RunToLogTask.java b/src/main/java/net/id/aether/entities/passive/ambyst/RunToLogTask.java new file mode 100644 index 000000000..3a0817b31 --- /dev/null +++ b/src/main/java/net/id/aether/entities/passive/ambyst/RunToLogTask.java @@ -0,0 +1,82 @@ +package net.id.aether.entities.passive.ambyst; + +import com.google.common.collect.ImmutableMap; +import net.id.aether.entities.AetherEntityTypes; +import net.minecraft.entity.ai.brain.Brain; +import net.minecraft.entity.ai.brain.MemoryModuleState; +import net.minecraft.entity.ai.brain.task.Task; +import net.minecraft.entity.ai.pathing.Path; +import net.minecraft.entity.ai.pathing.PathNode; +import net.minecraft.entity.passive.AnimalEntity; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.math.BlockPos; + +import java.util.ArrayList; +import java.util.List; + +public class RunToLogTask extends Task { + private final float speed = .25f; + + public RunToLogTask() { + super(ImmutableMap.of(AetherEntityTypes.IS_RAINING_MEMORY, MemoryModuleState.VALUE_PRESENT, + AetherEntityTypes.LOG_MEMORY, MemoryModuleState.VALUE_PRESENT, + AetherEntityTypes.LOG_OPENING_MEMORY, MemoryModuleState.VALUE_PRESENT)); + } + + protected boolean shouldRun(ServerWorld world, AnimalEntity entity) { + if (FindLogSensor.isLog(world, entity.getBlockPos())) + return false; + + Brain brain = entity.getBrain(); + Boolean isRaining = brain.getOptionalMemory(AetherEntityTypes.IS_RAINING_MEMORY).get(); + if (isRaining) + return false; + + BlockPos openPos = brain.getOptionalMemory(AetherEntityTypes.LOG_OPENING_MEMORY).get(); + if (!FindLogSensor.isValidOpening(world, openPos)) + return false; + + BlockPos logPos = brain.getOptionalMemory(AetherEntityTypes.LOG_MEMORY).get(); + return FindLogSensor.isLog(world, logPos); + } + + @Override + protected boolean shouldKeepRunning(ServerWorld world, AnimalEntity entity, long time) { + return shouldRun(world, entity); + } + + protected void run(ServerWorld world, AnimalEntity entity, long time) { + Brain brain = entity.getBrain(); + + BlockPos openPos = brain.getOptionalMemory(AetherEntityTypes.LOG_OPENING_MEMORY).get(); + BlockPos logPos = brain.getOptionalMemory(AetherEntityTypes.LOG_MEMORY).get(); + + Path path = entity.getNavigation().findPathTo(openPos, 0); + if (path != null) { + path = extendPath(path, logPos); + entity.getNavigation().startMovingAlong(path, speed); + entity.getLookControl().lookAt(logPos.getX() + .5f, logPos.getY(), logPos.getZ() + .5f); + } + } + + @Override + protected void keepRunning(ServerWorld world, AnimalEntity entity, long time) { + Brain brain = entity.getBrain(); + + BlockPos openPos = brain.getOptionalMemory(AetherEntityTypes.LOG_OPENING_MEMORY).get(); + BlockPos logPos = brain.getOptionalMemory(AetherEntityTypes.LOG_MEMORY).get(); + entity.getLookControl().lookAt(openPos.getX() + .5f, openPos.getY(), openPos.getZ() + .5f); + } + + public Path extendPath(Path path, BlockPos newNode) { + List oldNodes = new ArrayList<>(); + for (int i = 0; i < path.getLength(); i++) + oldNodes.add(path.getNode(i)); + PathNode finalNode = new PathNode(newNode.getX(), newNode.getY(), newNode.getZ()); + finalNode.previous = path.getEnd(); + + oldNodes.add(path.getEnd()); + oldNodes.add(finalNode); + return new Path(oldNodes, newNode, path.reachesTarget()); + } +} \ No newline at end of file diff --git a/src/main/java/net/id/aether/entities/passive/ambyst/StayInLogTask.java b/src/main/java/net/id/aether/entities/passive/ambyst/StayInLogTask.java new file mode 100644 index 000000000..90658e4c0 --- /dev/null +++ b/src/main/java/net/id/aether/entities/passive/ambyst/StayInLogTask.java @@ -0,0 +1,50 @@ +package net.id.aether.entities.passive.ambyst; + +import com.google.common.collect.ImmutableMap; +import net.id.aether.entities.AetherEntityTypes; +import net.minecraft.entity.ai.brain.Brain; +import net.minecraft.entity.ai.brain.MemoryModuleState; +import net.minecraft.entity.ai.brain.task.Task; +import net.minecraft.entity.passive.AnimalEntity; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.math.BlockPos; + +public class StayInLogTask extends Task { + public StayInLogTask() { + super(ImmutableMap.of(AetherEntityTypes.IS_RAINING_MEMORY, MemoryModuleState.VALUE_PRESENT, + AetherEntityTypes.LOG_MEMORY, MemoryModuleState.VALUE_PRESENT, + AetherEntityTypes.LOG_OPENING_MEMORY, MemoryModuleState.VALUE_PRESENT)); + } + + protected boolean shouldRun(ServerWorld world, AnimalEntity entity) { + if (FindLogSensor.isLog(world, entity.getBlockPos())) + return false; + + Brain brain = entity.getBrain(); + Boolean isRaining = brain.getOptionalMemory(AetherEntityTypes.IS_RAINING_MEMORY).get(); + if (isRaining) + return false; + + BlockPos openPos = brain.getOptionalMemory(AetherEntityTypes.LOG_OPENING_MEMORY).get(); + if (!FindLogSensor.isValidOpening(world, openPos)) + return false; + + BlockPos logPos = brain.getOptionalMemory(AetherEntityTypes.LOG_MEMORY).get(); + return FindLogSensor.isLog(world, logPos); + } + + @Override + protected boolean shouldKeepRunning(ServerWorld world, AnimalEntity entity, long time) { + return shouldRun(world, entity); + } + + protected void run(ServerWorld world, AnimalEntity entity, long time) { + Brain brain = entity.getBrain(); + + BlockPos openPos = brain.getOptionalMemory(AetherEntityTypes.LOG_OPENING_MEMORY).get(); + BlockPos logPos = brain.getOptionalMemory(AetherEntityTypes.LOG_MEMORY).get(); + + System.out.println("crawling in hole"); + + } +} diff --git a/src/main/java/net/id/aether/mixin/brain/ActivityInvoker.java b/src/main/java/net/id/aether/mixin/brain/ActivityInvoker.java new file mode 100644 index 000000000..8143b55c7 --- /dev/null +++ b/src/main/java/net/id/aether/mixin/brain/ActivityInvoker.java @@ -0,0 +1,14 @@ +package net.id.aether.mixin.brain; + +import net.minecraft.entity.ai.brain.Activity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(Activity.class) +public interface ActivityInvoker { + + @Invoker + static Activity invokeRegister(String id) { + throw new AssertionError(); + } +} diff --git a/src/main/java/net/id/aether/mixin/brain/MemoryModuleTypeInvoker.java b/src/main/java/net/id/aether/mixin/brain/MemoryModuleTypeInvoker.java new file mode 100644 index 000000000..e8a9482d8 --- /dev/null +++ b/src/main/java/net/id/aether/mixin/brain/MemoryModuleTypeInvoker.java @@ -0,0 +1,22 @@ +package net.id.aether.mixin.brain; + +import com.mojang.serialization.Codec; +import net.minecraft.entity.ai.brain.MemoryModuleType; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + + + +@Mixin(MemoryModuleType.class) +public interface MemoryModuleTypeInvoker { + + @Invoker + static MemoryModuleType invokeRegister(String id, Codec codec) { + throw new AssertionError(); + } + + // @Invoker("register") + // static MemoryModuleType invokeRegister(String id) { + // throw new AssertionError(); + // } +} diff --git a/src/main/java/net/id/aether/mixin/brain/SensorTypeInvoker.java b/src/main/java/net/id/aether/mixin/brain/SensorTypeInvoker.java new file mode 100644 index 000000000..d656545c9 --- /dev/null +++ b/src/main/java/net/id/aether/mixin/brain/SensorTypeInvoker.java @@ -0,0 +1,17 @@ +package net.id.aether.mixin.brain; + +import net.minecraft.entity.ai.brain.sensor.Sensor; +import net.minecraft.entity.ai.brain.sensor.SensorType; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +import java.util.function.Supplier; + +@Mixin(SensorType.class) +public interface SensorTypeInvoker { + + @Invoker + static > SensorType invokeRegister(String id, Supplier factory) { + throw new AssertionError(); + } +} diff --git a/src/main/resources/paradise_lost.mixins.json b/src/main/resources/paradise_lost.mixins.json index 0a2b9e5c9..1fada5822 100644 --- a/src/main/resources/paradise_lost.mixins.json +++ b/src/main/resources/paradise_lost.mixins.json @@ -32,7 +32,10 @@ "server.ServerPlayNetworkHandlerMixin", "util.NbtCompoundAccessor", "util.RarityMixin", - "util.SlotAccessor" + "util.SlotAccessor", + "brain.MemoryModuleTypeInvoker", + "brain.ActivityInvoker", + "brain.SensorTypeInvoker" ], "client": [ "client.ClientPlayNetworkHandlerMixin", From fb7817b895b3bf1461a2f5c2b393b8ceed73915c Mon Sep 17 00:00:00 2001 From: kalucky0 Date: Thu, 8 Sep 2022 10:56:43 +0200 Subject: [PATCH 8/8] Merge branch 'feature/b1.7/mob-adjustments' into 0.2.0/1.19/master --- .../id/aether/entities/AetherEntityTypes.java | 35 +++---- .../entities/hostile/AechorPlantEntity.java | 94 +++++++++++-------- .../entities/hostile/CockatriceEntity.java | 20 +++- 3 files changed, 86 insertions(+), 63 deletions(-) diff --git a/src/main/java/net/id/aether/entities/AetherEntityTypes.java b/src/main/java/net/id/aether/entities/AetherEntityTypes.java index 1ac1ad8a8..910dbf15c 100644 --- a/src/main/java/net/id/aether/entities/AetherEntityTypes.java +++ b/src/main/java/net/id/aether/entities/AetherEntityTypes.java @@ -28,7 +28,6 @@ import net.minecraft.entity.ai.brain.sensor.Sensor; import net.minecraft.entity.ai.brain.sensor.SensorType; import net.minecraft.entity.attribute.DefaultAttributeContainer; -import net.minecraft.entity.mob.HostileEntity; import net.minecraft.entity.mob.MobEntity; import net.minecraft.entity.passive.AnimalEntity; import net.minecraft.server.world.ServerWorld; @@ -48,29 +47,30 @@ public class AetherEntityTypes { /* Begin entity types */ - // block + // Block public static final EntityType FLOATING_BLOCK = add("floating_block", AetherEntityTypes.of(FloatingBlockEntity::new, MISC, changing(0.98F, 0.98F), 10).trackedUpdateRate(20)); public static final EntityType SLIDER = add("slider", AetherEntityTypes.of(SliderEntity::new, MISC, changing(0.98F, 0.98F), 10).trackedUpdateRate(20)); - // hostile + + // Hostile public static final EntityType BLUE_SWET = add("blue_swet", of(BlueSwetEntity::new, MONSTER, changing(2.0F, 2.0F), 5), - attributes(BlueSwetEntity::createSwetAttributes), spawnRestrictions(BlueSwetEntity::canSpawn)); + attributes(BlueSwetEntity::createSwetAttributes), spawnRestrictions(MobEntity::canMobSpawn)); public static final EntityType PURPLE_SWET = add("purple_swet", of(PurpleSwetEntity::new, MONSTER, changing(2.0F, 2.0F), 5), - attributes(PurpleSwetEntity::createSwetAttributes), spawnRestrictions(PurpleSwetEntity::canSpawn)); + attributes(PurpleSwetEntity::createSwetAttributes), spawnRestrictions(MobEntity::canMobSpawn)); public static final EntityType WHITE_SWET = add("white_swet", of(WhiteSwetEntity::new, MONSTER, changing(2.0F, 2.0F), 5), - attributes(WhiteSwetEntity::createSwetAttributes), spawnRestrictions(WhiteSwetEntity::canSpawn)); + attributes(WhiteSwetEntity::createSwetAttributes), spawnRestrictions(MobEntity::canMobSpawn)); public static final EntityType GOLDEN_SWET = add("golden_swet", of(GoldenSwetEntity::new, MONSTER, changing(2.0F, 2.0F), 5), - attributes(GoldenSwetEntity::createSwetAttributes), spawnRestrictions(GoldenSwetEntity::canSpawn)); + attributes(GoldenSwetEntity::createSwetAttributes), spawnRestrictions(MobEntity::canMobSpawn)); public static final EntityType VERMILION_SWET = add("vermilion_swet", of(VermilionSwetEntity::new, MONSTER, changing(2.0F, 2.0F), 5), attributes(VermilionSwetEntity::createSwetAttributes), spawnRestrictions(VermilionSwetEntity::canSpawn)); - //todo: why is this an animal? should extend hostile to allow hostile spawn restrictions, and inherit hostile behviour + // TODO: why is this an animal? should extend hostile to allow hostile spawn restrictions, and inherit hostile behviour public static final EntityType AECHOR_PLANT = add("aechor_plant", of(AechorPlantEntity::new, MONSTER, changing(1f, 1f), 5), - attributes(AechorPlantEntity::createAechorPlantAttributes), spawnRestrictions(AetherAnimalEntity::isValidNaturalAetherSpawn)); -// public static final EntityType CHEST_MIMIC = add("chest_mimic", of(ChestMimicEntity::new, MONSTER, changing(1.0F, 2.0F), 5), -// attributes(ChestMimicEntity::createChestMimicAttributes), spawnRestrictions(HostileEntity::canSpawnInDark)); + attributes(AechorPlantEntity::createAechorPlantAttributes), spawnRestrictions(AechorPlantEntity::canSpawn)); + // public static final EntityType CHEST_MIMIC = add("chest_mimic", of(ChestMimicEntity::new, MONSTER, changing(1.0F, 2.0F), 5), + // attributes(ChestMimicEntity::createChestMimicAttributes), spawnRestrictions(HostileEntity::canSpawnInDark)); public static final EntityType COCKATRICE = add("cockatrice", of(CockatriceEntity::new, MONSTER, changing(1.0F, 2.0F), 5), - attributes(CockatriceEntity::createCockatriceAttributes), spawnRestrictions(HostileEntity::canSpawnInDark)); + attributes(CockatriceEntity::createCockatriceAttributes), spawnRestrictions(CockatriceEntity::canSpawn)); // passive public static final EntityType MOA = add("moa", of(MoaEntity::new, CREATURE, changing(1.0F, 2.0F), 5), attributes(MoaEntity::createMoaAttributes), spawnRestrictions(AetherAnimalEntity::isValidNaturalAetherSpawn)); @@ -80,9 +80,10 @@ public class AetherEntityTypes { attributes(AerwhaleEntity::createAerwhaleAttributes), spawnRestrictions(MobEntity::canMobSpawn)); public static final EntityType ROOK = add("rook", of(RookEntity::new, MISC, fixed(0.75F, 1.8F), 5), attributes(RookEntity::createRookAttributes), spawnRestrictions((type, world, spawnReason, pos, random) -> false)); -// public static final EntityType AMBYST = add("ambyst", of(AmbystEntity::new, CREATURE, changing(0.6F, 0.42F), 5), -// attributes(AmbystEntity::createAmbystAttributes), spawnRestrictions(AetherAnimalEntity::isValidNaturalAetherSpawn)); - // projectile + // public static final EntityType AMBYST = add("ambyst", of(AmbystEntity::new, CREATURE, changing(0.6F, 0.42F), 5), + // attributes(AmbystEntity::createAmbystAttributes), spawnRestrictions(AetherAnimalEntity::isValidNaturalAetherSpawn)); + + // Projectile public static final EntityType COCKATRICE_SPIT = add("cockatrice_spit", of(CockatriceSpitEntity::new, MISC, changing(0.5F, 0.5F), 5)); public static final EntityType GOLDEN_DART = add("golden_dart", of(GoldenDartEntity::new, MISC, changing(0.5F, 0.5F), 5)); public static final EntityType ENCHANTED_DART = add("enchanted_dart", of(EnchantedDartEntity::new, MISC, changing(0.5F, 0.5F), 5)); @@ -97,8 +98,8 @@ public class AetherEntityTypes { public static final MemoryModuleType LOG_MEMORY = MemoryModuleTypeInvoker.invokeRegister(Aether.locate("log").toString(), BlockPos.CODEC); public static final MemoryModuleType LOG_OPENING_MEMORY = MemoryModuleTypeInvoker.invokeRegister(Aether.locate("log_opening").toString(), BlockPos.CODEC); - public static final SensorType FINDLOG_SENSOR = SensorTypeInvoker.invokeRegister(Aether.locate("find_log").toString(),() -> new FindLogSensor(6,20)); - public static final SensorType> WEATHER_SENSOR = SensorTypeInvoker.invokeRegister(Aether.locate("weather").toString(), () -> new Sensor<>(100) { + public static final SensorType FINDLOG_SENSOR = SensorTypeInvoker.invokeRegister(Aether.locate("find_log").toString(), () -> new FindLogSensor(6, 20)); + public static final SensorType> WEATHER_SENSOR = SensorTypeInvoker.invokeRegister(Aether.locate("weather").toString(), () -> new Sensor<>(100) { protected void sense(ServerWorld world, AnimalEntity entity) { entity.getBrain().remember(AetherEntityTypes.IS_RAINING_MEMORY, world.isRaining()); } diff --git a/src/main/java/net/id/aether/entities/hostile/AechorPlantEntity.java b/src/main/java/net/id/aether/entities/hostile/AechorPlantEntity.java index d5b97cf98..f160c9913 100644 --- a/src/main/java/net/id/aether/entities/hostile/AechorPlantEntity.java +++ b/src/main/java/net/id/aether/entities/hostile/AechorPlantEntity.java @@ -1,31 +1,35 @@ package net.id.aether.entities.hostile; -import net.id.aether.entities.passive.AetherAnimalEntity; import net.id.aether.entities.projectile.PoisonNeedleEntity; import net.id.aether.items.AetherItems; import net.id.aether.tag.AetherBlockTags; import net.id.aether.util.AetherSoundEvents; import net.minecraft.entity.*; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.SpawnReason; import net.minecraft.entity.ai.RangedAttackMob; import net.minecraft.entity.ai.goal.ActiveTargetGoal; import net.minecraft.entity.ai.goal.ProjectileAttackGoal; import net.minecraft.entity.ai.goal.RevengeGoal; import net.minecraft.entity.attribute.DefaultAttributeContainer; import net.minecraft.entity.attribute.EntityAttributes; -import net.minecraft.entity.mob.HostileEntity; -import net.minecraft.entity.passive.PassiveEntity; +import net.minecraft.entity.mob.MobEntity; +import net.minecraft.entity.mob.PathAwareEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NbtCompound; -import net.minecraft.server.world.ServerWorld; import net.minecraft.sound.SoundEvent; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; -import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.random.Random; +import net.minecraft.world.ServerWorldAccess; import net.minecraft.world.World; -import net.minecraft.world.WorldAccess; -public class AechorPlantEntity extends AetherAnimalEntity implements RangedAttackMob { +public class AechorPlantEntity extends PathAwareEntity implements RangedAttackMob { public final int poisonRemaining; public float sinage; public int size; @@ -37,22 +41,21 @@ public AechorPlantEntity(EntityType entityType, Wor this.sinage = this.random.nextFloat() * 6F; this.poisonRemaining = this.random.nextInt(4) + 2; - this.setPosition(this.getX(), this.getY(), this.getZ()); + this.setPosition(Math.floor(this.getX()) + 0.5, this.getY(), Math.floor(this.getZ()) + 0.5); } public static DefaultAttributeContainer.Builder createAechorPlantAttributes() { - return HostileEntity.createHostileAttributes().add(EntityAttributes.GENERIC_MAX_HEALTH, 20.0); - } - - public EntityDimensions getSizeForStatus(EntityPose entityPose_1) { - return EntityDimensions.changing(0.75F + ((float) this.size * 0.125F), 0.5F + ((float) this.size * 0.075F)); + return MobEntity.createMobAttributes() + .add(EntityAttributes.GENERIC_MAX_HEALTH, 15.0F) + .add(EntityAttributes.GENERIC_MOVEMENT_SPEED, 0.0F) + .add(EntityAttributes.GENERIC_KNOCKBACK_RESISTANCE, 1.0F); } @Override protected void initGoals() { super.initGoals(); - this.goalSelector.add(4, new ProjectileAttackGoal(this, 0.0D, 30, 1.0F)); + this.goalSelector.add(4, new ProjectileAttackGoal(this, 1.0D, 60, 5.0F)); this.targetSelector.add(1, new RevengeGoal(this, AechorPlantEntity.class)); this.targetSelector.add(2, new ActiveTargetGoal<>(this, LivingEntity.class, 10, true, false, entity -> !(entity instanceof AechorPlantEntity))); @@ -75,27 +78,20 @@ public void tick() { this.sinage -= (3.141593F * 2F); } - @Override - public boolean canSee(Entity entity) { - double distance = this.distanceTo(entity); - return distance <= 6.0F && super.canSee(entity); - } - - @Override - public boolean canSpawn(WorldAccess worldIn, SpawnReason SpawnReason) { - return worldIn.getBlockState(this.getBlockPos().down(1)).isIn(AetherBlockTags.AECHOR_PLANT_VALID_GROUND) - && worldIn.getBaseLightLevel(this.getBlockPos(), 0) > 8; + public static boolean canSpawn(EntityType type, ServerWorldAccess world, SpawnReason spawnReason, BlockPos pos, Random random) { + return world.getBlockState(pos.down(1)).isIn(AetherBlockTags.AECHOR_PLANT_VALID_GROUND) + && world.getBaseLightLevel(pos, 0) > 8; } @Override public void attack(LivingEntity targetIn, float distFactor) { PoisonNeedleEntity needle = new PoisonNeedleEntity(this, this.world); double x = targetIn.getX() - this.getX(); - double y = targetIn.getBoundingBox().minY + (double)(targetIn.getHeight() / 3.0F) - needle.getY(); + double y = targetIn.getBoundingBox().minY + (double) (targetIn.getHeight() / 3.0F) - needle.getY(); double z = targetIn.getZ() - this.getZ(); double distance = Math.sqrt((float) (x * x + z * z)); - needle.setVelocity(x, y + distance * 0.20000000298023224D, z, 1.0F, (float)(14 - this.world.getDifficulty().getId() * 4)); + needle.setVelocity(x, y + distance * 0.20000000298023224D, z, 1.0F, (float) (14 - this.world.getDifficulty().getId() * 4)); this.playSound(AetherSoundEvents.ENTITY_AECHOR_PLANT_SHOOT, 1.0F, 1.2F / (this.getRandom().nextFloat() * 0.2F + 0.9F)); this.world.spawnEntity(needle); } @@ -117,19 +113,6 @@ else if (!player.getInventory().insertStack(new ItemStack(AetherItems.SKYROOT_PO return super.interactMob(player, hand); } - public Vec3d getVelocity() { - return Vec3d.ZERO; - } - - public void setVelocity(Vec3d velocity) { - } - - @Override - public void takeKnockback(double strength, double xRatio, double zRatio) { - if (this.getHealth() <= 0.0F) - super.takeKnockback(strength, xRatio, zRatio); - } - @Override public void writeCustomDataToNbt(NbtCompound compound) { super.writeCustomDataToNbt(compound); @@ -143,8 +126,37 @@ public void readCustomDataFromNbt(NbtCompound compound) { } @Override - public PassiveEntity createChild(ServerWorld world, PassiveEntity entityIn) { - return null; + protected void pushAway(Entity entityIn) { + if (!entityIn.isConnectedThroughVehicle(this)) { + if (!this.noClip && !entityIn.noClip) { + double d0 = this.getX() - entityIn.getX(); + double d1 = this.getZ() - entityIn.getZ(); + double d2 = MathHelper.absMax(d0, d1); + + if (d2 >= 0.009999999776482582D) { + d2 = Math.sqrt((float) d2); + d0 = d0 / d2; + d1 = d1 / d2; + + double d3 = 1.0D / d2; + + if (d3 > 1.0D) { + d3 = 1.0D; + } + + d0 = d0 * d3; + d1 = d1 * d3; + d0 = d0 * 0.05000000074505806D; + d1 = d1 * 0.05000000074505806D; +// d0 = d0 * (double) (1.0F - entityIn.pushthrough); //TODO: What is pushthrough? +// d1 = d1 * (double) (1.0F - entityIn.pushthrough); + + if (!entityIn.hasPassengers()) { + entityIn.addVelocity(-d0, 0.0D, -d1); + } + } + } + } } @Override diff --git a/src/main/java/net/id/aether/entities/hostile/CockatriceEntity.java b/src/main/java/net/id/aether/entities/hostile/CockatriceEntity.java index 0298b64f3..7bd68aed9 100644 --- a/src/main/java/net/id/aether/entities/hostile/CockatriceEntity.java +++ b/src/main/java/net/id/aether/entities/hostile/CockatriceEntity.java @@ -3,6 +3,7 @@ import net.id.aether.effect.condition.Conditions; import net.id.aether.entities.projectile.CockatriceSpitEntity; import net.id.aether.util.AetherSoundEvents; +import net.id.aether.world.dimension.AetherBiomes; import net.id.incubus_core.condition.api.ConditionAPI; import net.id.incubus_core.condition.api.Persistence; import net.id.incubus_core.condition.base.ConditionManager; @@ -11,7 +12,14 @@ import net.minecraft.entity.LivingEntity; import net.minecraft.entity.SpawnReason; import net.minecraft.entity.ai.RangedAttackMob; -import net.minecraft.entity.ai.goal.*; +import net.minecraft.entity.ai.goal.ActiveTargetGoal; +import net.minecraft.entity.ai.goal.GoToWalkTargetGoal; +import net.minecraft.entity.ai.goal.LookAroundGoal; +import net.minecraft.entity.ai.goal.LookAtEntityGoal; +import net.minecraft.entity.ai.goal.ProjectileAttackGoal; +import net.minecraft.entity.ai.goal.RevengeGoal; +import net.minecraft.entity.ai.goal.SwimGoal; +import net.minecraft.entity.ai.goal.WanderAroundFarGoal; import net.minecraft.entity.attribute.DefaultAttributeContainer; import net.minecraft.entity.attribute.EntityAttributes; import net.minecraft.entity.damage.DamageSource; @@ -21,11 +29,13 @@ import net.minecraft.entity.passive.IronGolemEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.sound.SoundEvent; +import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.random.Random; import net.minecraft.world.Difficulty; +import net.minecraft.world.ServerWorldAccess; import net.minecraft.world.World; -import net.minecraft.world.WorldAccess; public class CockatriceEntity extends HostileEntity implements RangedAttackMob { public float flapProgress; @@ -135,9 +145,9 @@ public boolean tryAttack(Entity target) { return false; } - @Override - public boolean canSpawn(WorldAccess world, SpawnReason SpawnReason) { - return world.getRandom().nextInt(25) == 0 && super.canSpawn(world, SpawnReason); + public static boolean canSpawn(EntityType type, ServerWorldAccess world, SpawnReason spawnReason, BlockPos pos, Random random) { + return HostileEntity.canSpawnInDark(type, world, spawnReason, pos, random) || + world.getBiome(pos) == AetherBiomes.AUTUMNAL_TUNDRA; } @Override