package net.tiagom.archeologyanddinos.entity.custom;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.AgeableMob;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.ai.goal.FloatGoal;
import net.minecraft.world.entity.ai.goal.MeleeAttackGoal;
import net.minecraft.world.entity.ai.goal.RandomLookAroundGoal;
import net.minecraft.world.entity.ai.goal.WaterAvoidingRandomStrollGoal;
import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal;
import net.minecraft.world.entity.animal.Animal;
import net.minecraft.world.entity.animal.Chicken;
import net.minecraft.world.entity.animal.Cow;
import net.minecraft.world.entity.animal.horse.Llama;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.tiagom.archeologyanddinos.entity.DinoEntities;
import net.tiagom.archeologyanddinos.entity.ai.goal.TrexSleepAtNightGoal;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import software.bernie.geckolib.animatable.GeoEntity;
import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache;
import software.bernie.geckolib.core.animation.AnimatableManager;
import software.bernie.geckolib.core.animation.AnimationController;
import software.bernie.geckolib.core.animation.AnimationState;
import software.bernie.geckolib.core.animation.RawAnimation;
import software.bernie.geckolib.core.object.PlayState;
import software.bernie.geckolib.util.GeckoLibUtil;
public class TrexEntity extends Animal implements GeoEntity {
private final AnimatableInstanceCache geoCache = GeckoLibUtil.createInstanceCache(this);
public static final RawAnimation TREX_WALK = RawAnimation.begin().thenLoop("animation.trex.walk");
public static final RawAnimation TREX_IDLE = RawAnimation.begin().thenLoop("animation.trex.idle");
public static final RawAnimation TREX_ATTACK = RawAnimation.begin().thenPlay("animation.trex.attack");
public static final RawAnimation TREX_REST = RawAnimation.begin().thenPlayAndHold("animation.trex.rest");
private static final long TIME_UNTIL_REST = 42000;
private long lastMove = System.currentTimeMillis();
public TrexEntity(EntityType<? extends Animal> pEntityType, Level pLevel) {
super(pEntityType, pLevel);
}
public static AttributeSupplier setAttributes() {
return Animal.createMobAttributes()
.add(Attributes.MAX_HEALTH, 100D)
.add(Attributes.ATTACK_DAMAGE, 4.0f)
.add(Attributes.ATTACK_SPEED, 1.0f)
.add(Attributes.MOVEMENT_SPEED, 0.5f).build();
}
@Override
protected void registerGoals() {
this.goalSelector.addGoal(1, new FloatGoal(this));
this.goalSelector.addGoal(1, new MeleeAttackGoal(this, 1.2D, false));
this.goalSelector.addGoal(3, new TrexSleepAtNightGoal(this));
this.goalSelector.addGoal(4, new WaterAvoidingRandomStrollGoal(this, 1.0D));
this.goalSelector.addGoal(4, new RandomLookAroundGoal(this));
this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true));
this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Cow.class, true));
this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Llama.class, true));
this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Chicken.class, true));
}
@Nullable
@Override
public AgeableMob getBreedOffspring(@NotNull ServerLevel pLevel, @NotNull AgeableMob pOtherParent) {
return DinoEntities.TREX.get().create(pLevel);
}
@Override
public void registerControllers(final AnimatableManager.ControllerRegistrar controllers) {
controllers.add(new AnimationController<>(this, "Trex Walk", 5, this::walkAnimController));
controllers.add(new AnimationController<>(this, "Trex Idle", 5, this::idleAnimController));
controllers.add(new AnimationController<>(this, "Trex Attack",5, this::attackAnimController));
controllers.add(new AnimationController<>(this, "Trex Rest",5, this::restAnimController));
}
private PlayState idleAnimController(AnimationState<TrexEntity> trexEntityAnimationState) {
return trexEntityAnimationState.setAndContinue(TREX_IDLE);
}
private PlayState walkAnimController(AnimationState<TrexEntity> trexEntityAnimationState) {
if (trexEntityAnimationState.isMoving()) {
return trexEntityAnimationState.setAndContinue(TREX_WALK);
}
return PlayState.STOP;
}
private PlayState attackAnimController(AnimationState<TrexEntity> trexEntityAnimationState) {
if (trexEntityAnimationState.getAnimatable().swinging
&& trexEntityAnimationState.getController().getAnimationState().equals(AnimationController.State.STOPPED)){
trexEntityAnimationState.getController().forceAnimationReset();
trexEntityAnimationState.setAnimation(TREX_ATTACK);
trexEntityAnimationState.getAnimatable().swinging = false;
}
return PlayState.CONTINUE;
}
private PlayState restAnimController(AnimationState<TrexEntity> trexEntityAnimationState) {
long actualTime = System.currentTimeMillis();
if (getLevel().isNight())
{
return trexEntityAnimationState.setAndContinue(TREX_REST);
}
else {
if (!trexEntityAnimationState.isMoving()) {
long lasMoveTime = actualTime - lastMove;
if (lasMoveTime >= TIME_UNTIL_REST) {
return trexEntityAnimationState.setAndContinue(TREX_REST);
}
}
else {
lastMove = actualTime;
return PlayState.STOP;
}
}
return PlayState.STOP;
}
@Override
public AnimatableInstanceCache getAnimatableInstanceCache() {
return this.geoCache;
}
public Level getLevel() {
return level();
}
}