Initial work on NeonFlies
This commit is contained in:
@@ -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<T extends Entity> extends EntityModel<T> {
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
@@ -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<NeonFlyEntity, NeonFlyModel<NeonFlyEntity>> {
|
||||
|
||||
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<T extends Entity, M extends NeonFlyModel<T>> extends EyesLayer<T, M> {
|
||||
private static final RenderType FIREFLY_TAIL = RenderType.eyes(new ResourceLocation(Constants.MOD_ID, "textures/entity/firefly_tail.png"));
|
||||
|
||||
public FireflyTailLayer(RenderLayerParent<T, M> 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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -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<? extends Animal> 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<NeonFlyEntity> 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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -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<? extends LivingEntity> findType;
|
||||
|
||||
public FindSimilarEntityGoal(PathfinderMob pMob, double pSpeedModifier, int pSearchRange, Class<? extends LivingEntity> 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;
|
||||
}
|
||||
|
||||
}
|
@@ -17,6 +17,8 @@ public class CommonRegistration {
|
||||
HLParticles.loadAll();
|
||||
HLBlocks.loadAll();
|
||||
HLItems.loadAll();
|
||||
HLEntities.loadAll();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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<EntityType<?>> ENTITIES = RegistrationProvider.get(Registry.ENTITY_TYPE, Constants.MOD_ID);
|
||||
|
||||
public static final RegistryObject<EntityType<NeonFlyEntity>> FIREFLY = ENTITIES.register("firefly", () -> EntityType.Builder.of(NeonFlyEntity::new, MobCategory.AMBIENT)
|
||||
.sized(1f, 1f)
|
||||
.clientTrackingRange(8)
|
||||
.build("firefly"));
|
||||
|
||||
public static void loadAll() {}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
Binary file not shown.
After Width: | Height: | Size: 572 B |
Reference in New Issue
Block a user