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

cn.nukkit.entity.passive.EntityNPCEntity Maven / Gradle / Ivy

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

import cn.nukkit.Player;
import cn.nukkit.Server;
import cn.nukkit.api.PowerNukkitOnly;
import cn.nukkit.api.PowerNukkitXOnly;
import cn.nukkit.api.Since;
import cn.nukkit.command.NPCCommandSender;
import cn.nukkit.dialog.element.ElementDialogButton;
import cn.nukkit.dialog.window.FormWindowDialog;
import cn.nukkit.entity.Entity;
import cn.nukkit.entity.EntityInteractable;
import cn.nukkit.entity.EntityLiving;
import cn.nukkit.entity.data.IntEntityData;
import cn.nukkit.entity.data.StringEntityData;
import cn.nukkit.event.entity.EntityDamageByEntityEvent;
import cn.nukkit.event.entity.EntityDamageEvent;
import cn.nukkit.item.Item;
import cn.nukkit.level.format.FullChunk;
import cn.nukkit.math.Vector3;
import cn.nukkit.nbt.tag.CompoundTag;
import cn.nukkit.network.protocol.NPCRequestPacket;

/**
 * @author good777LUCKY
 */
@Since("1.4.0.0-PN")
@PowerNukkitOnly
public class EntityNPCEntity extends EntityLiving implements EntityNPC, EntityInteractable {
    //todo: Implement automatic steering of NPC entities

    @Since("1.4.0.0-PN")
    @PowerNukkitOnly
    public static final int NETWORK_ID = 51;

    public static final String KEY_DIALOG_TITLE = "DialogTitle";
    public static final String KEY_DIALOG_CONTENT = "DialogContent";
    public static final String KEY_DIALOG_SKINDATA = "DialogSkinData";
    public static final String KEY_DIALOG_BUTTONS = "DialogButtons";

    protected FormWindowDialog dialog;

    protected int variant = 0;

    @Since("1.4.0.0-PN")
    @PowerNukkitOnly
    public EntityNPCEntity(FullChunk chunk, CompoundTag nbt) {
        super(chunk, nbt);
    }

    @Override
    public int getNetworkId() {
        return NETWORK_ID;
    }

    @Override
    public float getWidth() {
        return 0.6f;
    }

    @Override
    public float getHeight() {
        return 2.1f;
    }

    @Override
    public boolean canDoInteraction() {
        return true;
    }

    @Override
    public String getInteractButtonText(Player player) {
        return player.isCreative() ? "action.interact.edit" : "action.interact.talk";
    }

    @PowerNukkitOnly
    @Since("1.5.1.0-PN")
    @Override
    public String getOriginalName() {
        return "NPC";
    }

