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

cn.nukkit.entity.EntityIntelligent Maven / Gradle / Ivy

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

import cn.nukkit.Player;
import cn.nukkit.Server;
import cn.nukkit.api.PowerNukkitXOnly;
import cn.nukkit.api.Since;
import cn.nukkit.entity.ai.EntityAI;
import cn.nukkit.entity.ai.behaviorgroup.EmptyBehaviorGroup;
import cn.nukkit.entity.ai.behaviorgroup.IBehaviorGroup;
import cn.nukkit.entity.ai.controller.WalkController;
import cn.nukkit.entity.ai.memory.CoreMemoryTypes;
import cn.nukkit.entity.ai.memory.IMemoryStorage;
import cn.nukkit.event.entity.EntityDamageEvent;
import cn.nukkit.form.window.FormWindowSimple;
import cn.nukkit.item.Item;
import cn.nukkit.item.ItemID;
import cn.nukkit.level.format.FullChunk;
import cn.nukkit.math.Vector3;
import cn.nukkit.nbt.tag.CompoundTag;
import lombok.Getter;
import lombok.Setter;

/**
 * {@code EntityIntelligent}抽象了一个具有行为组{@link IBehaviorGroup}(也就是具有AI)的实体
 */
@PowerNukkitXOnly
@Since("1.6.0.0-PNX")
@Getter
@Setter
public abstract class EntityIntelligent extends EntityPhysical {

    public static final IBehaviorGroup EMPTY_BEHAVIOR_GROUP = new EmptyBehaviorGroup();

    /**
     * 是否为活跃实体,如果实体不活跃,就应当降低AI运行频率
     */
    protected boolean isActive = true;

    public EntityIntelligent(FullChunk chunk, CompoundTag nbt) {
        super(chunk, nbt);
        var storage = getMemoryStorage();
        if (storage != null) {
            getMemoryStorage().put(CoreMemoryTypes.ENTITY_SPAWN_TIME, Server.getInstance().getTick());
        }
    }

    @Override
    protected void initEntity() {
        super.initEntity();
    }

