All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.nukkit.entity.ai.executor.EntityBreedingExecutor Maven / Gradle / Ivy

There is a newer version: 1.20.40-r1
Show newest version
package cn.nukkit.entity.ai.executor;

import cn.nukkit.Server;
import cn.nukkit.api.PowerNukkitXOnly;
import cn.nukkit.api.Since;
import cn.nukkit.entity.Entity;
import cn.nukkit.entity.EntityIntelligent;
import cn.nukkit.entity.ai.memory.CoreMemoryTypes;
import cn.nukkit.entity.passive.EntityAnimal;
import edu.umd.cs.findbugs.annotations.Nullable;

import java.util.concurrent.ThreadLocalRandom;

@PowerNukkitXOnly
@Since("1.6.0.0-PNX")
public class EntityBreedingExecutor implements IBehaviorExecutor {

    protected Class entityClass;
    protected int findingRangeSquared;
    protected int duration;
    protected int currentTick = 0;
    protected float moveSpeed;
    protected boolean finded;
    protected T another;

    public EntityBreedingExecutor(Class entityClass, int findingRangeSquared, int duration, float moveSpeed) {
        this.entityClass = entityClass;
        this.findingRangeSquared = findingRangeSquared;
        this.duration = duration;
        this.moveSpeed = moveSpeed;
    }

    @Override
    public boolean execute(EntityIntelligent uncasted) {
        if (entityClass.isInstance(uncasted)) {
            T entity = entityClass.cast(uncasted);
            if (shouldFindingSpouse(entity)) {
                if (!entity.getMemoryStorage().get(CoreMemoryTypes.IS_IN_LOVE))
                    return false;
                another = getNearestInLove(entity);
                if (another == null) return true;
                setSpouse(entity, another);

                //set move speed
                entity.setMovementSpeed(moveSpeed);
                another.setMovementSpeed(moveSpeed);

                finded = true;
            }
            if (finded) {
                currentTick++;

                updateMove(entity, another);

                if (currentTick > duration) {
                    bear(entity, another);
                    clearData(entity);
                    clearData(another);

                    currentTick = 0;
                    finded = false;
                    entity.setEnablePitch(false);
                    another.setEnablePitch(false);
                    another = null;
                    return false;
                }
            }
            return true;
        } else {
            return false;
        }
    }

    @Override
    public void onInterrupt(EntityIntelligent entity) {
        currentTick = 0;
        finded = false;
        entity.setEnablePitch(false);
        another.setEnablePitch(false);
        another = null;
    }

    protected void setSpouse(T entity1, T entity2) {
        entity1.getMemoryStorage().put(CoreMemoryTypes.ENTITY_SPOUSE, entity2);
        entity2.getMemoryStorage().put(CoreMemoryTypes.ENTITY_SPOUSE, entity1);
    }

    protected void clearData(T entity) {
        entity.getMemoryStorage().clear(CoreMemoryTypes.ENTITY_SPOUSE);
        //clear move target
        entity.setMoveTarget(null);
        //clear look target
        entity.setLookTarget(null);
        //reset move speed
        entity.setMovementSpeed(0.1f);
        //interrupt in love status
        entity.getMemoryStorage().put(CoreMemoryTypes.IS_IN_LOVE, false);
    }

    protected void updateMove(T entity1, T entity2) {
        if (!entity1.isEnablePitch()) entity1.setEnablePitch(true);
        if (!entity2.isEnablePitch()) entity2.setEnablePitch(true);

        //clone the vec
        var cloned1 = entity1.clone();
        var cloned2 = entity2.clone();

        //update move target
        entity1.setMoveTarget(cloned2);
        entity2.setMoveTarget(cloned1);

        //update look target
        entity1.setLookTarget(cloned2);
        entity2.setLookTarget(cloned1);
    }

    @Nullable
    protected T getNearestInLove(EntityIntelligent entity) {
        var entities = entity.level.getEntities();
        var maxDistanceSquared = -1d;
        T nearestInLove = null;
        for (var e : entities) {
            var newDistance = e.distanceSquared(entity);
            if (!e.equals(entity) && entityClass.isInstance(e)) {
                T another = (T) e;
                if (!another.isBaby() && another.getMemoryStorage().get(CoreMemoryTypes.IS_IN_LOVE) && another.getMemoryStorage().isEmpty(CoreMemoryTypes.ENTITY_SPOUSE) && (maxDistanceSquared == -1 || newDistance < maxDistanceSquared)) {
                    maxDistanceSquared = newDistance;
                    nearestInLove = another;
                }
            }
        }
        return nearestInLove;
    }

    protected boolean shouldFindingSpouse(T entity) {
        return entity.getMemoryStorage().isEmpty(CoreMemoryTypes.ENTITY_SPOUSE);
    }

    protected void bear(T entity1, T entity2) {
        var rand = ThreadLocalRandom.current();
        T baby = (T) Entity.createEntity(entity1.getNetworkId(), entity1.getPosition());
        baby.setBaby(true);
        //防止小屁孩去生baby
        baby.getMemoryStorage().put(CoreMemoryTypes.LAST_IN_LOVE_TIME, Server.getInstance().getTick());
        baby.spawnToAll();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy