Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.mysticsbiomes.common.entity.animal;
- import com.mysticsbiomes.init.MysticEntities;
- import net.minecraft.nbt.CompoundTag;
- import net.minecraft.network.syncher.EntityDataAccessor;
- import net.minecraft.network.syncher.EntityDataSerializers;
- import net.minecraft.network.syncher.SynchedEntityData;
- import net.minecraft.server.level.ServerLevel;
- import net.minecraft.util.ByIdMap;
- import net.minecraft.util.RandomSource;
- import net.minecraft.util.StringRepresentable;
- import net.minecraft.world.InteractionHand;
- import net.minecraft.world.InteractionResult;
- 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.LookControl;
- import net.minecraft.world.entity.ai.control.MoveControl;
- import net.minecraft.world.entity.ai.goal.*;
- import net.minecraft.world.entity.animal.*;
- import net.minecraft.world.entity.monster.Monster;
- import net.minecraft.world.entity.player.Player;
- import net.minecraft.world.item.Items;
- import net.minecraft.world.item.crafting.Ingredient;
- import net.minecraft.world.level.Level;
- import net.minecraft.world.level.block.Blocks;
- import javax.annotation.Nullable;
- import java.util.EnumSet;
- import java.util.function.IntFunction;
- /**
- * Red Pandas spawn in the Bamboo Blossom Forest, scouting out bamboo, and stealing items.
- */
- public class RedPanda extends Animal {
- private static final EntityDataAccessor<Byte> MAIN_GENE_ID = SynchedEntityData.defineId(RedPanda.class, EntityDataSerializers.BYTE);
- private static final EntityDataAccessor<Byte> HIDDEN_GENE_ID = SynchedEntityData.defineId(RedPanda.class, EntityDataSerializers.BYTE);
- private static final EntityDataAccessor<Byte> DATA_FLAGS_ID = SynchedEntityData.defineId(RedPanda.class, EntityDataSerializers.BYTE);
- private int ticksSinceLastTimeStanding;
- public final AnimationState sleepingAnimationState = new AnimationState();
- public final AnimationState standingPoseAnimationState = new AnimationState();
- public RedPanda(EntityType<? extends RedPanda> type, Level level) {
- super(type, level);
- this.moveControl = new MoveControl(this);
- this.lookControl = new LookControl(this);
- }
- protected void defineSynchedData() {
- super.defineSynchedData();
- this.entityData.define(MAIN_GENE_ID, (byte)0);
- this.entityData.define(HIDDEN_GENE_ID, (byte)0);
- this.entityData.define(DATA_FLAGS_ID, (byte)0);
- }
- protected void registerGoals() {
- this.goalSelector.addGoal(0, new FloatGoal(this));
- this.goalSelector.addGoal(0, new RedPanda.StandUpGoal());
- this.goalSelector.addGoal(1, new PanicGoal(this, 2.0));
- this.goalSelector.addGoal(1, new BreedGoal(this, 1.0));
- this.goalSelector.addGoal(2, new RedPanda.AttackGoal(this, 1.2F, true));
- this.goalSelector.addGoal(3, new TemptGoal(this, 1.0, Ingredient.of(Blocks.BAMBOO.asItem()), false));
- this.goalSelector.addGoal(4, new AvoidEntityGoal<>(this, Monster.class, 4.0F, 2.0, 2.0));
- this.goalSelector.addGoal(5, new LookAtPlayerGoal(this, Player.class, 6.0F));
- this.goalSelector.addGoal(6, new RandomLookAroundGoal(this));
- this.goalSelector.addGoal(7, new RedPanda.SleepGoal());
- this.goalSelector.addGoal(8, new FollowParentGoal(this, 1.25));
- this.goalSelector.addGoal(9, new WaterAvoidingRandomStrollGoal(this, 1.0));
- }
- public static AttributeSupplier.Builder createAttributes() {
- return Mob.createMobAttributes().add(Attributes.MOVEMENT_SPEED, 1.0F).add(Attributes.MAX_HEALTH, 10.0D).add(Attributes.FOLLOW_RANGE, 32.0D).add(Attributes.ATTACK_DAMAGE, 8.0D);
- }
- public void setAttributes() {
- if (this.isEnergetic()) {
- this.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(1.1F);
- }
- if (this.isLazy()) {
- this.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.1F);
- }
- }
- public RedPanda getBreedOffspring(ServerLevel level, AgeableMob mob) {
- RedPanda redPanda = MysticEntities.RED_PANDA.get().create(level);
- if (redPanda != null) {
- if (mob instanceof RedPanda parent) {
- redPanda.setGeneFromParents(this, parent);
- }
- redPanda.setAttributes();
- }
- return redPanda;
- }
- public EntityDimensions getDimensions(Pose pose) {
- return pose == Pose.STANDING ? EntityDimensions.scalable(0.5F, 1.125F) : super.getDimensions(pose);
- }
- protected float getStandingEyeHeight(Pose pose, EntityDimensions dimensions) {
- return pose == Pose.STANDING ? 1.0F : super.getStandingEyeHeight(pose, dimensions);
- }
- /////////////////////////////////////////////////////////////////////////////////
- public void addAdditionalSaveData(CompoundTag tag) {
- super.addAdditionalSaveData(tag);
- tag.putBoolean("IsSleeping", this.isSleeping());
- tag.putString("MainGene", this.getMainGene().getSerializedName());
- tag.putString("HiddenGene", this.getHiddenGene().getSerializedName());
- }
- public void readAdditionalSaveData(CompoundTag tag) {
- super.readAdditionalSaveData(tag);
- this.setSleeping(tag.getBoolean("IsSleeping"));
- this.setMainGene(Gene.byName(tag.getString("MainGene")));
- this.setHiddenGene(Gene.byName(tag.getString("HiddenGene")));
- }
- /////////////////////////////////////////////////////////////////////////////////
- public Gene getMainGene() {
- return Gene.byId(this.entityData.get(MAIN_GENE_ID));
- }
- public void setMainGene(Gene gene) {
- if (gene.getId() > 6) {
- gene = Gene.getRandom(this.random);
- }
- this.entityData.set(MAIN_GENE_ID, (byte)gene.getId());
- }
- public Gene getHiddenGene() {
- return Gene.byId(this.entityData.get(HIDDEN_GENE_ID));
- }
- public void setHiddenGene(Gene gene) {
- if (gene.getId() > 6) {
- gene = Gene.getRandom(this.random);
- }
- this.entityData.set(HIDDEN_GENE_ID, (byte)gene.getId());
- }
- public void setGeneFromParents(RedPanda parent, @Nullable RedPanda parent2) {
- if (parent2 == null) {
- if (this.random.nextBoolean()) {
- this.setMainGene(parent.getOneOfGenesRandomly());
- this.setHiddenGene(Gene.getRandom(this.random));
- } else {
- this.setMainGene(Gene.getRandom(this.random));
- this.setHiddenGene(parent.getOneOfGenesRandomly());
- }
- } else if (this.random.nextBoolean()) {
- this.setMainGene(parent.getOneOfGenesRandomly());
- this.setHiddenGene(parent2.getOneOfGenesRandomly());
- } else {
- this.setMainGene(parent2.getOneOfGenesRandomly());
- this.setHiddenGene(parent.getOneOfGenesRandomly());
- }
- if (this.random.nextInt(32) == 0) {
- this.setMainGene(Gene.getRandom(this.random));
- }
- if (this.random.nextInt(32) == 0) {
- this.setHiddenGene(Gene.getRandom(this.random));
- }
- }
- private Gene getOneOfGenesRandomly() {
- return this.random.nextBoolean() ? this.getMainGene() : this.getHiddenGene();
- }
- public Gene getVariant() {
- return Gene.getVariantFromGenes(this.getMainGene(), this.getHiddenGene());
- }
- public boolean isEnergetic() {
- return this.getVariant() == Gene.ENERGETIC;
- }
- public boolean isLazy() {
- return this.getVariant() == Gene.LAZY;
- }
- public boolean isCurious() {
- return this.getVariant() == Gene.CURIOUS;
- }
- public boolean isClingy() {
- return this.getVariant() == Gene.CLINGY;
- }
- public boolean isShy() {
- return this.getVariant() == Gene.SHY;
- }
- public boolean isMischievous() {
- return this.getVariant() == Gene.MISCHIEVOUS;
- }
- public boolean isVelvet() {
- return this.getVariant() == Gene.VELVET;
- }
- /////////////////////////////////////////////////////////////////////////////////
- private boolean getFlag(int value) {
- return (this.entityData.get(DATA_FLAGS_ID) & value) != 0;
- }
- private void setFlag(int value, boolean b) {
- if (b) {
- this.entityData.set(DATA_FLAGS_ID, (byte)(this.entityData.get(DATA_FLAGS_ID) | value));
- } else {
- this.entityData.set(DATA_FLAGS_ID, (byte)(this.entityData.get(DATA_FLAGS_ID) & ~value));
- }
- }
- public boolean isSleeping() {
- return this.getFlag(4);
- }
- public void setSleeping(boolean sleeping) {
- this.setPose(sleeping ? Pose.SLEEPING : Pose.SITTING);
- this.setFlag(4, sleeping);
- }
- public boolean isStanding() {
- return this.getFlag(8);
- }
- public void setStanding(boolean standing) {
- this.setPose(standing ? Pose.STANDING : Pose.SITTING);
- this.setFlag(8, standing);
- }
- /////////////////////////////////////////////////////////////////////////////////
- public void tick() {
- super.tick();
- if (this.isStanding()) {
- this.setPose(this.walkAnimation.isMoving() ? Pose.STANDING : Pose.SITTING);
- }
- if (this.level().isClientSide()) {
- this.sleepingAnimationState.animateWhen(this.isSleeping(), this.tickCount);
- }
- }
- public void aiStep() {
- super.aiStep();
- if (this.isSleeping() || this.isImmobile()) {
- this.xxa = 0.0F;
- this.zza = 0.0F;
- }
- }
- protected void customServerAiStep() {
- super.customServerAiStep();
- if (!this.isStanding()) {
- ++this.ticksSinceLastTimeStanding;
- }
- }
- /////////////////////////////////////////////////////////////////////////////////
- public InteractionResult mobInteract(Player player, InteractionHand hand) {
- this.setSleeping(player.getMainHandItem().is(Items.STICK));
- this.setStanding(player.getMainHandItem().is(Items.PINK_PETALS));
- return super.mobInteract(player, hand);
- }
- /////////////////////////////////////////////////////////////////////////////////
- /**
- * Those with clingy trait will search for other red pandas nearby before falling asleep.
- * Those with lazy trait will sleep longer than others.
- * Those with energetic trait will rarely sleep.
- */
- class SleepGoal extends Goal {
- public SleepGoal() {
- this.setFlags(EnumSet.of(Flag.MOVE, Flag.LOOK, Flag.JUMP));
- }
- public boolean canUse() {
- return this.canSleep();
- }
- public void start() {
- RedPanda.this.setSleeping(true);
- }
- public void stop() {
- RedPanda.this.setSleeping(false);
- }
- private boolean canSleep() {
- return RedPanda.this.level().isNight();
- }
- }
- /**
- * Those with lazy trait will never stand up.
- * Those with energetic trait tend to stand up more often.
- */
- class StandUpGoal extends Goal {
- private int remainingTicksStanding;
- public boolean canUse() {
- return RedPanda.this.ticksSinceLastTimeStanding > 200 && !RedPanda.this.isStanding();
- }
- public boolean canContinueToUse() {
- return this.remainingTicksStanding > 0;
- }
- public void start() {
- RedPanda.this.setStanding(true);
- this.remainingTicksStanding = RedPanda.this.random.nextInt(100) + 200;
- }
- public void stop() {
- RedPanda.this.setStanding(false);
- RedPanda.this.ticksSinceLastTimeStanding = 0;
- }
- public void tick() {
- --this.remainingTicksStanding;
- }
- }
- class AttackGoal extends MeleeAttackGoal {
- public AttackGoal(PathfinderMob mob, double speed, boolean followIfNotSeen) {
- super(mob, speed, followIfNotSeen);
- }
- public boolean canUse() {
- return super.canUse() && !RedPanda.this.isLazy() && !RedPanda.this.isShy();
- }
- }
- /**
- * normal - base for all red pandas, sleeps at night, likes to be alone, etc.
- * curious - looks at everything, interacts with others, picks up items.
- * clingy - will sleep next to other red pandas, does not leave others alone, will sleep in bed with trusted players.
- * energetic - sleeps less, runs more often, wakes other red pandas up.
- * lazy - sleeps more, slower, is less territorial.
- * shy - avoids untrusted players, sleeps directly under leaves, light sleeper.
- * mischievous - steals items off players, wakes other red pandas from sleeping, scares shy traits.
- * velvet - normal, just dark red like a red velvet cupcake.
- *
- * territorial - attacks untrusted players who approach too fast.
- * loyal - picks up and gives player items they have dropped.
- */
- public enum Gene implements StringRepresentable {
- NORMAL(0, "normal", false),
- ENERGETIC(1, "energetic", false),
- LAZY(2, "lazy", false),
- CURIOUS(3, "curious", false),
- CLINGY(4, "clingy", false),
- SHY(5, "shy", false),
- MISCHIEVOUS(6, "mischievous", false),
- VELVET(7, "velvet", true);
- private static final IntFunction<Gene> BY_ID = ByIdMap.continuous(Gene::getId, values(), ByIdMap.OutOfBoundsStrategy.ZERO);
- private final int id;
- private final String name;
- private final boolean isRecessive;
- Gene(int id, String type, boolean recessive) {
- this.id = id;
- this.name = type;
- this.isRecessive = recessive;
- }
- public int getId() {
- return this.id;
- }
- public String getSerializedName() {
- return this.name;
- }
- public boolean isRecessive() {
- return this.isRecessive;
- }
- static Gene getVariantFromGenes(Gene gene1, Gene gene2) {
- if (gene1.isRecessive()) {
- return gene1 == gene2 ? gene1 : NORMAL;
- } else {
- return gene1;
- }
- }
- public static Gene byId(int id) {
- return BY_ID.apply(id);
- }
- public static Gene byName(String name) {
- return StringRepresentable.fromEnum(Gene::values).byName(name, NORMAL);
- }
- public static Gene getRandom(RandomSource source) {
- int i = source.nextInt(13);
- if (i == 0) {
- return ENERGETIC;
- } else if (i == 1) {
- return LAZY;
- } else if (i == 2) {
- return CURIOUS;
- } else if (i == 4) {
- return CLINGY;
- } else if (i == 6) {
- return SHY;
- } else if (i == 7) {
- return MISCHIEVOUS;
- } else {
- return i < 9 ? VELVET : NORMAL;
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement