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 com.mysticsbiomes.init.MysticItems;
- 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.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.SmoothSwimmingLookControl;
- import net.minecraft.world.entity.ai.control.SmoothSwimmingMoveControl;
- import net.minecraft.world.entity.ai.goal.*;
- import net.minecraft.world.entity.ai.navigation.PathNavigation;
- import net.minecraft.world.entity.ai.navigation.WaterBoundPathNavigation;
- import net.minecraft.world.entity.animal.Animal;
- import net.minecraft.world.item.crafting.Ingredient;
- import net.minecraft.world.level.Level;
- import net.minecraft.world.level.pathfinder.BlockPathTypes;
- import net.minecraft.world.level.pathfinder.PathFinder;
- import net.minecraft.world.level.pathfinder.SwimNodeEvaluator;
- import net.minecraft.world.phys.Vec3;
- /**
- * swims on the surface.
- * only swims underwater fully when playing or searching for food.
- */
- public class SeaOtter extends Animal {
- private static final EntityDataAccessor<Boolean> DATA_FLOATING_ID = SynchedEntityData.defineId(SeaOtter.class, EntityDataSerializers.BOOLEAN);
- private int ticksSinceLastSwim;
- public SeaOtter(EntityType<? extends SeaOtter> type, Level level) {
- super(type, level);
- this.setPathfindingMalus(BlockPathTypes.WATER, 0.0F);
- this.moveControl = new SmoothSwimmingMoveControl(this, 85, 10, 0.02F, 0.1F, true);
- this.lookControl = new SmoothSwimmingLookControl(this, 10);
- }
- protected void defineSynchedData() {
- super.defineSynchedData();
- this.entityData.define(DATA_FLOATING_ID, false);
- }
- protected void registerGoals() {
- this.goalSelector.addGoal(0, new PanicGoal(this, 2.0F));
- this.goalSelector.addGoal(1, new TemptGoal(this, 1.0F, Ingredient.of(MysticItems.MILKWEED.get()), false));
- this.goalSelector.addGoal(2, new SeaOtter.SwimAroundGoal(this, 1.0D, 10));
- this.goalSelector.addGoal(3, new SeaOtter.LookAroundGoal(this));
- }
- public static AttributeSupplier.Builder createAttributes() {
- return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 16.0F).add(Attributes.MOVEMENT_SPEED, 1.0D);
- }
- public void addAdditionalSaveData(CompoundTag tag) {
- super.addAdditionalSaveData(tag);
- tag.putBoolean("Floating", this.isFloating());
- tag.putInt("TicksSinceSwam", this.ticksSinceLastSwim);
- }
- public void readAdditionalSaveData(CompoundTag tag) {
- super.readAdditionalSaveData(tag);
- this.setFloating(tag.getBoolean("Floating"));
- this.ticksSinceLastSwim = tag.getInt("TicksSinceSwam");
- }
- public AgeableMob getBreedOffspring(ServerLevel level, AgeableMob mob) {
- return MysticEntities.SEA_OTTER.get().create(level);
- }
- public MobType getMobType() {
- return MobType.WATER;
- }
- // TICKS & A.I.
- public void tick() {
- super.tick();
- }
- public void aiStep() {
- super.aiStep();
- }
- // NAVIGATION & MOVEMENT
- protected PathNavigation createNavigation(Level level) {
- return new SeaOtter.SeaOtterPathNavigation(this, level);
- }
- public void travel(Vec3 vec3) {
- if (this.isEffectiveAi() && this.isInWater()) {
- this.moveRelative(this.getSpeed(), vec3);
- this.move(MoverType.SELF, this.getDeltaMovement());
- this.setDeltaMovement(this.getDeltaMovement().scale(0.9D));
- } else {
- super.travel(vec3);
- }
- }
- public int getMaxAirSupply() {
- return 6000;
- }
- /**
- * @return typically true unless the sea otter is searching for food or needs to swim a long distance.
- */
- public boolean isFloating() {
- return this.entityData.get(DATA_FLOATING_ID);
- }
- public void setFloating(boolean value) {
- this.entityData.set(DATA_FLOATING_ID, value);
- }
- // TODO: GOALS
- class SwimAroundGoal extends RandomSwimmingGoal {
- public SwimAroundGoal(PathfinderMob mob, double speed, int interval) {
- super(mob, speed, interval);
- }
- public boolean canUse() {
- if (!SeaOtter.this.isFloating()) {
- return super.canUse();
- } else {
- return false;
- }
- }
- public boolean canContinueToUse() {
- if (!SeaOtter.this.isFloating()) {
- return super.canContinueToUse();
- } else {
- return false;
- }
- }
- }
- class LookAroundGoal extends RandomLookAroundGoal {
- public LookAroundGoal(Mob mob) {
- super(mob);
- }
- public boolean canUse() {
- return super.canUse() && !SeaOtter.this.isFloating();
- }
- public boolean canContinueToUse() {
- return super.canContinueToUse() && !SeaOtter.this.isFloating();
- }
- }
- // TODO: NAVIGATION & CONTROLS
- static class SeaOtterPathNavigation extends WaterBoundPathNavigation {
- public SeaOtterPathNavigation(Mob mob, Level level) {
- super(mob, level);
- }
- protected PathFinder createPathFinder(int nodes) {
- this.nodeEvaluator = new SwimNodeEvaluator(true);
- return new PathFinder(this.nodeEvaluator, nodes);
- }
- protected boolean canUpdatePath() {
- return true;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement