237 lines
8.1 KiB
Java
237 lines
8.1 KiB
Java
package com.cursedcauldron.wildbackport.common.entities;
|
|
|
|
import com.cursedcauldron.wildbackport.client.registry.WBSoundEvents;
|
|
import com.cursedcauldron.wildbackport.common.entities.brain.TadpoleBrain;
|
|
import com.cursedcauldron.wildbackport.common.registry.WBItems;
|
|
import com.cursedcauldron.wildbackport.common.registry.entity.WBEntities;
|
|
import com.google.common.collect.ImmutableList;
|
|
import com.mojang.serialization.Dynamic;
|
|
import net.minecraft.core.particles.ParticleTypes;
|
|
import net.minecraft.nbt.CompoundTag;
|
|
import net.minecraft.network.protocol.game.DebugPackets;
|
|
import net.minecraft.server.level.ServerLevel;
|
|
import net.minecraft.sounds.SoundEvent;
|
|
import net.minecraft.world.InteractionHand;
|
|
import net.minecraft.world.InteractionResult;
|
|
import net.minecraft.world.damagesource.DamageSource;
|
|
import net.minecraft.world.entity.EntityType;
|
|
import net.minecraft.world.entity.Mob;
|
|
import net.minecraft.world.entity.MobSpawnType;
|
|
import net.minecraft.world.entity.ai.Brain;
|
|
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.memory.MemoryModuleType;
|
|
import net.minecraft.world.entity.ai.navigation.PathNavigation;
|
|
import net.minecraft.world.entity.ai.navigation.WaterBoundPathNavigation;
|
|
import net.minecraft.world.entity.ai.sensing.Sensor;
|
|
import net.minecraft.world.entity.ai.sensing.SensorType;
|
|
import net.minecraft.world.entity.animal.AbstractFish;
|
|
import net.minecraft.world.entity.animal.Bucketable;
|
|
import net.minecraft.world.entity.player.Player;
|
|
import net.minecraft.world.item.ItemStack;
|
|
import net.minecraft.world.level.Level;
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
//<>
|
|
|
|
public class Tadpole extends AbstractFish {
|
|
public static final int MAX_TADPOLE_AGE = Math.abs(-24000);
|
|
public static final float WIDTH = 0.4F;
|
|
public static final float HEIGHT = 0.3F;
|
|
private int age;
|
|
protected static final ImmutableList<SensorType<? extends Sensor<? super Tadpole>>> SENSORS = ImmutableList.of(SensorType.NEAREST_LIVING_ENTITIES, SensorType.NEAREST_PLAYERS, SensorType.HURT_BY);
|
|
protected static final ImmutableList<MemoryModuleType<?>> MEMORIES = ImmutableList.of(MemoryModuleType.LOOK_TARGET, MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, MemoryModuleType.WALK_TARGET, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryModuleType.PATH, MemoryModuleType.NEAREST_VISIBLE_ADULT);
|
|
|
|
public Tadpole(EntityType<? extends AbstractFish> type, Level level) {
|
|
super(type, level);
|
|
this.moveControl = new SmoothSwimmingMoveControl(this, 85, 10, 0.02F, 0.1F, true);
|
|
this.lookControl = new SmoothSwimmingLookControl(this, 10);
|
|
}
|
|
|
|
@Override
|
|
protected PathNavigation createNavigation(Level world) {
|
|
return new WaterBoundPathNavigation(this, world);
|
|
}
|
|
|
|
@Override
|
|
protected Brain.Provider<Tadpole> brainProvider() {
|
|
return Brain.provider(MEMORIES, SENSORS);
|
|
}
|
|
|
|
@Override
|
|
protected Brain<?> makeBrain(Dynamic<?> dynamic) {
|
|
return TadpoleBrain.create(this.brainProvider().makeBrain(dynamic));
|
|
}
|
|
|
|
@Override @SuppressWarnings("unchecked")
|
|
public Brain<Tadpole> getBrain() {
|
|
return (Brain<Tadpole>) super.getBrain();
|
|
}
|
|
|
|
@Override
|
|
protected SoundEvent getFlopSound() {
|
|
return WBSoundEvents.TADPOLE_FLOP;
|
|
}
|
|
|
|
@Override
|
|
protected void customServerAiStep() {
|
|
this.level.getProfiler().push("tadpoleBrain");
|
|
this.getBrain().tick((ServerLevel)this.level, this);
|
|
this.level.getProfiler().pop();
|
|
this.level.getProfiler().push("tadpoleActivityUpdate");
|
|
TadpoleBrain.updateActivities(this);
|
|
this.level.getProfiler().pop();
|
|
super.customServerAiStep();
|
|
}
|
|
|
|
public static AttributeSupplier.Builder createAttributes() {
|
|
return Mob.createMobAttributes().add(Attributes.MOVEMENT_SPEED, 1.0D).add(Attributes.MAX_HEALTH, 6.0D);
|
|
}
|
|
|
|
@Override
|
|
public void aiStep() {
|
|
super.aiStep();
|
|
if (!this.level.isClientSide()) {
|
|
this.setAge(this.age + 1);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void addAdditionalSaveData(CompoundTag nbt) {
|
|
super.addAdditionalSaveData(nbt);
|
|
nbt.putInt("Age", this.age);
|
|
}
|
|
|
|
@Override
|
|
public void readAdditionalSaveData(CompoundTag nbt) {
|
|
super.readAdditionalSaveData(nbt);
|
|
this.setAge(nbt.getInt("Age"));
|
|
}
|
|
|
|
@Override @Nullable
|
|
protected SoundEvent getAmbientSound() {
|
|
return null;
|
|
}
|
|
|
|
@Override @Nullable
|
|
protected SoundEvent getHurtSound(DamageSource source) {
|
|
return WBSoundEvents.TADPOLE_HURT;
|
|
}
|
|
|
|
@Override @Nullable
|
|
protected SoundEvent getDeathSound() {
|
|
return WBSoundEvents.TADPOLE_DEATH;
|
|
}
|
|
|
|
@Override
|
|
protected InteractionResult mobInteract(Player player, InteractionHand hand) {
|
|
ItemStack stack = player.getItemInHand(hand);
|
|
if (this.isSlimeBall(stack)) {
|
|
this.eatSlimeBall(player, stack);
|
|
return InteractionResult.sidedSuccess(this.level.isClientSide());
|
|
} else {
|
|
return Bucketable.bucketMobPickup(player, hand, this).orElse(super.mobInteract(player, hand));
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected void sendDebugPackets() {
|
|
super.sendDebugPackets();
|
|
DebugPackets.sendEntityBrain(this);
|
|
}
|
|
|
|
@Override
|
|
public boolean fromBucket() {
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public void setFromBucket(boolean fromBucket) {}
|
|
|
|
@Override
|
|
public void saveToBucketTag(ItemStack stack) {
|
|
Bucketable.saveDefaultDataToBucketTag(this, stack);
|
|
CompoundTag nbtCompound = stack.getOrCreateTag();
|
|
nbtCompound.putInt("Age", this.getAge());
|
|
}
|
|
|
|
@Override
|
|
public void loadFromBucketTag(CompoundTag nbt) {
|
|
Bucketable.loadDefaultDataFromBucketTag(this, nbt);
|
|
if (nbt.contains("Age")) {
|
|
this.setAge(nbt.getInt("Age"));
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public ItemStack getBucketItemStack() {
|
|
return new ItemStack(WBItems.TADPOLE_BUCKET.get());
|
|
}
|
|
|
|
@Override
|
|
public SoundEvent getPickupSound() {
|
|
return WBSoundEvents.BUCKED_FILL_TADPOLE;
|
|
}
|
|
|
|
private boolean isSlimeBall(ItemStack stack) {
|
|
return Frog.FOOD.test(stack);
|
|
}
|
|
|
|
private void eatSlimeBall(Player player, ItemStack stack) {
|
|
this.decrementItem(player, stack);
|
|
this.increaseAge((int)((float)(this.getTicksUntilGrowth() / 20) * 0.1F));
|
|
this.level.addParticle(ParticleTypes.HAPPY_VILLAGER, this.getRandomX(1.0D), this.getRandomY() + 0.5D, this.getRandomZ(1.0D), 0.0D, 0.0D, 0.0D);
|
|
}
|
|
|
|
private void decrementItem(Player player, ItemStack stack) {
|
|
if (!player.getAbilities().instabuild) {
|
|
stack.shrink(1);
|
|
}
|
|
}
|
|
|
|
private int getAge() {
|
|
return this.age;
|
|
}
|
|
|
|
private void increaseAge(int seconds) {
|
|
this.setAge(this.age + seconds * 20);
|
|
}
|
|
|
|
private void setAge(int age) {
|
|
this.age = age;
|
|
if (this.age >= MAX_TADPOLE_AGE) {
|
|
this.growUp();
|
|
}
|
|
}
|
|
|
|
private void growUp() {
|
|
if (this.level instanceof ServerLevel server) {
|
|
Frog frog = WBEntities.FROG.get().create(this.level);
|
|
if (frog == null) return;
|
|
|
|
frog.moveTo(this.getX(), this.getY(), this.getZ(), this.getYRot(), this.getXRot());
|
|
frog.finalizeSpawn(server, this.level.getCurrentDifficultyAt(frog.blockPosition()), MobSpawnType.CONVERSION, null, null);
|
|
frog.setNoAi(this.isNoAi());
|
|
if (this.hasCustomName()) {
|
|
frog.setCustomName(this.getCustomName());
|
|
frog.setCustomNameVisible(this.isCustomNameVisible());
|
|
}
|
|
|
|
frog.setPersistenceRequired();
|
|
this.playSound(WBSoundEvents.TADPOLE_GROW_UP, 0.15F, 1.0F);
|
|
server.addFreshEntityWithPassengers(frog);
|
|
this.discard();
|
|
}
|
|
}
|
|
|
|
private int getTicksUntilGrowth() {
|
|
return Math.max(0, MAX_TADPOLE_AGE - this.age);
|
|
}
|
|
|
|
@Override
|
|
protected boolean shouldDropExperience() {
|
|
return false;
|
|
}
|
|
} |