    @PowerNukkitXOnly
    @Since("1.6.0.0-PNX")
    @Override
    public void initEntity() {
        super.initEntity();
        this.setMaxHealth(Integer.MAX_VALUE); // Should be Float max value
        this.setHealth(20);
        this.setNameTagVisible(true);
        this.setNameTagAlwaysVisible(true);
        this.setVariant(this.namedTag.getInt("Variant"));
        this.dialog = new FormWindowDialog(this.namedTag.getString(KEY_DIALOG_TITLE).isEmpty() ? "NPC" : this.namedTag.getString(KEY_DIALOG_TITLE), this.namedTag.getString(KEY_DIALOG_CONTENT), this);
        this.setNameTag(this.dialog.getTitle());
        if (!this.namedTag.getString(KEY_DIALOG_SKINDATA).isEmpty())
            this.dialog.setSkinData(this.namedTag.getString(KEY_DIALOG_SKINDATA));
        if (!this.namedTag.getString(KEY_DIALOG_BUTTONS).isEmpty())
            this.dialog.setButtonJSONData(this.namedTag.getString(KEY_DIALOG_BUTTONS));
        this.dialog.addHandler((player, response) -> {
            if (response.getRequestType() == NPCRequestPacket.RequestType.SET_ACTIONS) {
                if (!response.getData().isEmpty()) {
                    this.dialog.setButtonJSONData(response.getData());
                    this.setDataProperty(new StringEntityData(Entity.DATA_NPC_ACTIONS, response.getData()));
                }
            }
            if (response.getRequestType() == NPCRequestPacket.RequestType.SET_INTERACTION_TEXT) {
                this.dialog.setContent(response.getData());
                this.setDataProperty(new StringEntityData(Entity.DATA_INTERACTIVE_TAG, response.getData()));
            }
            if (response.getRequestType() == NPCRequestPacket.RequestType.SET_NAME) {
                this.dialog.setTitle(response.getData());
                this.setNameTag(response.getData());
            }
            if (response.getRequestType() == NPCRequestPacket.RequestType.SET_SKIN) {
                this.setVariant(response.getSkinType());
            }
            if (response.getRequestType() == NPCRequestPacket.RequestType.EXECUTE_ACTION) {
                ElementDialogButton clickedButton = response.getClickedButton();
                for (ElementDialogButton.CmdLine line : clickedButton.getData()) {
                    Server.getInstance().dispatchCommand(new NPCCommandSender(this, player), line.cmd_line.startsWith("/") ? line.cmd_line.substring(1) : line.cmd_line);
                }
            }
            if (response.getRequestType() == NPCRequestPacket.RequestType.EXECUTE_OPENING_COMMANDS) {
                for (ElementDialogButton button : this.dialog.getButtons()) {
                    if (button.getMode() == ElementDialogButton.Mode.ON_ENTER) {
                        for (ElementDialogButton.CmdLine line : button.getData()) {
                            Server.getInstance().dispatchCommand(new NPCCommandSender(this, player), line.cmd_line.startsWith("/") ? line.cmd_line.substring(1) : line.cmd_line);
                        }
                    }
                }
            }
            if (response.getRequestType() == NPCRequestPacket.RequestType.EXECUTE_CLOSING_COMMANDS) {
                for (ElementDialogButton button : this.dialog.getButtons()) {
                    if (button.getMode() == ElementDialogButton.Mode.ON_EXIT) {
                        for (ElementDialogButton.CmdLine line : button.getData()) {
                            Server.getInstance().dispatchCommand(new NPCCommandSender(this, player), line.cmd_line.startsWith("/") ? line.cmd_line.substring(1) : line.cmd_line);
                        }
                    }
                }
            }
        });
        this.dialog.setBindEntity(this);
    }

    @PowerNukkitXOnly
    @Since("1.6.0.0-PNX")
    @Override
    public void saveNBT() {
        super.saveNBT();
        this.namedTag.putString(KEY_DIALOG_TITLE, this.dialog.getTitle());
        this.namedTag.putString(KEY_DIALOG_CONTENT, this.dialog.getContent());
        this.namedTag.putString(KEY_DIALOG_SKINDATA, this.dialog.getSkinData());
        this.namedTag.putString(KEY_DIALOG_BUTTONS, this.dialog.getButtonJSONData());
        this.namedTag.putInt("Variant", this.variant);
    }

    @PowerNukkitXOnly
    @Since("1.6.0.0-PNX")
    @Override
    public boolean onInteract(Player player, Item item, Vector3 clickedPos) {
        //对于创造模式玩家,NPC发送过去的dialog的sceneName必须为空,否则客户端会不允许修改对话框内容
        //另外的,我们不需要记录发送给创造模式玩家的对话框,首先因为我们无法清除,其次没有必要
        player.showDialogWindow(this.dialog, !player.isCreative());
        return true;
    }

    @PowerNukkitXOnly
    @Since("1.6.0.0-PNX")
    @Override
    public boolean attack(EntityDamageEvent source) {
        if (source instanceof EntityDamageByEntityEvent event && event.getDamager() instanceof Player damager && damager.isCreative()) {
            this.kill();
        }
        return false;
    }

    @PowerNukkitXOnly
    @Since("1.6.0.0-PNX")
    public int getVariant() {
        return this.variant;
    }

    @PowerNukkitXOnly
    @Since("1.6.0.0-PNX")
    public void setVariant(int variant) {
        this.variant = variant;
        this.setDataProperty(new IntEntityData(DATA_VARIANT, variant));
    }

    @PowerNukkitXOnly
    @Since("1.6.0.0-PNX")
    public FormWindowDialog getDialog() {
        return dialog;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy