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.core.BlockPos;
- 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.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.behavior.BehaviorUtils;
- import net.minecraft.world.entity.ai.control.BodyRotationControl;
- 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.entity.player.Player;
- import net.minecraft.world.item.Items;
- import net.minecraft.world.level.Level;
- import net.minecraft.world.level.LevelReader;
- import net.minecraft.world.level.block.Blocks;
- import net.minecraft.world.level.pathfinder.BlockPathTypes;
- import net.minecraft.world.phys.Vec3;
- import java.util.EnumSet;
- public class SeaOtter extends Animal {
- private static final EntityDataAccessor<Boolean> DATA_FLOATING_ID = SynchedEntityData.defineId(SeaOtter.class, EntityDataSerializers.BOOLEAN);
- private static final EntityDataAccessor<Boolean> DATA_SWIMMING_ID = SynchedEntityData.defineId(SeaOtter.class, EntityDataSerializers.BOOLEAN);
- private boolean needsToSurface;
- private int ticksSinceLastSwamAround;
- private int ticksSpentSwimmingAround;
- public final AnimationState floatingAnimationState = new AnimationState();
- public SeaOtter(EntityType<? extends SeaOtter> type, Level level) {
- super(type, level);
- this.moveControl = new SmoothSwimmingMoveControl(this, 85, 10, 0.02F, 0.1F, true);
- this.lookControl = new SmoothSwimmingLookControl(this, 10);
- this.setPathfindingMalus(BlockPathTypes.WATER, 0.0F);
- this.setMaxUpStep(1.0F);
- }
- @Override
- protected void defineSynchedData() {
- super.defineSynchedData();
- this.entityData.define(DATA_FLOATING_ID, false);
- this.entityData.define(DATA_SWIMMING_ID, false);
- }
- @Override
- protected void registerGoals() {
- this.goalSelector.addGoal(0, new SeaOtter.SwimToSurface(this, 1.0D, 16));
- this.goalSelector.addGoal(1, new SeaOtter.SwimAroundGoal(this, 1.0D, 10));
- this.goalSelector.addGoal(2, new LookAtPlayerGoal(this, Player.class, 6.0F));
- this.goalSelector.addGoal(3, new SeaOtter.FloatGoal());
- this.goalSelector.addGoal(3, new RandomLookAroundGoal(this));
- }
- public static AttributeSupplier.Builder createAttributes() {
- return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 16.0F).add(Attributes.MOVEMENT_SPEED, 1.0D);
- }
- @Override
- public void addAdditionalSaveData(CompoundTag tag) {
- super.addAdditionalSaveData(tag);
- tag.putBoolean("Floating", this.isFloating());
- tag.putBoolean("Swimming", this.isSwimming());
- tag.putBoolean("NeedsToSurface", this.needsToSurface());
- tag.putInt("TicksSinceSwam", this.ticksSinceLastSwamAround);
- tag.putInt("TicksSwimming", this.ticksSpentSwimmingAround);
- }
- @Override
- public void readAdditionalSaveData(CompoundTag tag) {
- super.readAdditionalSaveData(tag);
- this.setFloating(tag.getBoolean("Floating"));
- this.setSwimming(tag.getBoolean("Swimming"));
- this.setNeedsToSurface(tag.getBoolean("NeedsToSurface"));
- this.ticksSinceLastSwamAround = tag.getInt("TicksSinceSwam");
- this.ticksSpentSwimmingAround = tag.getInt("TicksSwimming");
- }
- @Override
- public AgeableMob getBreedOffspring(ServerLevel level, AgeableMob mob) {
- return MysticEntities.SEA_OTTER.get().create(level);
- }
- @Override
- public MobType getMobType() {
- return MobType.WATER;
- }
- @Override
- public int getMaxAirSupply() {
- return 600;
- }
- ///////////////////////////////////////////////////////////////////////////////
- @Override
- public void tick() {
- super.tick();
- if (this.isFloating()) {
- this.wasTouchingWater = true;
- this.setAirSupply(this.getMaxAirSupply());
- this.setDeltaMovement(this.getDeltaMovement().multiply(1.0, 0.0, 1.0));
- }
- if (this.level().isClientSide) {
- this.floatingAnimationState.animateWhen(this.isFloating() && !this.isSwimming(), this.tickCount);
- }
- if (!this.level().isClientSide) {
- if (!this.isSwimming()) {
- ++this.ticksSinceLastSwamAround;
- } else {
- ++this.ticksSpentSwimmingAround;
- }
- }
- }
- @Override
- public void aiStep() {
- super.aiStep();
- if (this.isEffectiveAi() && this.isAlive()) {
- if (this.wantsToFloat() || (this.isUnderWater() && this.getAirSupply() < 200)) {
- this.setNeedsToSurface(true);
- }
- if (this.wantsToSwim() && (!this.needsToSurface() || !this.wantsToFloat())) {
- this.setSwimming(true);
- }
- }
- }
- ///////////////////////////////////////////////////////////////////////////////
- @Override
- protected BodyRotationControl createBodyControl() {
- return new SeaOtter.SeaOtterBodyRotationControl(this);
- }
- public int getMaxHeadXRot() {
- return 30;
- }
- public int getMaxHeadYRot() {
- return 60;
- }
- public int getHeadRotSpeed() {
- return 7;
- }
- ///////////////////////////////////////////////////////////////////////////////
- @Override
- protected PathNavigation createNavigation(Level level) {
- return new WaterBoundPathNavigation(this, level);
- }
- @Override
- 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.9));
- } else {
- super.travel(vec3);
- }
- }
- ///////////////////////////////////////////////////////////////////////////////
- public boolean isFloating() {
- return this.entityData.get(DATA_FLOATING_ID);
- }
- public void setFloating(boolean value) {
- this.entityData.set(DATA_FLOATING_ID, value);
- }
- public boolean wantsToFloat() {
- return this.hasSwamLongEnough();
- }
- ///////////////////////////////////////////////////////////////////////////////
- public boolean isSwimming() {
- return this.entityData.get(DATA_SWIMMING_ID);
- }
- public void setSwimming(boolean value) {
- this.entityData.set(DATA_SWIMMING_ID, value);
- }
- public boolean wantsToSwim() {
- return this.ticksSinceLastSwamAround > 800;
- }
- public boolean hasSwamLongEnough() {
- return this.ticksSpentSwimmingAround > 600;
- }
- public void resetTicksSinceLastSwimAround() {
- this.ticksSinceLastSwamAround = 0;
- }
- public void resetTicksSpentSwimmingAround() {
- this.ticksSpentSwimmingAround = 0;
- }
- ///////////////////////////////////////////////////////////////////////////////
- public boolean needsToSurface() {
- return this.needsToSurface;
- }
- public void setNeedsToSurface(boolean value) {
- this.needsToSurface = value;
- }
- ///////////////////////////////////////////////////////////////////////////////
- public InteractionResult mobInteract(Player player, InteractionHand hand) {
- this.setFloating(player.getItemInHand(hand).is(Items.STICK));
- this.setSwimming(!player.getItemInHand(hand).is(Items.STICK));
- return super.mobInteract(player, hand);
- }
- ///////////////////////////////////////////////////////////////////////////////
- // 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 false;
- } else if (SeaOtter.this.needsToSurface()) {
- return false;
- } else if (SeaOtter.this.wantsToFloat()) {
- return false;
- } else {
- return super.canUse();
- }
- }
- public boolean canContinueToUse() {
- return !SeaOtter.this.hasSwamLongEnough() && super.canContinueToUse();
- }
- public void start() {
- SeaOtter.this.setSwimming(true);
- super.start();
- }
- public void stop() {
- super.stop();
- }
- protected Vec3 getPosition() {
- return BehaviorUtils.getRandomSwimmablePos(this.mob, 10, 7);
- }
- }
- class SwimToSurface extends MoveToBlockGoal {
- public SwimToSurface(PathfinderMob mob, double speed, int range) {
- super(mob, speed, range);
- this.setFlags(EnumSet.of(Flag.MOVE, Flag.LOOK));
- }
- public boolean canUse() {
- return SeaOtter.this.needsToSurface() && super.canUse();
- }
- public void start() {
- System.out.println("swimming to surface");
- super.start();
- }
- public void stop() {
- SeaOtter.this.setNeedsToSurface(false);
- SeaOtter.this.resetTicksSinceLastSwimAround();
- SeaOtter.this.resetTicksSpentSwimmingAround();
- SeaOtter.this.getNavigation().stop();
- }
- protected boolean isValidTarget(LevelReader level, BlockPos pos) {
- return level.getBlockState(pos).is(Blocks.WATER) && level.getBlockState(pos.above()).isAir();
- }
- public void tick() {
- super.tick();
- if (this.isReachedTarget()) {
- this.stop();
- }
- }
- }
- class FloatGoal extends Goal {
- public FloatGoal() {
- this.setFlags(EnumSet.of(Flag.MOVE));
- }
- public boolean canUse() {
- return SeaOtter.this.wantsToFloat();
- }
- public boolean canContinueToUse() {
- return !SeaOtter.this.wantsToSwim(); // or is hungry/wants to search for food.
- }
- public void start() {
- SeaOtter.this.setFloating(true);
- SeaOtter.this.setSwimming(false);
- }
- public void stop() {
- SeaOtter.this.setFloating(false);
- SeaOtter.this.setSwimming(true);
- }
- }
- ///////////////////////////////////////////////////////////////////////////////
- // TODO: CONTROLS
- private class SeaOtterBodyRotationControl extends BodyRotationControl {
- public SeaOtterBodyRotationControl(Mob mob) {
- super(mob);
- }
- public void clientTick() {
- if (!SeaOtter.this.isFloating()) {
- super.clientTick();
- }
- }
- }
- ///////////////////////////////////////////////////////////////////////////////
- // TODO: TYPES
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement