Repository: PaperMC/Paper
File: paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftArmadillo.java (Java)

Code before:
package org.bukkit.craftbukkit.entity;

import com.google.common.base.Preconditions;
import net.minecraft.world.entity.animal.armadillo.Armadillo.ArmadilloState;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.entity.Armadillo;

public class CraftArmadillo extends CraftAnimals implements Armadillo {

    public CraftArmadillo(CraftServer server, net.minecraft.world.entity.animal.armadillo.Armadillo entity) {
        super(server, entity);
    }

    @Override
    public net.minecraft.world.entity.animal.armadillo.Armadillo getHandle() {
        return (net.minecraft.world.entity.animal.armadillo.Armadillo) super.getHandle();
    }

    @Override
    public State getState() {
        return this.stateToBukkit(this.getHandle().getState());
    }

    @Override
    public void setState(final State state) {
        Preconditions.checkArgument(state != null, "state cannot be null");
        this.getHandle().switchToState(this.stateToNMS(state));
    }

    @Override
    public void rollUp() {
        this.getHandle().rollUp();
    }

    @Override
    public void rollOut() {
        this.getHandle().rollOut();
    }

    @Override
    public String toString() {
        return "CraftArmadillo";
    }

    public static State stateToBukkit(ArmadilloState state) {
        return switch (state) {
            case IDLE -> State.IDLE;
            case ROLLING -> State.ROLLING;
            case SCARED -> State.SCARED;
            case UNROLLING -> State.UNROLLING;

Review comment (suggestion):
I'm not sure if it's intended but those methods should probably set/reset the DANGER_DETECTED_RECENTLY memory module type otherwise the changes are immediately reverted. Alternatively the key could be exposed in the api ig.

Code after:
package org.bukkit.craftbukkit.entity;

import net.minecraft.world.entity.ai.memory.MemoryModuleType;
import net.minecraft.world.entity.animal.armadillo.Armadillo.ArmadilloState;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.entity.Armadillo;

public class CraftArmadillo extends CraftAnimals implements Armadillo {

    public CraftArmadillo(CraftServer server, net.minecraft.world.entity.animal.armadillo.Armadillo entity) {
        super(server, entity);
    }

    @Override
    public net.minecraft.world.entity.animal.armadillo.Armadillo getHandle() {
        return (net.minecraft.world.entity.animal.armadillo.Armadillo) super.getHandle();
    }

    @Override
    public State getState() {
        return CraftArmadillo.stateToBukkit(this.getHandle().getState());
    }

    @Override
    public void rollUp() {
        this.getHandle().getBrain().setMemoryWithExpiry(MemoryModuleType.DANGER_DETECTED_RECENTLY, true, net.minecraft.world.entity.animal.armadillo.Armadillo.SCARE_CHECK_INTERVAL);
        this.getHandle().rollUp();
    }

    @Override
    public void rollOut() {
        if (this.getHandle().getBrain().getTimeUntilExpiry(MemoryModuleType.DANGER_DETECTED_RECENTLY) <= ArmadilloState.UNROLLING.animationDuration()) {
            // already unrolling or unrolled
            return;
        }

        this.getHandle().lastHurtByMob = null; // Clear this memory to not have the sensor trigger rollUp instantly for damaged armadillo
        this.getHandle().getBrain().setMemoryWithExpiry(MemoryModuleType.DANGER_DETECTED_RECENTLY, true, ArmadilloState.UNROLLING.animationDuration());
    }

    @Override
    public String toString() {
        return "CraftArmadillo";
    }

    public static State stateToBukkit(ArmadilloState state) {
        return switch (state) {
            case IDLE -> State.IDLE;
            case ROLLING -> State.ROLLING;
            case SCARED -> State.SCARED;