From 00a7aa8fb069a935f326622f197f76cd5fd7145a Mon Sep 17 00:00:00 2001 From: HypherionMC Date: Fri, 5 Aug 2022 00:49:49 +0200 Subject: [PATCH] Initial work on NeonFlies --- .../client/model/NeonFlyModel.java | 154 +++++++++++++ .../renderer/entity/NeonFlyRenderer.java | 68 ++++++ .../common/entities/NeonFlyEntity.java | 214 ++++++++++++++++++ .../entities/ai/FindSimilarEntityGoal.java | 126 +++++++++++ .../common/init/CommonRegistration.java | 2 + .../hyperlighting/common/init/HLEntities.java | 25 ++ .../hyperlighting/textures/entity/firefly.png | Bin 0 -> 2046 bytes .../textures/entity/firefly_tail.png | Bin 0 -> 572 bytes .../client/ForgeClientEventHandler.java | 7 + .../common/ForgeCommonHandler.java | 21 ++ 10 files changed, 617 insertions(+) create mode 100644 Common/src/main/java/me/hypherionmc/hyperlighting/client/model/NeonFlyModel.java create mode 100644 Common/src/main/java/me/hypherionmc/hyperlighting/client/renderer/entity/NeonFlyRenderer.java create mode 100644 Common/src/main/java/me/hypherionmc/hyperlighting/common/entities/NeonFlyEntity.java create mode 100644 Common/src/main/java/me/hypherionmc/hyperlighting/common/entities/ai/FindSimilarEntityGoal.java create mode 100644 Common/src/main/java/me/hypherionmc/hyperlighting/common/init/HLEntities.java create mode 100644 Common/src/main/resources/assets/hyperlighting/textures/entity/firefly.png create mode 100644 Common/src/main/resources/assets/hyperlighting/textures/entity/firefly_tail.png create mode 100644 Forge/src/main/java/me/hypherionmc/hyperlighting/common/ForgeCommonHandler.java diff --git a/Common/src/main/java/me/hypherionmc/hyperlighting/client/model/NeonFlyModel.java b/Common/src/main/java/me/hypherionmc/hyperlighting/client/model/NeonFlyModel.java new file mode 100644 index 0000000..06a082a --- /dev/null +++ b/Common/src/main/java/me/hypherionmc/hyperlighting/client/model/NeonFlyModel.java @@ -0,0 +1,154 @@ +package me.hypherionmc.hyperlighting.client.model; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import me.hypherionmc.hyperlighting.Constants; +import net.minecraft.client.model.EntityModel; +import net.minecraft.client.model.geom.ModelLayerLocation; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.model.geom.PartPose; +import net.minecraft.client.model.geom.builders.*; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.Entity; + +/** + * @author HypherionSA + * @date 04/08/2022 + */ +public class NeonFlyModel extends EntityModel { + + public static final ModelLayerLocation LAYER_LOCATION = new ModelLayerLocation(new ResourceLocation(Constants.MOD_ID, "firefly"), "main"); + private final ModelPart head; + private final ModelPart tail_light; + private final ModelPart body; + private final ModelPart right_wing_front; + private final ModelPart right_wing_back; + private final ModelPart left_front_wing; + private final ModelPart left_back_wing; + private final ModelPart left_front_leg; + private final ModelPart left_middle_leg; + private final ModelPart left_rear_leg; + private final ModelPart right_front_leg; + private final ModelPart right_middle_leg; + private final ModelPart right_rear_leg; + + public NeonFlyModel(ModelPart root) { + this.head = root.getChild("head"); + this.tail_light = root.getChild("tail_light"); + this.body = root.getChild("body"); + this.right_wing_front = root.getChild("right_wing_front"); + this.right_wing_back = root.getChild("right_wing_back"); + this.left_front_wing = root.getChild("left_front_wing"); + this.left_back_wing = root.getChild("left_back_wing"); + this.left_front_leg = root.getChild("left_front_leg"); + this.left_middle_leg = root.getChild("left_middle_leg"); + this.left_rear_leg = root.getChild("left_rear_leg"); + this.right_front_leg = root.getChild("right_front_leg"); + this.right_middle_leg = root.getChild("right_middle_leg"); + this.right_rear_leg = root.getChild("right_rear_leg"); + } + + public static LayerDefinition createBodyLayer() { + MeshDefinition meshdefinition = new MeshDefinition(); + PartDefinition partdefinition = meshdefinition.getRoot(); + + PartDefinition head = partdefinition.addOrReplaceChild("head", CubeListBuilder.create().texOffs(21, 25).addBox(-3.0F, -3.0F, -6.0F, 6.0F, 6.0F, 6.0F, new CubeDeformation(0.0F)) + .texOffs(23, 6).addBox(-2.0F, 1.0F, -7.0F, 4.0F, 2.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(0, 31).addBox(3.0F, -1.0F, -5.0F, 1.0F, 3.0F, 3.0F, new CubeDeformation(0.0F)) + .texOffs(0, 0).addBox(-4.0F, -1.0F, -5.0F, 1.0F, 3.0F, 3.0F, new CubeDeformation(0.0F)), PartPose.offset(0.0F, 19.0F, -2.0F)); + + PartDefinition left_antenna = head.addOrReplaceChild("left_antenna", CubeListBuilder.create().texOffs(0, 38).addBox(-0.5F, -1.0174F, -0.5325F, 1.0F, 3.0F, 0.0F, new CubeDeformation(0.0F)), PartPose.offset(1.5F, -3.9826F, -2.4675F)); + PartDefinition cube_r1 = left_antenna.addOrReplaceChild("cube_r1", CubeListBuilder.create().texOffs(6, 0).addBox(-0.5F, -1.5F, -1.0F, 1.0F, 2.0F, 0.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(0.0F, -2.0F, 0.0F, 0.6109F, 0.0F, 0.0F)); + PartDefinition right_antenna = head.addOrReplaceChild("right_antenna", CubeListBuilder.create().texOffs(34, 6).addBox(-0.5F, -1.0174F, -0.5325F, 1.0F, 3.0F, 0.0F, new CubeDeformation(0.0F)), PartPose.offset(-1.5F, -3.9826F, -2.4675F)); + PartDefinition cube_r2 = right_antenna.addOrReplaceChild("cube_r2", CubeListBuilder.create().texOffs(0, 0).addBox(-0.5F, -1.5F, -1.0F, 1.0F, 2.0F, 0.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(0.0F, -2.0F, 0.0F, 0.6109F, 0.0F, 0.0F)); + + PartDefinition tail_light = partdefinition.addOrReplaceChild("tail_light", CubeListBuilder.create().texOffs(0, 17).addBox(-3.0F, -3.0F, 0.0F, 6.0F, 6.0F, 7.0F, new CubeDeformation(0.0F)), PartPose.offset(0.0F, 19.0F, 8.0F)); + PartDefinition body = partdefinition.addOrReplaceChild("body", CubeListBuilder.create().texOffs(0, 0).addBox(-3.0F, -3.0F, -5.0F, 6.0F, 6.0F, 10.0F, new CubeDeformation(0.0F)), PartPose.offset(0.0F, 19.0F, 3.0F)); + + /** Wings **/ + PartDefinition right_wing_front = partdefinition.addOrReplaceChild("right_wing_front", CubeListBuilder.create().texOffs(0, 38).addBox(-8.0F, 0.0F, -2.5F, 8.0F, 0.0F, 5.0F, new CubeDeformation(0.0F)), PartPose.offset(-3.0F, 16.0F, 0.5F)); + PartDefinition right_wing_back = partdefinition.addOrReplaceChild("right_wing_back", CubeListBuilder.create().texOffs(33, 6).addBox(-8.0F, 0.0F, -2.5F, 8.0F, 0.0F, 5.0F, new CubeDeformation(0.0F)), PartPose.offset(-3.0F, 16.0F, 5.5F)); + PartDefinition left_front_wing = partdefinition.addOrReplaceChild("left_front_wing", CubeListBuilder.create().texOffs(23, 0).addBox(0.0F, 0.0F, -2.5F, 8.0F, 0.0F, 5.0F, new CubeDeformation(0.0F)), PartPose.offset(3.0F, 16.0F, 0.5F)); + PartDefinition left_back_wing = partdefinition.addOrReplaceChild("left_back_wing", CubeListBuilder.create().texOffs(20, 17).addBox(0.0F, 0.0F, -2.5F, 8.0F, 0.0F, 5.0F, new CubeDeformation(0.0F)), PartPose.offset(3.0F, 16.0F, 5.5F)); + + /** Legs **/ + PartDefinition left_front_leg = partdefinition.addOrReplaceChild("left_front_leg", CubeListBuilder.create().texOffs(33, 12).addBox(-0.5F, 0.0F, -0.5F, 1.0F, 2.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offset(2.5F, 22.0F, -0.5F)); + PartDefinition left_middle_leg = partdefinition.addOrReplaceChild("left_middle_leg", CubeListBuilder.create().texOffs(14, 31).addBox(-0.5F, 0.0F, -0.5F, 1.0F, 2.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offset(2.5F, 22.0F, 3.0F)); + PartDefinition left_rear_leg = partdefinition.addOrReplaceChild("left_rear_leg", CubeListBuilder.create().texOffs(9, 31).addBox(-0.5F, 0.0F, -0.5F, 1.0F, 2.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offset(2.5F, 22.0F, 6.5F)); + PartDefinition right_front_leg = partdefinition.addOrReplaceChild("right_front_leg", CubeListBuilder.create().texOffs(20, 17).addBox(-0.5F, 0.0F, -0.5F, 1.0F, 2.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offset(-2.5F, 22.0F, -0.5F)); + PartDefinition right_middle_leg = partdefinition.addOrReplaceChild("right_middle_leg", CubeListBuilder.create().texOffs(0, 17).addBox(-0.5F, 0.0F, -0.5F, 1.0F, 2.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offset(-2.5F, 22.0F, 3.0F)); + PartDefinition right_rear_leg = partdefinition.addOrReplaceChild("right_rear_leg", CubeListBuilder.create().texOffs(23, 0).addBox(-0.5F, 0.0F, -0.5F, 1.0F, 2.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offset(-2.5F, 22.0F, 6.5F)); + + return LayerDefinition.create(meshdefinition, 64, 64); + } + + @Override + public void setupAnim(T entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) { + this.head.yRot = netHeadYaw * ((float)Math.PI / 180F); + this.head.xRot = headPitch * ((float)Math.PI / 180F); + + this.right_wing_front.zRot = 0.0f; + this.right_wing_back.zRot = 0.0f; + this.left_front_wing.zRot = 0.0f; + this.left_back_wing.zRot = 0.0f; + + boolean flag = entity.isOnGround() && entity.getDeltaMovement().lengthSqr() < 1.0E-7D; + + if (flag) { + this.right_wing_front.zRot = -0.1f; + this.left_front_wing.zRot = 0.1f; + this.right_wing_back.zRot = 0.1f; + this.left_back_wing.zRot = -0.1f; + + this.tail_light.xRot = 0.0f; + this.tail_light.yRot = 0.0f; + this.tail_light.zRot = 0.0f; + } else { + float f = ageInTicks * 120.32113F * ((float)Math.PI / 180F); + this.right_wing_front.zRot = Mth.cos(f) * (float)Math.PI * 0.15F; + this.left_front_wing.zRot = this.right_wing_front.zRot; + + this.right_wing_back.zRot = -Mth.cos(f) * (float)Math.PI * 0.15F; + this.left_back_wing.zRot = this.right_wing_back.zRot; + + this.tail_light.xRot = -Mth.cos(f) * (float)Math.PI * 0.001F; + this.tail_light.yRot = Mth.cos(f) * (float)Math.PI * 0.001F; + this.tail_light.zRot = 0f; + } + + if (entity.isOnGround()) { + this.right_front_leg.xRot = Mth.cos(limbSwing * 0.6662F) * 1.4F * limbSwingAmount; + this.right_middle_leg.xRot = -Mth.cos(limbSwing * 0.6662F) * 1.3F * limbSwingAmount; + this.right_rear_leg.xRot = Mth.cos(limbSwing * 0.6662F) * 1.2F * limbSwingAmount; + + this.left_front_leg.xRot = -this.right_front_leg.xRot; + this.left_middle_leg.xRot = this.right_middle_leg.xRot; + this.left_rear_leg.xRot = -this.right_front_leg.xRot; + } else { + this.right_front_leg.xRot = 0.2f; + this.right_middle_leg.xRot = 0.2f; + this.right_rear_leg.xRot = 0.2f; + this.left_front_leg.xRot = 0.2f; + this.left_middle_leg.xRot = 0.2f; + this.left_rear_leg.xRot = 0.2f; + } + } + + @Override + public void renderToBuffer(PoseStack poseStack, VertexConsumer buffer, int packedLight, int packedOverlay, float red, float green, float blue, float alpha) { + head.render(poseStack, buffer, packedLight, packedOverlay); + tail_light.render(poseStack, buffer, packedLight, packedOverlay, red, green, blue, alpha); + body.render(poseStack, buffer, packedLight, packedOverlay); + right_wing_front.render(poseStack, buffer, packedLight, packedOverlay); + right_wing_back.render(poseStack, buffer, packedLight, packedOverlay); + left_front_wing.render(poseStack, buffer, packedLight, packedOverlay); + left_back_wing.render(poseStack, buffer, packedLight, packedOverlay); + left_front_leg.render(poseStack, buffer, packedLight, packedOverlay); + left_middle_leg.render(poseStack, buffer, packedLight, packedOverlay); + left_rear_leg.render(poseStack, buffer, packedLight, packedOverlay); + right_front_leg.render(poseStack, buffer, packedLight, packedOverlay); + right_middle_leg.render(poseStack, buffer, packedLight, packedOverlay); + right_rear_leg.render(poseStack, buffer, packedLight, packedOverlay); + } +} diff --git a/Common/src/main/java/me/hypherionmc/hyperlighting/client/renderer/entity/NeonFlyRenderer.java b/Common/src/main/java/me/hypherionmc/hyperlighting/client/renderer/entity/NeonFlyRenderer.java new file mode 100644 index 0000000..d97d73f --- /dev/null +++ b/Common/src/main/java/me/hypherionmc/hyperlighting/client/renderer/entity/NeonFlyRenderer.java @@ -0,0 +1,68 @@ +package me.hypherionmc.hyperlighting.client.renderer.entity; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import me.hypherionmc.hyperlighting.Constants; +import me.hypherionmc.hyperlighting.client.model.NeonFlyModel; +import me.hypherionmc.hyperlighting.common.entities.NeonFlyEntity; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.client.renderer.entity.MobRenderer; +import net.minecraft.client.renderer.entity.RenderLayerParent; +import net.minecraft.client.renderer.entity.layers.EyesLayer; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.core.BlockPos; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.Entity; + +/** + * @author HypherionSA + * @date 04/08/2022 + */ +public class NeonFlyRenderer extends MobRenderer> { + + private static final ResourceLocation TEXTURE = new ResourceLocation(Constants.MOD_ID, "textures/entity/firefly.png"); + + public NeonFlyRenderer(EntityRendererProvider.Context context) { + super(context, new NeonFlyModel(context.bakeLayer(NeonFlyModel.LAYER_LOCATION)), 1f); + this.addLayer(new FireflyTailLayer<>(this)); + } + + @Override + public ResourceLocation getTextureLocation(NeonFlyEntity pEntity) { + return TEXTURE; + } + + @Override + protected int getBlockLightLevel(NeonFlyEntity p_174146_, BlockPos p_174147_) { + return 1; + } + + @Override + protected void scale(NeonFlyEntity pLivingEntity, PoseStack pMatrixStack, float pPartialTickTime) { + float f = 0.08f; + this.shadowRadius = 0.1F; + pMatrixStack.scale(f, f, f); + } + + class FireflyTailLayer> extends EyesLayer { + private static final RenderType FIREFLY_TAIL = RenderType.eyes(new ResourceLocation(Constants.MOD_ID, "textures/entity/firefly_tail.png")); + + public FireflyTailLayer(RenderLayerParent p_117507_) { + super(p_117507_); + } + + @Override + public void render(PoseStack pMatrixStack, MultiBufferSource pBuffer, int pPackedLight, T pLivingEntity, float pLimbSwing, float pLimbSwingAmount, float pPartialTicks, float pAgeInTicks, float pNetHeadYaw, float pHeadPitch) { + float[] color = ((NeonFlyEntity) pLivingEntity).getColor().getTextureDiffuseColors(); + VertexConsumer vertexconsumer = pBuffer.getBuffer(this.renderType()); + this.getParentModel().renderToBuffer(pMatrixStack, vertexconsumer, 15728640, OverlayTexture.NO_OVERLAY, color[0], color[1], color[2], 1.0f); + } + + @Override + public RenderType renderType() { + return FIREFLY_TAIL; + } + } +} diff --git a/Common/src/main/java/me/hypherionmc/hyperlighting/common/entities/NeonFlyEntity.java b/Common/src/main/java/me/hypherionmc/hyperlighting/common/entities/NeonFlyEntity.java new file mode 100644 index 0000000..c77a002 --- /dev/null +++ b/Common/src/main/java/me/hypherionmc/hyperlighting/common/entities/NeonFlyEntity.java @@ -0,0 +1,214 @@ +package me.hypherionmc.hyperlighting.common.entities; + +import me.hypherionmc.hyperlighting.common.entities.ai.FindSimilarEntityGoal; +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.*; +import net.minecraft.world.entity.ai.attributes.AttributeSupplier; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.ai.control.FlyingMoveControl; +import net.minecraft.world.entity.ai.goal.*; +import net.minecraft.world.entity.ai.navigation.FlyingPathNavigation; +import net.minecraft.world.entity.ai.navigation.PathNavigation; +import net.minecraft.world.entity.ai.util.AirAndWaterRandomPos; +import net.minecraft.world.entity.ai.util.HoverRandomPos; +import net.minecraft.world.entity.animal.Animal; +import net.minecraft.world.entity.animal.FlyingAnimal; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.DyeColor; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.biome.Biomes; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.pathfinder.BlockPathTypes; +import net.minecraft.world.phys.Vec3; +import org.jetbrains.annotations.Nullable; + +import java.util.EnumSet; +import java.util.Random; + +/** + * @author HypherionSA + * @date 04/08/2022 + */ +public class NeonFlyEntity extends Animal implements FlyingAnimal { + + private boolean isGlowing = false; + private DyeColor color; + + public NeonFlyEntity(EntityType type, Level level) { + super(type, level); + this.moveControl = new FlyingMoveControl(this, 20, true); + + this.setPathfindingMalus(BlockPathTypes.COCOA, -1.0F); + + this.color = DyeColor.byId(new Random().nextInt(DyeColor.values().length - 1)); + } + + @Override + protected void registerGoals() { + this.goalSelector.addGoal(0, new FireflySwampGoal(this, 1.1D, 24)); + this.goalSelector.addGoal(1, new FindSimilarEntityGoal(this, 1.1D, 24, NeonFlyEntity.class)); + this.goalSelector.addGoal(2, new FireflyWanderGoal()); + this.goalSelector.addGoal(3, new FloatGoal(this)); + this.goalSelector.addGoal(4, new BreedGoal(this, 1.0f)); + this.goalSelector.addGoal(5, new LookAtPlayerGoal(this, Player.class, 8.0f)); + this.goalSelector.addGoal(6, new FleeSunGoal(this, 1.1D)); + } + + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel serverLevel, AgeableMob ageableMob) { + return null; + } + + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + pCompound.putBoolean("isGlowing", isGlowing); + pCompound.putInt("color", color.getId()); + } + + @Override + public void load(CompoundTag pCompound) { + super.load(pCompound); + this.isGlowing = pCompound.getBoolean("isGlowing"); + this.color = DyeColor.byId(pCompound.getInt("color")); + } + + public boolean isGlowing() { + return isGlowing; + } + + public DyeColor getColor() { + return color; + } + + public void setColor(DyeColor color) { + this.color = color; + } + + public void setGlowing(boolean glowing) { + isGlowing = glowing; + } + + public static AttributeSupplier.Builder prepareAttributes() { + return LivingEntity.createLivingAttributes() + .add(Attributes.ATTACK_DAMAGE, 0) + .add(Attributes.MAX_HEALTH, 10.0) + .add(Attributes.FOLLOW_RANGE, 48.0) + .add(Attributes.MOVEMENT_SPEED, 0.3) + .add(Attributes.FLYING_SPEED, 0.6); + } + + @Override + public boolean isFlying() { + return !this.isOnGround(); + } + + @Override + protected PathNavigation createNavigation(Level pLevel) { + FlyingPathNavigation flyingPathNavigation = new FlyingPathNavigation(this, pLevel) { + @Override + public boolean isStableDestination(BlockPos pPos) { + return true; + } + }; + flyingPathNavigation.setCanOpenDoors(false); + flyingPathNavigation.setCanFloat(true); + flyingPathNavigation.setCanPassDoors(true); + return flyingPathNavigation; + } + + @Override + protected boolean isFlapping() { + return this.isFlying() && this.tickCount % 120 == 0; + } + + @Override + public MobType getMobType() { + return MobType.ARTHROPOD; + } + + @Override + public float getWalkTargetValue(BlockPos pPos, LevelReader pLevel) { + return pLevel.getBlockState(pPos).isAir() ? 10.0F : 0.0F; + } + + @Override + protected void playStepSound(BlockPos pPos, BlockState pBlock) {} + + @Override + public boolean causeFallDamage(float pFallDistance, float pMultiplier, DamageSource pSource) { + return false; + } + + @Override + protected void checkFallDamage(double pY, boolean pOnGround, BlockState pState, BlockPos pPos) {} + + @Override + public float getScale() { + return 0.5f; + } + + public static boolean canSpawn(EntityType entity, LevelAccessor levelAccessor, MobSpawnType spawnType, BlockPos pos, Random random) { + return levelAccessor instanceof Level level && !level.isDay() && !level.isRainingAt(pos); + } + + class FireflyWanderGoal extends Goal { + + FireflyWanderGoal() { + this.setFlags(EnumSet.of(Flag.MOVE)); + } + + @Override + public boolean canUse() { + return NeonFlyEntity.this.navigation.isDone() && NeonFlyEntity.this.random.nextInt(10) == 0; + } + + @Override + public boolean canContinueToUse() { + return NeonFlyEntity.this.navigation.isInProgress(); + } + + @Override + public void start() { + Vec3 vec3 = this.findPos(); + if (vec3 != null) { + NeonFlyEntity.this.navigation.moveTo( + NeonFlyEntity.this.navigation.createPath(new BlockPos(vec3), 1), + 1.0D + ); + } + } + + @Nullable + private Vec3 findPos() { + Vec3 vec3 = NeonFlyEntity.this.getViewVector(0.0f); + Vec3 vec32 = HoverRandomPos.getPos(NeonFlyEntity.this, 8, 7, vec3.x, vec3.z, ((float)Math.PI / 2F), 3, 1); + return vec32 != null ? vec32 : AirAndWaterRandomPos.getPos(NeonFlyEntity.this, 8, 4, -2, vec3.x, vec3.z, (float)Math.PI / 2F); + } + } + + static class FireflySwampGoal extends MoveToBlockGoal { + + public FireflySwampGoal(PathfinderMob pMob, double pSpeedModifier, int pSearchRange) { + super(pMob, pSpeedModifier, pSearchRange); + this.verticalSearchStart = -2; + this.setFlags(EnumSet.of(Flag.JUMP, Goal.Flag.MOVE)); + } + + @Override + protected boolean isValidTarget(LevelReader pLevel, BlockPos pPos) { + return pLevel.getBiome(pPos).is(Biomes.SWAMP) && pLevel.getBlockState(pPos).is(Blocks.OAK_LOG); + } + + @Override + protected int nextStartTick(PathfinderMob pCreature) { + return mob.getLevel().random.nextInt(120); + } + } +} diff --git a/Common/src/main/java/me/hypherionmc/hyperlighting/common/entities/ai/FindSimilarEntityGoal.java b/Common/src/main/java/me/hypherionmc/hyperlighting/common/entities/ai/FindSimilarEntityGoal.java new file mode 100644 index 0000000..2cc729d --- /dev/null +++ b/Common/src/main/java/me/hypherionmc/hyperlighting/common/entities/ai/FindSimilarEntityGoal.java @@ -0,0 +1,126 @@ +package me.hypherionmc.hyperlighting.common.entities.ai; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Vec3i; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.PathfinderMob; +import net.minecraft.world.entity.ai.goal.Goal; +import net.minecraft.world.entity.ai.targeting.TargetingConditions; +import net.minecraft.world.level.Level; + +/** + * This code is dirty like my underpants, but like said underpants, it still works :) + */ +public class FindSimilarEntityGoal extends Goal { + + protected final PathfinderMob mob; + public final double speedModifier; + + protected int nextStartTick; + protected int tryTicks; + private int maxStayTicks; + protected BlockPos blockPos = BlockPos.ZERO; + private final int searchRange; + private final int verticalSearchRange; + protected int verticalSearchStart; + + protected final Class findType; + + public FindSimilarEntityGoal(PathfinderMob pMob, double pSpeedModifier, int pSearchRange, Class clazz) { + this.mob = pMob; + this.speedModifier = pSpeedModifier; + this.searchRange = pSearchRange; + this.verticalSearchRange = 1; + this.findType = clazz; + } + + @Override + public boolean canUse() { + if (this.nextStartTick > 0) { + --this.nextStartTick; + return false; + } else { + this.nextStartTick = this.nextStartTick(this.mob); + return this.findNearestEntity(); + } + } + + protected int nextStartTick(PathfinderMob pCreature) { + return reducedTickDelay(200 + pCreature.getRandom().nextInt(200)); + } + + @Override + public boolean canContinueToUse() { + return this.tryTicks >= -this.maxStayTicks && this.tryTicks <= 1200 && this.isValidTarget(this.mob.level); + } + + protected void moveMobToEntity() { + this.mob.getNavigation().moveTo((double)((float)this.blockPos.getX()) + 0.5D, (double)(this.blockPos.getY() + 1), (double)((float)this.blockPos.getZ()) + 0.5D, this.speedModifier); + } + + @Override + public void start() { + this.moveMobToEntity(); + this.tryTicks = 0; + this.maxStayTicks = this.mob.getRandom().nextInt(this.mob.getRandom().nextInt(1200) + 1200) + 1200; + } + + public double acceptedDistance() { + return 1.0D; + } + + protected BlockPos getMoveToTarget() { + return this.blockPos.above(); + } + + @Override + public boolean requiresUpdateEveryTick() { + return true; + } + + @Override + public void tick() { + BlockPos blockpos = this.getMoveToTarget(); + if (!blockpos.closerThan(new Vec3i(this.mob.getBlockX(), this.mob.getBlockY(), this.mob.getBlockZ()), this.acceptedDistance())) { + ++this.tryTicks; + if (this.shouldRecalculatePath()) { + this.mob.getNavigation().moveTo((double)((float)blockpos.getX()) + 0.5D, (double)blockpos.getY(), (double)((float)blockpos.getZ()) + 0.5D, this.speedModifier); + } + } else { + --this.tryTicks; + } + } + + public boolean shouldRecalculatePath() { + return this.tryTicks % 240 == 0; + } + + protected boolean findNearestEntity() { + int i = this.searchRange; + int j = this.verticalSearchRange; + BlockPos blockpos = this.mob.blockPosition(); + BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos(); + + for(int k = this.verticalSearchStart; k <= j; k = k > 0 ? -k : 1 - k) { + for(int l = 0; l < i; ++l) { + for(int i1 = 0; i1 <= l; i1 = i1 > 0 ? -i1 : 1 - i1) { + for(int j1 = i1 < l && i1 > -l ? l : 0; j1 <= l; j1 = j1 > 0 ? -j1 : 1 - j1) { + blockpos$mutableblockpos.setWithOffset(blockpos, i1, k - 1, j1); + return this.mob.isWithinRestriction(blockpos$mutableblockpos) && this.isValidTarget(this.mob.level); + } + } + } + } + return false; + } + + private boolean isValidTarget(Level level) { + Entity entity = level.getNearestEntity(level.getEntitiesOfClass(this.findType, this.mob.getBoundingBox().inflate(this.searchRange, 3.0D, this.searchRange), (p_148124_) -> true), TargetingConditions.forNonCombat().range(searchRange), this.mob, this.mob.getX(), this.mob.getEyeY(), this.mob.getZ()); + if (entity != null) { + this.blockPos = entity.getOnPos(); + } + return entity != null; + } + +} diff --git a/Common/src/main/java/me/hypherionmc/hyperlighting/common/init/CommonRegistration.java b/Common/src/main/java/me/hypherionmc/hyperlighting/common/init/CommonRegistration.java index e576740..ac17c4c 100644 --- a/Common/src/main/java/me/hypherionmc/hyperlighting/common/init/CommonRegistration.java +++ b/Common/src/main/java/me/hypherionmc/hyperlighting/common/init/CommonRegistration.java @@ -17,6 +17,8 @@ public class CommonRegistration { HLParticles.loadAll(); HLBlocks.loadAll(); HLItems.loadAll(); + HLEntities.loadAll(); + } } diff --git a/Common/src/main/java/me/hypherionmc/hyperlighting/common/init/HLEntities.java b/Common/src/main/java/me/hypherionmc/hyperlighting/common/init/HLEntities.java new file mode 100644 index 0000000..57f581a --- /dev/null +++ b/Common/src/main/java/me/hypherionmc/hyperlighting/common/init/HLEntities.java @@ -0,0 +1,25 @@ +package me.hypherionmc.hyperlighting.common.init; + +import me.hypherionmc.craterlib.systems.reg.RegistrationProvider; +import me.hypherionmc.craterlib.systems.reg.RegistryObject; +import me.hypherionmc.hyperlighting.Constants; +import me.hypherionmc.hyperlighting.common.entities.NeonFlyEntity; +import net.minecraft.core.Registry; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.MobCategory; + +/** + * @author HypherionSA + * @date 04/08/2022 + */ +public class HLEntities { + + public static final RegistrationProvider> ENTITIES = RegistrationProvider.get(Registry.ENTITY_TYPE, Constants.MOD_ID); + + public static final RegistryObject> FIREFLY = ENTITIES.register("firefly", () -> EntityType.Builder.of(NeonFlyEntity::new, MobCategory.AMBIENT) + .sized(1f, 1f) + .clientTrackingRange(8) + .build("firefly")); + + public static void loadAll() {} +} diff --git a/Common/src/main/resources/assets/hyperlighting/textures/entity/firefly.png b/Common/src/main/resources/assets/hyperlighting/textures/entity/firefly.png new file mode 100644 index 0000000000000000000000000000000000000000..e620b29ec81a8d8c2e955ba76d6c4f93514cdf5f GIT binary patch literal 2046 zcmVl50>FY@set#YXDBrLSq_?@^>c3dAlD^aC{LlfOaX2ipY-)b00B z(f2+Sh#$NJNmFkTlUky=9b1&~%?%75F1q7fZ7j>*J zfUd;j0O!uGsw5@Ui~&fJ5{jb65F?QiM#p^j!*f4Z-Blv84PX}BLKr;AB_*j1Z$RDQ6zqLM34^CEP#ozxj=-LCY<4~fBu@^Ui%dX`fpGH zv7CAVthO%%w(@?!Ed;>=L`ppW{>gF7^Ymt08;c3e#RSzu0QSdahWmyeUHk6Xd2a(^ z^|gesga{bj!79<7WiNmye>yY8Gr)&m7*MtDKqUyI+uNBdBX5eb-TDs7PG-8Ay8v+h zOc_5mfBSQ8$MDx{TBpuh0@7ovCD8gmt$EGt|EL6J|sKN5B$D3Nav z*wh&cq5N_Zi~hdQ-!HM!u$uOQSZ|l<4h@5m6~anmOe;-*quTbc)`N4VC+c7W%2$!Y z&B!XRuC_01KJOgwV_pZZECA1VGxbq^?4Af)Ju8^4UWsNc2}dU~?^nSz+D$kF&0D~0 ztoiakJ$H6h_x6X>Y7GX%UD8^EfBkVtV<8EQHEW5>dDQv4{9e056KH$;hF{!B=?{CP ze$BnnywTP4zp3E?moBb8hZA;@GZF%`39b{Z06##S{Ee)feSt&G?m8rIv&qfX*T)G=b| zRg^~^VZE(%2TEEQ@!=orx%Y{Y&lK^~e9A1EH+l&onk%fgQd`6z))F)-1~iU|;@!9# zo#w#ACPE7NLdgqI;(;u;BL2%cB9X*;a}93UUO&2#(%UzD)k#=yXF{+gfHhzdbrvG@ z_6;B1NI@0VEGO_+iHamEJU!w|P6J7Z(PnHJbeo1OtYr%F-~MVXVx=)=FscMUk|ZU< zadB&_NKVZ@+sy8Ap91qjT+K6isLkFj&AhhNxQGvh&H`}Z5l9xVXY0iT7L$E|Q)z%q zq8xUgeT7YLKe$JlR)f153=YD?dRnFL?$dgeK|egxiSJw!qzoL|y#A!ze{Kk_IP%G1 zQ)cg$=6vA~ zU<;pmy-L4-K$=$lwBs_Ii6)3_MzTLOocQOucWa_Om~#k65cz;3c-txMo8rV`=-}}~ zz-qsqRzaZOKM3dFT0`D99EW#-*=aaY0F|{%fU*qWB0yCI6=gZf>lZkM9Ck(!vv*6k zAKYX4($Cp`@FmNat}uH1kjmNzxy&teEW{=_FCN@u`SKMG{`-*X+6UM*uGl#Op||du zZnAjo-L-&vy#lB;bAv|MkoXH`yIv|##i5tplC z#cAGJLRAD&=sV#E{d?c!CmjS4R?uQ+3)x^GvsR`XdzE{wyC7{fed4Tds$;<3vn}Xe; z)v`VFwwnaxtYMBj%21MvYS<2MgC+<=V2g(1u3x~;?X%iU6T~swtRZa^mo4`ad}@35?>}ZFhyRT$yO~1FG*Ud&`R@j#nVLeO{evi ze|e(ES68z@g0xg*Nrfd_T6X4|`LvlqM`K=HD_Y z{vD#^3z7n}#Yr;Vh(7AB?;Va4z=mW@zt=*TCV)w%{b%Fp&GvhB3PV$L3N{_V)x(Lg z_X$&(|KII%T3bk1C|TA;%IxkLdV7ZRpLgEL&Q5^>1qu`>P@q780tE^bC{Un4fdT~z c6nF*vAB%#s#wKPLtpET307*qoM6N<$f**b11poj5 literal 0 HcmV?d00001 diff --git a/Common/src/main/resources/assets/hyperlighting/textures/entity/firefly_tail.png b/Common/src/main/resources/assets/hyperlighting/textures/entity/firefly_tail.png new file mode 100644 index 0000000000000000000000000000000000000000..9c8619610b7e4b243565f20a1b2a93fc6235b174 GIT binary patch literal 572 zcmV-C0>k}@P)Px$_DMuRRCt{2*0FBeFc8M^{}~n&kc+Z=jWRgz)jm=lEFNNy^&T%00vX74ASJ6s zp`s`f$nE!AB!Uv5J02;5h=_=Yh=_>Df5zrI-`}1b1DtX(%p9Mz^B|4`tJ|-$<1Nv8 zuJg3t5n~u~K-cwSUy6aYv||c%ZU5^*7H&2Hb+a9V2MCis1FA`9xVpK|ep>-41#rgM zPBGv(U3bpy6lmL?7{lC9i#3~oyJkDieho0$5Q1Nxt3T-DKErGR`r`q}v!7xBgSPF* z^`EQZ$Gzd&%qF1PG=Pt@Z{`Fy+??7O3*v^$K5=dA{q4z5`yF-j$Z7vf-E27@4^*3b zto-ICv0~=n@VehoKWyp09SECy@)+Cvjsad$VwP9U?UzMvlWTyKD!_A@W3*jQJvky+ zNr3@4xIv5+=DGZD$nD`+@%r)%K#COrVbgqCK!0il(6(nTb37FDq^Qj7$=CoZ-L@K|uF+iV$;9!?*l$pDKkqvv$hf3=={#5f0000< KMNUMnLSTaA*b5B+ literal 0 HcmV?d00001 diff --git a/Forge/src/main/java/me/hypherionmc/hyperlighting/client/ForgeClientEventHandler.java b/Forge/src/main/java/me/hypherionmc/hyperlighting/client/ForgeClientEventHandler.java index 0e02839..1f1f20c 100644 --- a/Forge/src/main/java/me/hypherionmc/hyperlighting/client/ForgeClientEventHandler.java +++ b/Forge/src/main/java/me/hypherionmc/hyperlighting/client/ForgeClientEventHandler.java @@ -1,8 +1,10 @@ package me.hypherionmc.hyperlighting.client; +import me.hypherionmc.hyperlighting.client.model.NeonFlyModel; import me.hypherionmc.hyperlighting.client.particles.ParticleRegistryHandler; import net.minecraft.client.Minecraft; import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.client.event.EntityRenderersEvent; import net.minecraftforge.client.event.RegisterParticleProvidersEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; @@ -19,4 +21,9 @@ public class ForgeClientEventHandler { ParticleRegistryHandler.registerParticles(Minecraft.getInstance().particleEngine::register); } + @SubscribeEvent + public static void onRegisterLayers(EntityRenderersEvent.RegisterLayerDefinitions event) { + event.registerLayerDefinition(NeonFlyModel.LAYER_LOCATION, NeonFlyModel::createBodyLayer); + } + } diff --git a/Forge/src/main/java/me/hypherionmc/hyperlighting/common/ForgeCommonHandler.java b/Forge/src/main/java/me/hypherionmc/hyperlighting/common/ForgeCommonHandler.java new file mode 100644 index 0000000..6e5225b --- /dev/null +++ b/Forge/src/main/java/me/hypherionmc/hyperlighting/common/ForgeCommonHandler.java @@ -0,0 +1,21 @@ +package me.hypherionmc.hyperlighting.common; + +import me.hypherionmc.hyperlighting.common.entities.NeonFlyEntity; +import me.hypherionmc.hyperlighting.common.init.HLEntities; +import net.minecraftforge.event.entity.EntityAttributeCreationEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; + +/** + * @author HypherionSA + * @date 05/08/2022 + */ +@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD) +public class ForgeCommonHandler { + + @SubscribeEvent + public static void onAttributeCreate(EntityAttributeCreationEvent event) { + event.put(HLEntities.FIREFLY.get(), NeonFlyEntity.prepareAttributes().build()); + } + +}