    /**
     * 返回此实体持有的行为组{@link IBehaviorGroup} 
* 默认实现只会返回一个空行为{@link EmptyBehaviorGroup}常量,若你想让实体具有AI,你需要覆写此方法 * * @return 此实体持有的行为组 */ @PowerNukkitXOnly public IBehaviorGroup getBehaviorGroup() { return EMPTY_BEHAVIOR_GROUP; } @Override public boolean onUpdate(int currentTick) { if (!this.isImmobile()) { var behaviorGroup = getBehaviorGroup(); behaviorGroup.tickRunningCoreBehaviors(this); behaviorGroup.tickRunningBehaviors(this); behaviorGroup.applyController(this); if (EntityAI.DEBUG) behaviorGroup.debugTick(this); } return super.onUpdate(currentTick); } /** * 我们将行为组运行循环的部分工作并行化以提高性能 */ @Override public void asyncPrepare(int currentTick) { if (needsRecalcMovement) { // 每次要重新计算实体运动时,都重新计算一次是否活跃 isActive = level.isHighLightChunk(getChunkX(), getChunkZ()); } if (!this.isImmobile()) { // immobile会禁用实体AI var behaviorGroup = getBehaviorGroup(); if (behaviorGroup == null) return; if (needsRecalcMovement) { behaviorGroup.collectSensorData(this); behaviorGroup.evaluateCoreBehaviors(this); behaviorGroup.evaluateBehaviors(this); behaviorGroup.updateRoute(this); } } super.asyncPrepare(currentTick); } @Override public boolean attack(EntityDamageEvent source) { var result = super.attack(source); var storage = getMemoryStorage(); if (storage != null) { storage.put(CoreMemoryTypes.BE_ATTACKED_EVENT, source); storage.put(CoreMemoryTypes.LAST_BE_ATTACKED_TIME, Server.getInstance().getTick()); } return result; } @Override public boolean onInteract(Player player, Item item, Vector3 clickedPos) { if (!EntityAI.DEBUG) { return super.onInteract(player, item, clickedPos); } else { if (player.isOp() && item.getId() == ItemID.STICK) { var strBuilder = new StringBuilder(); //Build memory information strBuilder.append("§eMemory:§f\n"); var all = getMemoryStorage().getAll(); all.forEach((memory, value) -> { strBuilder.append(memory.getIdentifier()); strBuilder.append(" = §b"); strBuilder.append(value); strBuilder.append("§f\n"); }); var form = new FormWindowSimple("§f" + getOriginalName(), strBuilder.toString()); player.showFormWindow(form); return true; } else return super.onInteract(player, item, clickedPos); } } public IMemoryStorage getMemoryStorage() { return getBehaviorGroup().getMemoryStorage(); } /** * 返回实体最大的跳跃高度,返回值会用在移动处理上 * * @return 实体最大跳跃高度 * @see WalkController */ public float getJumpingHeight() { return 1.0f; } public boolean hasMoveDirection() { return getMoveDirectionStart() != null && getMoveDirectionEnd() != null; } @Override public boolean enableHeadYaw() { return true; } public Vector3 getLookTarget() { return getMemoryStorage().get(CoreMemoryTypes.LOOK_TARGET); } public void setLookTarget(Vector3 lookTarget) { getMemoryStorage().put(CoreMemoryTypes.LOOK_TARGET, lookTarget); } public Vector3 getMoveTarget() { return getMemoryStorage().get(CoreMemoryTypes.MOVE_TARGET); } public void setMoveTarget(Vector3 moveTarget) { getMemoryStorage().put(CoreMemoryTypes.MOVE_TARGET, moveTarget); } public Vector3 getMoveDirectionStart() { return getMemoryStorage().get(CoreMemoryTypes.MOVE_DIRECTION_START); } public void setMoveDirectionStart(Vector3 moveDirectionStart) { getMemoryStorage().put(CoreMemoryTypes.MOVE_DIRECTION_START, moveDirectionStart); } public Vector3 getMoveDirectionEnd() { return getMemoryStorage().get(CoreMemoryTypes.MOVE_DIRECTION_END); } public void setMoveDirectionEnd(Vector3 moveDirectionEnd) { getMemoryStorage().put(CoreMemoryTypes.MOVE_DIRECTION_END, moveDirectionEnd); } public boolean isShouldUpdateMoveDirection() { return getMemoryStorage().get(CoreMemoryTypes.SHOULD_UPDATE_MOVE_DIRECTION); } public void setShouldUpdateMoveDirection(boolean shouldUpdateMoveDirection) { getMemoryStorage().put(CoreMemoryTypes.SHOULD_UPDATE_MOVE_DIRECTION, shouldUpdateMoveDirection); } public boolean isEnablePitch() { return getMemoryStorage().get(CoreMemoryTypes.ENABLE_PITCH); } public void setEnablePitch(boolean enablePitch) { getMemoryStorage().put(CoreMemoryTypes.ENABLE_PITCH, enablePitch); } //暂时不使用 // @PowerNukkitXOnly // @Since("1.19.50-r1") // public boolean isEnableYaw() { // return getMemoryStorage().get(CoreMemoryTypes.ENABLE_YAW); // } // // @PowerNukkitXOnly // @Since("1.19.50-r1") // public void setEnableYaw(boolean enableYaw) { // getMemoryStorage().put(CoreMemoryTypes.ENABLE_YAW, enableYaw); // } // // @PowerNukkitXOnly // @Since("1.19.50-r1") // public boolean isEnableHeadYaw() { // return getMemoryStorage().get(CoreMemoryTypes.ENABLE_HEAD_YAW); // } // // @PowerNukkitXOnly // @Since("1.19.50-r1") // public void setEnableHeadYaw(boolean enableHeadYaw) { // getMemoryStorage().put(CoreMemoryTypes.ENABLE_HEAD_YAW, enableHeadYaw); // } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy