NPC Interactions - Legacy

  • Konuyu Başlatan Konuyu Başlatan Senpai
  • Başlangıç tarihi Başlangıç tarihi
  • Görüntüleme 752
Durum
Üzgünüz bu konu cevaplar için kapatılmıştır...

Senpai

Züm... Zümrü... Zümrüt...
Yasaklandı
Katılım
24 Kasım 2014
Mesajlar
816
Elmaslar
341
Puan
14.845
Yaş
27
Konum
Istanbul
Minecraft
NaN2
Tamamen deney amaçlı yaptığım bir proje oldu, yıllardır Skript ile alakalı hiçbir şey yapmıyordum. /npc komudu ile NPC oluşturabilir, giydirebilir, custom texture skull ekleyebilir ve diyalog ekleyebilirsiniz. Performans konusunda emin değilim, dediğim gibi production-level bir kod değil sadece kendimi denemek ve Skript'e tekrar alışabilmek için yaptığım bir proje.

Gerekli Addonlar: skript-reflect, skript-gui, SkBee (?, gerekli olmayabilir), ProtocolLib
GitHub:
Değerli ziyaretçimiz, içeriği görebilmek için şimdi giriş yapın veya kayıt olun.


Kod:
Kod:
import:
    org.bukkit.entity.EntityType
    org.bukkit.entity.ArmorStand
    org.bukkit.Location
    org.bukkit.inventory.meta.SkullMeta
    com.mojang.authlib.GameProfile
    com.mojang.authlib.properties.Property
    java.util.UUID

function createNPC(name: text, world: text, x: number, y: number, z: number, skin: text) :: number:
    set {_location} to new Location(world "%{_world}%", {_x}, {_y}, {_z})
   
    if {npc.lastid} is not set:
        set {npc.lastid} to 0
    add 1 to {npc.lastid}
    set {_id} to {npc.lastid}
   
    set {_hint_loc} to {_location}.clone()
    {_hint_loc}.add(2, 0, 0) # x,y,z - h ihtiyac var cunku location clone ettigimizde armor standin basladigi yeri baz aliyoruz.
    set {_hint} to {_location}.getWorld().spawn({_hint_loc}, ArmorStand.class)
    {_hint}.setCustomName(colored "&7&o(Right-click to interact!)")
    {_hint}.setCustomNameVisible(false)
    {_hint}.setVisible(false)
    {_hint}.setGravity(false)
    {_hint}.setMarker(true)
    {_hint}.setSmall(true)
   
    set {_npc} to {_location}.getWorld().spawn({_location}, ArmorStand.class)
    {_npc}.setCustomName(colored {_name})
    {_npc}.setCustomNameVisible(true)
    {_npc}.setVisible(true)
    {_npc}.setGravity(false)
    {_npc}.setSmall(false)
   
    set {npcs::%{_id}%::name} to {_name}
    set {npcs::%{_id}%::location} to {_location}
    set {npcs::%{_id}%::entity} to {_npc}
    set {npcs::%{_id}%::hint} to {_hint}
    clear {npcs::%{_id}%::stages::*}
   
    set {npcs::%{_id}%::equipment::helmet} to air
    set {npcs::%{_id}%::equipment::chestplate} to air
    set {npcs::%{_id}%::equipment::leggings} to air
    set {npcs::%{_id}%::equipment::boots} to air
    set {npcs::%{_id}%::equipment::mainhand} to air
    set {npcs::%{_id}%::equipment::offhand} to air
   
    delete {npcs::%{_id}%::skull_texture}
   
    return {_id}

function addNPCStages(id: number, stages: texts):
    send "&e[Debug] Adding stages to NPC %{_id}%" to console
    clear {npcs::%{_id}%::stages::*}
    loop {_stages::*}:
        add loop-value to {npcs::%{_id}%::stages::*}
    send "&a[Debug] Added %size of {npcs::%{_id}%::stages::*}% stages: %{npcs::%{_id}%::stages::*}%" to console

function isNPCDebug(p: player) :: boolean:
    set {_uuid} to "%{_p}'s uuid%"
    if {npc.debug::%{_uuid}%} is set:
        return true
    return false

function toggleNPCDebug(p: player):
    set {_uuid} to "%{_p}'s uuid%"
    if {npc.debug::%{_uuid}%} is set:
        delete {npc.debug::%{_uuid}%}
        send "&c[NPC] Debug mode disabled" to {_p}
    else:
        set {npc.debug::%{_uuid}%} to true
        send "&a[NPC] Debug mode enabled" to {_p}

command /npcdebug:
    permission: op
    trigger:
        toggleNPCDebug(player)

on rightclick on entity:
    if event-entity is an armor stand:
        set {_clicked} to event-entity
        set {_debug} to isNPCDebug(player)
        if {_debug} is true:
            send "&b[Debug] Clicked armor stand with UUID: %{_clicked}.getUniqueId()%" to player
            send "&e[Debug] Checking stored NPCs..." to player
            send "&e[Debug] Current NPCs in storage: %{npc.lastid}% total" to player
       
        loop {npc.lastid} times:
            set {_id} to loop-number
            if {_debug} is true:
                send "&e[Debug] Checking NPC ID: %{_id}%" to player
           
            if {npcs::%{_id}%::entity} is set:
                set {_npc} to {npcs::%{_id}%::entity}
                if {_debug} is true:
                    send "&e[Debug] Comparing entities:" to player
                    send "&7 - Clicked UUID: %{_clicked}.getUniqueId()%" to player
                    send "&7 - Stored UUID: %{_npc}.getUniqueId()%" to player
               
                if {_clicked}.getUniqueId() is {_npc}.getUniqueId():
                    if {_debug} is true:
                        send "&a[Debug] Found NPC match! ID: %{_id}%" to player
                   
                    if {npc.talking::%{_id}%::%player's uuid%} is set:
                        if {_debug} is true:
                            send "&c[Debug] NPC is already talking to this player" to player
                        stop

                    if {npcs::%{_id}%::locked} is true:
                        if {_debug} is true:
                            send "&c[Debug] This NPC is locked" to player
                        stop
                   
                    set {player.npc.stage::%{_id}%} to 1
                    playNPCDialog({_id}, player)
                    stop

function playNPCDialog(id: number, p: player):
    set {npc.talking::%{_id}%::%{_p}'s uuid%} to true
   
    set {_stage} to {player.npc.stage::%{_id}%}
    set {_total} to size of {npcs::%{_id}%::stages::*}
   
    while {_stage} <= {_total}:
        set {_message} to {npcs::%{_id}%::stages::%{_stage}%}
        set {_name} to {npcs::%{_id}%::name}
       
        send "&7[%{_stage}%/%{_total}%] %colored {_name}%&a: %{_message}%" to {_p}
       
        add 1 to {_stage}
        if {_stage} <= {_total}:
            wait 1.3 seconds
   
    delete {player.npc.stage::%{_id}%}
    delete {npc.talking::%{_id}%::%{_p}'s uuid%}

on damage of armor stand:
    loop {npcs::*}:
        set {_id} to loop-index parsed as number
        if {_id} is set:
            if {npcs::%{_id}%::entity} is victim:
                cancel event
                stop

on break:
    if event-entity is an armor stand:
        loop {npcs::*}:
            set {_id} to loop-index parsed as number
            if {_id} is set:
                if {npcs::%{_id}%::entity} is event-entity:
                    cancel event
                    stop

on explosion prime:
    loop {npcs::*}:
        set {_id} to loop-index parsed as number
        if {_id} is set:
            set {_npc} to {npcs::%{_id}%::entity}
            if {_npc} is set:
                if event-entity's location.distance({_npc}.getLocation()) <= 5:
                    cancel event

on target:
    loop {npcs::*}:
        set {_id} to loop-index parsed as number
        if {_id} is set:
            if {npcs::%{_id}%::entity} is target:
                cancel event

on entity teleport:
    if event-entity is an armor stand:
        loop {npcs::*}:
            set {_id} to loop-index parsed as number
            if {_id} is set:
                if {npcs::%{_id}%::entity} is event-entity:
                    cancel event

on right click:
    if clicked entity is an armor stand:
        loop {npcs::*}:
            set {_id} to loop-index parsed as number
            if {_id} is set:
                if {npcs::%{_id}%::entity} is clicked entity:
                    cancel event
                    stop

on left click:
    if clicked entity is an armor stand:
        loop {npcs::*}:
            set {_id} to loop-index parsed as number
            if {_id} is set:
                if {npcs::%{_id}%::entity} is clicked entity:
                    cancel event
                    stop

on skript load:
    set {_id} to createNPC("&aTrader Jack", "world", 100, 64, 100, "MHF_Villager")
    addNPCStages({_id}, ("Welcome to my shop!", "I have the best deals in town!", "Check out my special offers!", "Have a great day!"))

    set {_id} to createNPC("&cCity Guard", "world", 105, 64, 105, "MHF_Guard")
    addNPCStages({_id}, ("Halt! State your business.", "Keep the peace, citizen.", "Stay out of trouble.", "Move along."))

on load:
    delete {npc.creating::*}
    delete {npc.editing::*}

function openNPCCreationMenu(p: player):
    create a gui with virtual chest inventory with 3 rows named "&8NPC Creation Menu":
        make gui slot 11 with name tag named "&a&lCreate New NPC" with lore "&7Click to create a new NPC", "&7at your current location":
            close {_p}'s inventory
            set {npc.creating::%{_p}'s uuid%::state} to "name"
            send "&aEnter the name for the new NPC in chat:" to {_p}
            send "&7(Type 'cancel' to cancel)" to {_p}
           
        make gui slot 13 with book named "&6&lEdit Existing NPCs" with lore "&7Click to manage existing NPCs":
            openNPCListMenu({_p})
           
        make gui slot 15 with barrier named "&c&lClose Menu" with lore "&7Click to close this menu":
            close {_p}'s inventory
           
    open the last gui for {_p}

function openNPCEditMenu(p: player, id: number):
    create a gui with virtual chest inventory with 6 rows named "&8Edit NPC #%{_id}%":
        make gui slot 13 with name tag named "&e&l%{npcs::%{_id}%::name}%" with lore "&7ID: &e%{_id}%", "&7Stages: &e%size of {npcs::%{_id}%::stages::*}%":
            stop
           
        make gui slot 29 with book named "&a&lEdit Dialog" with lore "&7Click to edit NPC's dialog stages":
            openNPCStagesMenu({_p}, {_id})
           
        make gui slot 31 with diamond chestplate named "&b&lEquipment" with lore "&7Click to edit NPC's equipment":
            openNPCEquipmentMenu({_p}, {_id})
           
        make gui slot 32 with blaze rod named "&6&lMove NPC" with lore "&7Click to move this NPC", "&7to a new location":
            close {_p}'s inventory
            set {npc.moving::%{_p}'s uuid%} to {_id}
            give blaze rod named "&6Moving NPC #%{_id}%" with lore "&7Place to move the NPC", "&7Right-click to cancel" to {_p}
            {npcs::%{_id}%::entity}.remove()
            {npcs::%{_id}%::hint}.remove()
            send "&eRight-click with the blaze rod to cancel" to {_p}
           
        make gui slot 33 with ender pearl named "&5&lTeleport" with lore "&7Click to teleport to NPC":
            teleport {_p} to {npcs::%{_id}%::location}
            close {_p}'s inventory
           
        make gui slot 30 with player head named "&d&lChange Head" with lore "&7Current: %{npcs::%{_id}%::skull_texture} ? "Default"%", "", "&eClick &8» &7Set custom head":
            close {_p}'s inventory
            set {npc.editing::%{_p}'s uuid%::state} to "skull"
            set {npc.editing::%{_p}'s uuid%::npc_id} to {_id}
            send "&aEnter the skull texture value:" to {_p}
            send "&7(Type 'cancel' to cancel, 'reset' to remove custom head)" to {_p}
           
        make gui slot 49 with arrow named "&c&lBack" with lore "&7Return to NPC list":
            openNPCListMenu({_p})
           
    open the last gui for {_p}

function openNPCListMenu(p: player):
    create a gui with virtual chest inventory with 6 rows named "&8NPC List":
        set {_slot} to 0
        loop {npc.lastid} times:
            set {_id} to loop-number
            if {npcs::%{_id}%::entity} is set:
                set {_locked} to ""
                if {npcs::%{_id}%::locked} is true:
                    set {_locked} to " &c[LOCKED]"
                make gui slot {_slot} with blaze rod named "&e&l%{npcs::%{_id}%::name}%%{_locked}%" with lore "&7ID: &e%{_id}%", "&7Click to edit":
                    openNPCEditMenu({_p}, {_id})
                add 1 to {_slot}
               
        make gui slot 49 with emerald named "&a&lCreate New NPC" with lore "&7Click to create a new NPC":
            close {_p}'s inventory
            set {npc.creating::%{_p}'s uuid%::state} to "name"
            send "&aEnter the name for the new NPC in chat:" to {_p}
            send "&7(Type 'cancel' to cancel)" to {_p}
           
    open the last gui for {_p}

function openNPCStagesMenu(p: player, id: number):
    create a gui with virtual chest inventory with 6 rows named "&8Edit NPC #%{_id}% Stages":
        set {_slot} to 0
       
        loop {npcs::%{_id}%::stages::*}:
            make gui slot {_slot} with paper named "&e&lStage #%{_slot}+1%" with lore "&7Message: %loop-value%", "", "&eLeft-Click &7to edit", "&cRight-Click &7to remove":
                if click type is right mouse button:
                    delete {npcs::%{_id}%::stages::%{_slot}+1%}
                    openNPCStagesMenu({_p}, {_id})
                else if click type is left mouse button:
                    close {_p}'s inventory
                    set {npc.editing::%{_p}'s uuid%::state} to "edit_stage"
                    set {npc.editing::%{_p}'s uuid%::npc_id} to {_id}
                    set {npc.editing::%{_p}'s uuid%::stage_num} to {_slot}+1
                    send "&aEnter the new message for this stage in chat:" to {_p}
                    send "&7(Type 'cancel' to cancel)" to {_p}
            add 1 to {_slot}
       
        make gui slot 48 with emerald named "&a&lAdd New Stage" with lore "&7Click to add a new stage":
            close {_p}'s inventory
            set {npc.editing::%{_p}'s uuid%::state} to "add_stage"
            set {npc.editing::%{_p}'s uuid%::npc_id} to {_id}
            send "&aEnter the message for the new stage in chat:" to {_p}
            send "&7(Type 'cancel' to cancel)" to {_p}
           
        make gui slot 49 with arrow named "&c&lBack to NPC List" with lore "&7Click to return to NPC list":
            openNPCEditMenu({_p}, {_id})
           
    open the last gui for {_p}

on chat:
    if {npc.creating::%player's uuid%::state} is set:
        cancel event
       
        if message is "cancel":
            delete {npc.creating::%player's uuid%::*}
            send "&cNPC creation cancelled" to player
            stop
       
        if {npc.creating::%player's uuid%::state} is "name":
            set {npc.creating::%player's uuid%::name} to colored message
            set {_id} to createNPC(message, player.getWorld().getName(), player.getLocation().getX(), player.getLocation().getY(), player.getLocation().getZ(), "MHF_Villager")
           
            if {_id} is set:
                delete {npc.creating::%player's uuid%::*}
                send "&aSuccessfully created NPC with ID: %{_id}%" to player
                send "&eNow opening stage editor..." to player
                wait 1 tick
                openNPCStagesMenu(player, {_id})
            else:
                delete {npc.creating::%player's uuid%::*}
                send "&cFailed to create NPC! Please try again." to player
            stop
   
    if {npc.editing::%player's uuid%::state} is "edit_stage":
        cancel event
       
        if message is "cancel":
            delete {npc.editing::%player's uuid%::*}
            send "&cStage editing cancelled" to player
            stop
           
        set {_id} to {npc.editing::%player's uuid%::npc_id}
        set {_stage} to {npc.editing::%player's uuid%::stage_num}
       
        set {npcs::%{_id}%::stages::%{_stage}%} to message
        delete {npc.editing::%player's uuid%::*}
        send "&aStage updated successfully!" to player
        wait 1 tick
        openNPCStagesMenu(player, {_id})
       
    if {npc.editing::%player's uuid%::state} is "add_stage":
        cancel event
       
        if message is "cancel":
            delete {npc.editing::%player's uuid%::*}
            send "&cStage addition cancelled" to player
            stop
           
        set {_id} to {npc.editing::%player's uuid%::npc_id}
        add message to {npcs::%{_id}%::stages::*}
        delete {npc.editing::%player's uuid%::*}
        send "&aNew stage added successfully!" to player
        wait 1 tick
        openNPCStagesMenu(player, {_id})
   
    if {npc.editing::%player's uuid%::state} is "skull":
        cancel event
        set {_id} to {npc.editing::%player's uuid%::npc_id}
       
        if message is "cancel":
            delete {npc.editing::%player's uuid%::*}
            send "&cSkull editing cancelled" to player
            openNPCEditMenu(player, {_id})
            stop
           
        if message is "reset":
            delete {npcs::%{_id}%::skull_texture}
            delete {npc.editing::%player's uuid%::*}
            send "&aRemoved custom skull!" to player
            updateNPCSkull({_id})
            openNPCEditMenu(player, {_id})
            stop
           
        set {npcs::%{_id}%::skull_texture} to message
        delete {npc.editing::%player's uuid%::*}
        send "&aSkull texture updated!" to player
        updateNPCSkull({_id})
        openNPCEditMenu(player, {_id})
        stop

command /createnpc:
    permission: admin.createnpc
    trigger:
        openNPCCreationMenu(player)

command /checknpc [<number>]:
    permission: admin.createnpc
    trigger:
        if arg-1 is set:
            send "&eChecking NPC %arg-1%:" to player
            send "&7Name: %{npcs::%arg-1%::name}%" to player
            send "&7Entity: %{npcs::%arg-1%::entity}%" to player
            send "&7Stages: %{npcs::%arg-1%::stages::*}%" to player
            send "&7Total stages: %size of {npcs::%arg-1%::stages::*}%" to player
        else:
            loop {npcs::*}:
                set {_id} to loop-index parsed as number
                send "&eNPC %{_id}%:" to player
                send "&7Name: %{npcs::%{_id}%::name}%" to player
                send "&7Stages: %{npcs::%{_id}%::stages::*}%" to player

command /npc [<text>] [<number>] [<text>]:
    aliases: npca
    permission: admin.npc
    trigger:
        if arg-1 is not set:
            openNPCMainMenu(player)
            stop
           
        if arg-1 is "create":
            openNPCCreationMenu(player)
           
        else if arg-1 is "list":
            openNPCListMenu(player)
           
        else if arg-1 is "edit" or "e":
            if arg-2 is not set:
                send "&c/npc edit <id>" to player
                stop
            if {npcs::%arg-2%::entity} is not set:
                send "&cNo NPC found with ID %arg-2%" to player
                stop
            openNPCEditMenu(player, arg-2)
           
        else if arg-1 is "wipe":
            set {_count} to 0
            loop {npc.lastid} times:
                set {_id} to loop-number
                if {npcs::%{_id}%::entity} is set:
                    add 1 to {_count}
                    {npcs::%{_id}%::entity}.remove()
                    {npcs::%{_id}%::hint}.remove()
                    delete {npcs::%{_id}%::*}
            delete {npc.lastid}
            send "&cRemoved %{_count}% NPCs from the world" to player
           
        else if arg-1 is "delete" or "del":
            if arg-2 is not set:
                send "&c/npc delete <id>" to player
                stop
            if {npcs::%arg-2%::entity} is not set:
                send "&cNo NPC found with ID %arg-2%" to player
                stop
            {npcs::%arg-2%::entity}.remove()
            {npcs::%arg-2%::hint}.remove()
            delete {npcs::%arg-2%::*}
            send "&cDeleted NPC with ID %arg-2%" to player
           
        else if arg-1 is "lock":
            if arg-2 is not set:
                send "&c/npc lock <id>" to player
                stop
            if {npcs::%arg-2%::entity} is not set:
                send "&cNo NPC found with ID %arg-2%" to player
                stop
            if {npcs::%arg-2%::locked} is true:
                delete {npcs::%arg-2%::locked}
                send "&aUnlocked NPC with ID %arg-2%" to player
            else:
                set {npcs::%arg-2%::locked} to true
                send "&cLocked NPC with ID %arg-2%" to player
               
        else if arg-1 is "skull":
            if arg-2 is not set:
                send "&c/npc skull <id> [texture]" to player
                stop
            if {npcs::%arg-2%::entity} is not set:
                send "&cNo NPC found with ID %arg-2%" to player
                stop
            if arg-3 is set:
                set {npcs::%arg-2%::skull_texture} to arg-3
                updateNPCSkull(arg-2)
                send "&aUpdated skull texture for NPC %arg-2%" to player
            else:
                send "&eCurrent skull texture for NPC %arg-2%: %{npcs::%arg-2%::skull_texture} ? "None"%" to player
               
        else if arg-1 is "help":
            send "" to player
            send "&e&lNPC Commands:" to player
            send "&7/npc &8» &fOpen main NPC menu" to player
            send "&7/npc create &8» &fCreate new NPC" to player
            send "&7/npc list &8» &fList all NPCs" to player
            send "&7/npc edit <id> &8» &fEdit NPC" to player
            send "&7/npc delete <id> &8» &fDelete NPC" to player
            send "&7/npc lock <id> &8» &fLock/unlock NPC" to player
            send "&7/npc skull <id> [texture] &8» &fSet NPC skull" to player
            send "&7/npc wipe &8» &fDelete all NPCs" to player
            send "" to player
           
        else:
            send "&cUnknown argument. Use /npc help for commands" to player

function openNPCMainMenu(p: player):
    create a gui with virtual chest inventory with 3 rows named "&8NPC Management":
        make gui slot 10 with emerald named "&a&lCreate NPC" with lore "&7Click to create a new NPC", "&7at your current location":
            openNPCCreationMenu({_p})
           
        make gui slot 12 with book named "&e&lNPC List" with lore "&7Click to view and edit", "&7all existing NPCs":
            openNPCListMenu({_p})
           
        make gui slot 14 with redstone named "&c&lQuick Actions" with lore "&7Click to access quick", "&7management options":
            openNPCQuickActionsMenu({_p})
           
        make gui slot 16 with paper named "&b&lHelp" with lore "&7Click to view commands", "&7and information":
            close {_p}'s inventory
            make player execute command "npc help"
           
    open the last gui for {_p}

function openNPCQuickActionsMenu(p: player):
    create a gui with virtual chest inventory with 3 rows named "&8Quick Actions":
        make gui slot 11 with barrier named "&c&lWipe All NPCs" with lore "&7Click to remove all NPCs", "&7from the world", "", "&c&lWARNING: &7This cannot be undone!":
            close {_p}'s inventory
            make player execute command "npc wipe"
           
        set {_debug} to "&cOFF"
        if {npc.debug::%{_p}'s uuid%} is set:
            set {_debug} to "&aON"
        make gui slot 13 with redstone torch named "&e&lToggle Debug" with lore "&7Click to toggle debug mode", "&7Current: %{_debug}%":
            toggleNPCDebug({_p})
            openNPCQuickActionsMenu({_p})
           
        make gui slot 15 with arrow named "&7Back to Main Menu" with lore "&7Return to main menu":
            openNPCMainMenu({_p})
           
    open the last gui for {_p}

on quit:
    delete {npc.creating::%player's uuid%::*}
    delete {npc.editing::%player's uuid%::*}

function openNPCEquipmentMenu(p: player, id: number):
    create a gui with virtual chest inventory with 4 rows named "&8Equipment - %{npcs::%{_id}%::name}%":
        if {npcs::%{_id}%::equipment::helmet} is not set:
            set {npcs::%{_id}%::equipment::helmet} to air
        if {npcs::%{_id}%::equipment::chestplate} is not set:
            set {npcs::%{_id}%::equipment::chestplate} to air
        if {npcs::%{_id}%::equipment::leggings} is not set:
            set {npcs::%{_id}%::equipment::leggings} to air
        if {npcs::%{_id}%::equipment::boots} is not set:
            set {npcs::%{_id}%::equipment::boots} to air
        if {npcs::%{_id}%::equipment::mainhand} is not set:
            set {npcs::%{_id}%::equipment::mainhand} to air
        if {npcs::%{_id}%::equipment::offhand} is not set:
            set {npcs::%{_id}%::equipment::offhand} to air
       
        make gui slot 10 with leather helmet named "&e&lHelmet" with lore "&7Current: %{npcs::%{_id}%::equipment::helmet} ? "None"%", "", "&eClick &8» &7Change Item":
            openEquipmentTypeMenu({_p}, {_id}, "helmet")
       
        make gui slot 19 with leather chestplate named "&e&lChestplate" with lore "&7Current: %{npcs::%{_id}%::equipment::chestplate} ? "None"%", "", "&eClick &8» &7Change Item":
            openEquipmentTypeMenu({_p}, {_id}, "chestplate")
       
        make gui slot 28 with leather leggings named "&e&lLeggings" with lore "&7Current: %{npcs::%{_id}%::equipment::leggings} ? "None"%", "", "&eClick &8» &7Change Item":
            openEquipmentTypeMenu({_p}, {_id}, "leggings")
       
        make gui slot 12 with leather boots named "&e&lBoots" with lore "&7Current: %{npcs::%{_id}%::equipment::boots} ? "None"%", "", "&eClick &8» &7Change Item":
            openEquipmentTypeMenu({_p}, {_id}, "boots")
       
        make gui slot 21 with iron sword named "&e&lMain Hand" with lore "&7Current: %{npcs::%{_id}%::equipment::mainhand} ? "None"%", "", "&eClick &8» &7Change Item":
            openEquipmentTypeMenu({_p}, {_id}, "mainhand")
       
        # kalkan, tod
        make gui slot 30 with shield named "&e&lOff Hand" with lore "&7Current: %{npcs::%{_id}%::equipment::offhand} ? "None"%", "", "&eClick &8» &7Change Item":
            openEquipmentTypeMenu({_p}, {_id}, "offhand")
       
        if {npcs::%{_id}%::skull_texture} is set:
            set {_preview} to player head named "&d&lCurrent Head" with lore "&7Has custom texture"
            make gui slot 16 with {_preview}:
                stop
       
        make gui slot 15 with barrier named "&c&lClear All" with lore "&7Click to remove all equipment":
            loop "helmet", "chestplate", "leggings", "boots", "mainhand" and "offhand":
                set {npcs::%{_id}%::equipment::%loop-value%} to air
            updateNPCEquipment({_id})
            openNPCEquipmentMenu({_p}, {_id})
       
        make gui slot 31 with arrow named "&c&lBack" with lore "&7Return to NPC editor":
            openNPCEditMenu({_p}, {_id})
           
    open the last gui for {_p}

function openEquipmentTypeMenu(p: player, id: number, slot: text):
    create a gui with virtual chest inventory with 6 rows named "&8Select %{_slot}% Type":
        set {_items::*} to getValidItems({_slot})
        set {_index} to 0
       
        loop {_items::*}:
            set {_item} to loop-value
            make gui slot {_index} with {_item} named "&e&l%{_item}%" with lore "&7Click to select":
                if {_item} is leather helmet, leather chestplate, leather leggings or leather boots:
                    #openColorSelector({_p}, {_id}, {_slot}, {_item}) # crash 2?
                else:
                    set {npcs::%{_id}%::equipment::%{_slot}%} to {_item}
                    updateNPCEquipment({_id})
                    openNPCEquipmentMenu({_p}, {_id})
            add 1 to {_index}
       
        make gui slot 49 with arrow named "&c&lBack" with lore "&7Return to equipment menu":
            openNPCEquipmentMenu({_p}, {_id})
           
    open the last gui for {_p}
function updateNPCEquipment(id: number):
    set {_npc} to {npcs::%{_id}%::entity}
    if {_npc} is set:
        if {npcs::%{_id}%::skull_texture} is not set:
            {_npc}.getEquipment().setHelmet({npcs::%{_id}%::equipment::helmet})
        {_npc}.getEquipment().setChestplate({npcs::%{_id}%::equipment::chestplate})
        {_npc}.getEquipment().setLeggings({npcs::%{_id}%::equipment::leggings})
        {_npc}.getEquipment().setBoots({npcs::%{_id}%::equipment::boots})
        {_npc}.getEquipment().setItemInMainHand({npcs::%{_id}%::equipment::mainhand})
        {_npc}.getEquipment().setItemInOffHand({npcs::%{_id}%::equipment::offhand})

function getValidItems(slot: text) :: items:
    if {_slot} is "helmet":
        set {_items::*} to leather helmet, chainmail helmet, iron helmet, golden helmet and diamond helmet
        return {_items::*}
    else if {_slot} is "chestplate":
        set {_items::*} to leather chestplate, chainmail chestplate, iron chestplate, golden chestplate and diamond chestplate
        return {_items::*}
    else if {_slot} is "leggings":
        set {_items::*} to leather leggings, chainmail leggings, iron leggings, golden leggings and diamond leggings
        return {_items::*}
    else if {_slot} is "boots":
        set {_items::*} to leather boots, chainmail boots, iron boots, golden boots and diamond boots
        return {_items::*}
    else if {_slot} is "mainhand":
        set {_items::*} to wooden sword, stone sword, iron sword, golden sword, diamond sword, bow, crossbow, trident, wooden axe, stone axe, iron axe, golden axe and diamond axe
        return {_items::*}
    else if {_slot} is "offhand":
        set {_items::*} to shield and totem of undying
        return {_items::*}

function updateNPCSkull(id: number):
    set {_npc} to {npcs::%{_id}%::entity}
    if {_npc} is set:
        if {npcs::%{_id}%::skull_texture} is set:
            set {_head} to player head
            set {_meta} to {_head}.getItemMeta()
            set {_uuid} to UUID.randomUUID()
            set {_profile} to new GameProfile({_uuid}, "CustomHead")
            set {_property} to new Property("textures", {npcs::%{_id}%::skull_texture}, "")
            {_profile}.getProperties().put("textures", {_property})
           
            set {_field} to {_meta}.getClass().getDeclaredField("profile")
            {_field}.setAccessible(true)
            {_field}.set({_meta}, {_profile})
           
            {_head}.setItemMeta({_meta})
            {_npc}.getEquipment().setHelmet({_head})
           
            send "&aApplied skull texture to NPC %{_id}%" to console
            send "&7Texture: %{npcs::%{_id}%::skull_texture}%" to console
        else:
            {_npc}.getEquipment().setHelmet(air)

command /npcskull [<number>] [<text>]:
    permission: admin.npc
    trigger:
        if arg-1 is not set:
            send "&c/npcskull <id> [texture]" to player
            stop
           
        if {npcs::%arg-1%::entity} is not set:
            send "&cNo NPC found with ID %arg-1%" to player
            stop
           
        if arg-2 is set:
            set {npcs::%arg-1%::skull_texture} to arg-2
            updateNPCSkull(arg-1)
            send "&aUpdated skull texture for NPC %arg-1%" to player
        else:
            send "&eCurrent skull texture for NPC %arg-1%: %{npcs::%arg-1%::skull_texture} ? "None"%" to player

on place:
    if event-item is blaze rod:
        if name of event-item contains "Moving NPC #":
            cancel event
            set {_id} to {npc.moving::%player's uuid%}
            if {_id} is set:
                set {npcs::%{_id}%::location} to location of event-block
                set {_npc} to event-block's world.spawn({npcs::%{_id}%::location}, ArmorStand.class)
                {_npc}.setCustomName(colored {npcs::%{_id}%::name})
                {_npc}.setCustomNameVisible(true)
                {_npc}.setVisible(true)
                {_npc}.setGravity(false)
                {_npc}.setSmall(false)
               
                set {_hint_loc} to {npcs::%{_id}%::location}.clone()
                {_hint_loc}.add(2, 0, 0)
                set {_hint} to event-block's world.spawn({_hint_loc}, ArmorStand.class)
                {_hint}.setCustomName(colored "&7&o(Right-click to interact!)")
                {_hint}.setCustomNameVisible(false)
                {_hint}.setVisible(false)
                {_hint}.setGravity(false)
                {_hint}.setMarker(true)
                {_hint}.setSmall(true)
               
                set {npcs::%{_id}%::entity} to {_npc}
                set {npcs::%{_id}%::hint} to {_hint}
               
                updateNPCEquipment({_id})
                if {npcs::%{_id}%::skull_texture} is set:
                    updateNPCSkull({_id})
               
                delete {npc.moving::%player's uuid%}
                remove blaze rod named "&6Moving NPC #%{_id}%" from player's inventory
                send "&aNPC moved successfully!" to player
                openNPCEditMenu(player, {_id})

on right click:
    if player's tool is blaze rod:
        if name of player's tool contains "Moving NPC #":
            set {_id} to {npc.moving::%player's uuid%}
            if {_id} is set:
                set {_npc} to {npcs::%{_id}%::location}.getWorld().spawn({npcs::%{_id}%::location}, ArmorStand.class)
                {_npc}.setCustomName(colored {npcs::%{_id}%::name})
                {_npc}.setCustomNameVisible(true)
                {_npc}.setVisible(true)
                {_npc}.setGravity(false)
                {_npc}.setSmall(false)
               
                set {_hint_loc} to {npcs::%{_id}%::location}.clone()
                {_hint_loc}.add(2, 0, 0)
                set {_hint} to {npcs::%{_id}%::location}.getWorld().spawn({_hint_loc}, ArmorStand.class)
                {_hint}.setCustomName(colored "&7&o(Right-click to interact!)")
                {_hint}.setCustomNameVisible(false)
                {_hint}.setVisible(false)
                {_hint}.setGravity(false)
                {_hint}.setMarker(true)
                {_hint}.setSmall(true)
               
                set {npcs::%{_id}%::entity} to {_npc}
                set {npcs::%{_id}%::hint} to {_hint}
               
                updateNPCEquipment({_id})
                if {npcs::%{_id}%::skull_texture} is set:
                    updateNPCSkull({_id})
               
                delete {npc.moving::%player's uuid%}
                remove blaze rod named "&6Moving NPC #%{_id}%" from player's inventory # crash aq?
                send "&cNPC move cancelled" to player
                openNPCEditMenu(player, {_id})

on quit:
    if {npc.moving::%player's uuid%} is set:
        set {_id} to {npc.moving::%player's uuid%}
        set {_npc} to {npcs::%{_id}%::location}.getWorld().spawn({npcs::%{_id}%::location}, ArmorStand.class)
        {_npc}.setCustomName(colored {npcs::%{_id}%::name})
        {_npc}.setCustomNameVisible(true)
        {_npc}.setVisible(true)
        {_npc}.setGravity(false)
        {_npc}.setSmall(false)
       
        set {_hint_loc} to {npcs::%{_id}%::location}.clone()
        {_hint_loc}.add(2, 0, 0)
        set {_hint} to {npcs::%{_id}%::location}.getWorld().spawn({_hint_loc}, ArmorStand.class)
        {_hint}.setCustomName(colored "&7&o(Right-click to interact!)")
        {_hint}.setCustomNameVisible(false)
        {_hint}.setVisible(false)
        {_hint}.setGravity(false)
        {_hint}.setMarker(true)
        {_hint}.setSmall(true)
       
        set {npcs::%{_id}%::entity} to {_npc}
        set {npcs::%{_id}%::hint} to {_hint}
        delete {npc.moving::%player's uuid%}
 
Tamamen deney amaçlı yaptığım bir proje oldu, yıllardır Skript ile alakalı hiçbir şey yapmıyordum. /npc komudu ile NPC oluşturabilir, giydirebilir, custom texture skull ekleyebilir ve diyalog ekleyebilirsiniz. Performans konusunda emin değilim, dediğim gibi production-level bir kod değil sadece kendimi denemek ve Skript'e tekrar alışabilmek için yaptığım bir proje.

Gerekli Addonlar: skript-reflect, skript-gui, SkBee (?, gerekli olmayabilir), ProtocolLib
GitHub:
Değerli ziyaretçimiz, içeriği görebilmek için şimdi giriş yapın veya kayıt olun.


Kod:
Kod:
import:
    org.bukkit.entity.EntityType
    org.bukkit.entity.ArmorStand
    org.bukkit.Location
    org.bukkit.inventory.meta.SkullMeta
    com.mojang.authlib.GameProfile
    com.mojang.authlib.properties.Property
    java.util.UUID

function createNPC(name: text, world: text, x: number, y: number, z: number, skin: text) :: number:
    set {_location} to new Location(world "%{_world}%", {_x}, {_y}, {_z})
  
    if {npc.lastid} is not set:
        set {npc.lastid} to 0
    add 1 to {npc.lastid}
    set {_id} to {npc.lastid}
  
    set {_hint_loc} to {_location}.clone()
    {_hint_loc}.add(2, 0, 0) # x,y,z - h ihtiyac var cunku location clone ettigimizde armor standin basladigi yeri baz aliyoruz.
    set {_hint} to {_location}.getWorld().spawn({_hint_loc}, ArmorStand.class)
    {_hint}.setCustomName(colored "&7&o(Right-click to interact!)")
    {_hint}.setCustomNameVisible(false)
    {_hint}.setVisible(false)
    {_hint}.setGravity(false)
    {_hint}.setMarker(true)
    {_hint}.setSmall(true)
  
    set {_npc} to {_location}.getWorld().spawn({_location}, ArmorStand.class)
    {_npc}.setCustomName(colored {_name})
    {_npc}.setCustomNameVisible(true)
    {_npc}.setVisible(true)
    {_npc}.setGravity(false)
    {_npc}.setSmall(false)
  
    set {npcs::%{_id}%::name} to {_name}
    set {npcs::%{_id}%::location} to {_location}
    set {npcs::%{_id}%::entity} to {_npc}
    set {npcs::%{_id}%::hint} to {_hint}
    clear {npcs::%{_id}%::stages::*}
  
    set {npcs::%{_id}%::equipment::helmet} to air
    set {npcs::%{_id}%::equipment::chestplate} to air
    set {npcs::%{_id}%::equipment::leggings} to air
    set {npcs::%{_id}%::equipment::boots} to air
    set {npcs::%{_id}%::equipment::mainhand} to air
    set {npcs::%{_id}%::equipment::offhand} to air
  
    delete {npcs::%{_id}%::skull_texture}
  
    return {_id}

function addNPCStages(id: number, stages: texts):
    send "&e[Debug] Adding stages to NPC %{_id}%" to console
    clear {npcs::%{_id}%::stages::*}
    loop {_stages::*}:
        add loop-value to {npcs::%{_id}%::stages::*}
    send "&a[Debug] Added %size of {npcs::%{_id}%::stages::*}% stages: %{npcs::%{_id}%::stages::*}%" to console

function isNPCDebug(p: player) :: boolean:
    set {_uuid} to "%{_p}'s uuid%"
    if {npc.debug::%{_uuid}%} is set:
        return true
    return false

function toggleNPCDebug(p: player):
    set {_uuid} to "%{_p}'s uuid%"
    if {npc.debug::%{_uuid}%} is set:
        delete {npc.debug::%{_uuid}%}
        send "&c[NPC] Debug mode disabled" to {_p}
    else:
        set {npc.debug::%{_uuid}%} to true
        send "&a[NPC] Debug mode enabled" to {_p}

command /npcdebug:
    permission: op
    trigger:
        toggleNPCDebug(player)

on rightclick on entity:
    if event-entity is an armor stand:
        set {_clicked} to event-entity
        set {_debug} to isNPCDebug(player)
        if {_debug} is true:
            send "&b[Debug] Clicked armor stand with UUID: %{_clicked}.getUniqueId()%" to player
            send "&e[Debug] Checking stored NPCs..." to player
            send "&e[Debug] Current NPCs in storage: %{npc.lastid}% total" to player
      
        loop {npc.lastid} times:
            set {_id} to loop-number
            if {_debug} is true:
                send "&e[Debug] Checking NPC ID: %{_id}%" to player
          
            if {npcs::%{_id}%::entity} is set:
                set {_npc} to {npcs::%{_id}%::entity}
                if {_debug} is true:
                    send "&e[Debug] Comparing entities:" to player
                    send "&7 - Clicked UUID: %{_clicked}.getUniqueId()%" to player
                    send "&7 - Stored UUID: %{_npc}.getUniqueId()%" to player
              
                if {_clicked}.getUniqueId() is {_npc}.getUniqueId():
                    if {_debug} is true:
                        send "&a[Debug] Found NPC match! ID: %{_id}%" to player
                  
                    if {npc.talking::%{_id}%::%player's uuid%} is set:
                        if {_debug} is true:
                            send "&c[Debug] NPC is already talking to this player" to player
                        stop

                    if {npcs::%{_id}%::locked} is true:
                        if {_debug} is true:
                            send "&c[Debug] This NPC is locked" to player
                        stop
                  
                    set {player.npc.stage::%{_id}%} to 1
                    playNPCDialog({_id}, player)
                    stop

function playNPCDialog(id: number, p: player):
    set {npc.talking::%{_id}%::%{_p}'s uuid%} to true
  
    set {_stage} to {player.npc.stage::%{_id}%}
    set {_total} to size of {npcs::%{_id}%::stages::*}
  
    while {_stage} <= {_total}:
        set {_message} to {npcs::%{_id}%::stages::%{_stage}%}
        set {_name} to {npcs::%{_id}%::name}
      
        send "&7[%{_stage}%/%{_total}%] %colored {_name}%&a: %{_message}%" to {_p}
      
        add 1 to {_stage}
        if {_stage} <= {_total}:
            wait 1.3 seconds
  
    delete {player.npc.stage::%{_id}%}
    delete {npc.talking::%{_id}%::%{_p}'s uuid%}

on damage of armor stand:
    loop {npcs::*}:
        set {_id} to loop-index parsed as number
        if {_id} is set:
            if {npcs::%{_id}%::entity} is victim:
                cancel event
                stop

on break:
    if event-entity is an armor stand:
        loop {npcs::*}:
            set {_id} to loop-index parsed as number
            if {_id} is set:
                if {npcs::%{_id}%::entity} is event-entity:
                    cancel event
                    stop

on explosion prime:
    loop {npcs::*}:
        set {_id} to loop-index parsed as number
        if {_id} is set:
            set {_npc} to {npcs::%{_id}%::entity}
            if {_npc} is set:
                if event-entity's location.distance({_npc}.getLocation()) <= 5:
                    cancel event

on target:
    loop {npcs::*}:
        set {_id} to loop-index parsed as number
        if {_id} is set:
            if {npcs::%{_id}%::entity} is target:
                cancel event

on entity teleport:
    if event-entity is an armor stand:
        loop {npcs::*}:
            set {_id} to loop-index parsed as number
            if {_id} is set:
                if {npcs::%{_id}%::entity} is event-entity:
                    cancel event

on right click:
    if clicked entity is an armor stand:
        loop {npcs::*}:
            set {_id} to loop-index parsed as number
            if {_id} is set:
                if {npcs::%{_id}%::entity} is clicked entity:
                    cancel event
                    stop

on left click:
    if clicked entity is an armor stand:
        loop {npcs::*}:
            set {_id} to loop-index parsed as number
            if {_id} is set:
                if {npcs::%{_id}%::entity} is clicked entity:
                    cancel event
                    stop

on skript load:
    set {_id} to createNPC("&aTrader Jack", "world", 100, 64, 100, "MHF_Villager")
    addNPCStages({_id}, ("Welcome to my shop!", "I have the best deals in town!", "Check out my special offers!", "Have a great day!"))

    set {_id} to createNPC("&cCity Guard", "world", 105, 64, 105, "MHF_Guard")
    addNPCStages({_id}, ("Halt! State your business.", "Keep the peace, citizen.", "Stay out of trouble.", "Move along."))

on load:
    delete {npc.creating::*}
    delete {npc.editing::*}

function openNPCCreationMenu(p: player):
    create a gui with virtual chest inventory with 3 rows named "&8NPC Creation Menu":
        make gui slot 11 with name tag named "&a&lCreate New NPC" with lore "&7Click to create a new NPC", "&7at your current location":
            close {_p}'s inventory
            set {npc.creating::%{_p}'s uuid%::state} to "name"
            send "&aEnter the name for the new NPC in chat:" to {_p}
            send "&7(Type 'cancel' to cancel)" to {_p}
          
        make gui slot 13 with book named "&6&lEdit Existing NPCs" with lore "&7Click to manage existing NPCs":
            openNPCListMenu({_p})
          
        make gui slot 15 with barrier named "&c&lClose Menu" with lore "&7Click to close this menu":
            close {_p}'s inventory
          
    open the last gui for {_p}

function openNPCEditMenu(p: player, id: number):
    create a gui with virtual chest inventory with 6 rows named "&8Edit NPC #%{_id}%":
        make gui slot 13 with name tag named "&e&l%{npcs::%{_id}%::name}%" with lore "&7ID: &e%{_id}%", "&7Stages: &e%size of {npcs::%{_id}%::stages::*}%":
            stop
          
        make gui slot 29 with book named "&a&lEdit Dialog" with lore "&7Click to edit NPC's dialog stages":
            openNPCStagesMenu({_p}, {_id})
          
        make gui slot 31 with diamond chestplate named "&b&lEquipment" with lore "&7Click to edit NPC's equipment":
            openNPCEquipmentMenu({_p}, {_id})
          
        make gui slot 32 with blaze rod named "&6&lMove NPC" with lore "&7Click to move this NPC", "&7to a new location":
            close {_p}'s inventory
            set {npc.moving::%{_p}'s uuid%} to {_id}
            give blaze rod named "&6Moving NPC #%{_id}%" with lore "&7Place to move the NPC", "&7Right-click to cancel" to {_p}
            {npcs::%{_id}%::entity}.remove()
            {npcs::%{_id}%::hint}.remove()
            send "&eRight-click with the blaze rod to cancel" to {_p}
          
        make gui slot 33 with ender pearl named "&5&lTeleport" with lore "&7Click to teleport to NPC":
            teleport {_p} to {npcs::%{_id}%::location}
            close {_p}'s inventory
          
        make gui slot 30 with player head named "&d&lChange Head" with lore "&7Current: %{npcs::%{_id}%::skull_texture} ? "Default"%", "", "&eClick &8» &7Set custom head":
            close {_p}'s inventory
            set {npc.editing::%{_p}'s uuid%::state} to "skull"
            set {npc.editing::%{_p}'s uuid%::npc_id} to {_id}
            send "&aEnter the skull texture value:" to {_p}
            send "&7(Type 'cancel' to cancel, 'reset' to remove custom head)" to {_p}
          
        make gui slot 49 with arrow named "&c&lBack" with lore "&7Return to NPC list":
            openNPCListMenu({_p})
          
    open the last gui for {_p}

function openNPCListMenu(p: player):
    create a gui with virtual chest inventory with 6 rows named "&8NPC List":
        set {_slot} to 0
        loop {npc.lastid} times:
            set {_id} to loop-number
            if {npcs::%{_id}%::entity} is set:
                set {_locked} to ""
                if {npcs::%{_id}%::locked} is true:
                    set {_locked} to " &c[LOCKED]"
                make gui slot {_slot} with blaze rod named "&e&l%{npcs::%{_id}%::name}%%{_locked}%" with lore "&7ID: &e%{_id}%", "&7Click to edit":
                    openNPCEditMenu({_p}, {_id})
                add 1 to {_slot}
              
        make gui slot 49 with emerald named "&a&lCreate New NPC" with lore "&7Click to create a new NPC":
            close {_p}'s inventory
            set {npc.creating::%{_p}'s uuid%::state} to "name"
            send "&aEnter the name for the new NPC in chat:" to {_p}
            send "&7(Type 'cancel' to cancel)" to {_p}
          
    open the last gui for {_p}

function openNPCStagesMenu(p: player, id: number):
    create a gui with virtual chest inventory with 6 rows named "&8Edit NPC #%{_id}% Stages":
        set {_slot} to 0
      
        loop {npcs::%{_id}%::stages::*}:
            make gui slot {_slot} with paper named "&e&lStage #%{_slot}+1%" with lore "&7Message: %loop-value%", "", "&eLeft-Click &7to edit", "&cRight-Click &7to remove":
                if click type is right mouse button:
                    delete {npcs::%{_id}%::stages::%{_slot}+1%}
                    openNPCStagesMenu({_p}, {_id})
                else if click type is left mouse button:
                    close {_p}'s inventory
                    set {npc.editing::%{_p}'s uuid%::state} to "edit_stage"
                    set {npc.editing::%{_p}'s uuid%::npc_id} to {_id}
                    set {npc.editing::%{_p}'s uuid%::stage_num} to {_slot}+1
                    send "&aEnter the new message for this stage in chat:" to {_p}
                    send "&7(Type 'cancel' to cancel)" to {_p}
            add 1 to {_slot}
      
        make gui slot 48 with emerald named "&a&lAdd New Stage" with lore "&7Click to add a new stage":
            close {_p}'s inventory
            set {npc.editing::%{_p}'s uuid%::state} to "add_stage"
            set {npc.editing::%{_p}'s uuid%::npc_id} to {_id}
            send "&aEnter the message for the new stage in chat:" to {_p}
            send "&7(Type 'cancel' to cancel)" to {_p}
          
        make gui slot 49 with arrow named "&c&lBack to NPC List" with lore "&7Click to return to NPC list":
            openNPCEditMenu({_p}, {_id})
          
    open the last gui for {_p}

on chat:
    if {npc.creating::%player's uuid%::state} is set:
        cancel event
      
        if message is "cancel":
            delete {npc.creating::%player's uuid%::*}
            send "&cNPC creation cancelled" to player
            stop
      
        if {npc.creating::%player's uuid%::state} is "name":
            set {npc.creating::%player's uuid%::name} to colored message
            set {_id} to createNPC(message, player.getWorld().getName(), player.getLocation().getX(), player.getLocation().getY(), player.getLocation().getZ(), "MHF_Villager")
          
            if {_id} is set:
                delete {npc.creating::%player's uuid%::*}
                send "&aSuccessfully created NPC with ID: %{_id}%" to player
                send "&eNow opening stage editor..." to player
                wait 1 tick
                openNPCStagesMenu(player, {_id})
            else:
                delete {npc.creating::%player's uuid%::*}
                send "&cFailed to create NPC! Please try again." to player
            stop
  
    if {npc.editing::%player's uuid%::state} is "edit_stage":
        cancel event
      
        if message is "cancel":
            delete {npc.editing::%player's uuid%::*}
            send "&cStage editing cancelled" to player
            stop
          
        set {_id} to {npc.editing::%player's uuid%::npc_id}
        set {_stage} to {npc.editing::%player's uuid%::stage_num}
      
        set {npcs::%{_id}%::stages::%{_stage}%} to message
        delete {npc.editing::%player's uuid%::*}
        send "&aStage updated successfully!" to player
        wait 1 tick
        openNPCStagesMenu(player, {_id})
      
    if {npc.editing::%player's uuid%::state} is "add_stage":
        cancel event
      
        if message is "cancel":
            delete {npc.editing::%player's uuid%::*}
            send "&cStage addition cancelled" to player
            stop
          
        set {_id} to {npc.editing::%player's uuid%::npc_id}
        add message to {npcs::%{_id}%::stages::*}
        delete {npc.editing::%player's uuid%::*}
        send "&aNew stage added successfully!" to player
        wait 1 tick
        openNPCStagesMenu(player, {_id})
  
    if {npc.editing::%player's uuid%::state} is "skull":
        cancel event
        set {_id} to {npc.editing::%player's uuid%::npc_id}
      
        if message is "cancel":
            delete {npc.editing::%player's uuid%::*}
            send "&cSkull editing cancelled" to player
            openNPCEditMenu(player, {_id})
            stop
          
        if message is "reset":
            delete {npcs::%{_id}%::skull_texture}
            delete {npc.editing::%player's uuid%::*}
            send "&aRemoved custom skull!" to player
            updateNPCSkull({_id})
            openNPCEditMenu(player, {_id})
            stop
          
        set {npcs::%{_id}%::skull_texture} to message
        delete {npc.editing::%player's uuid%::*}
        send "&aSkull texture updated!" to player
        updateNPCSkull({_id})
        openNPCEditMenu(player, {_id})
        stop

command /createnpc:
    permission: admin.createnpc
    trigger:
        openNPCCreationMenu(player)

command /checknpc [<number>]:
    permission: admin.createnpc
    trigger:
        if arg-1 is set:
            send "&eChecking NPC %arg-1%:" to player
            send "&7Name: %{npcs::%arg-1%::name}%" to player
            send "&7Entity: %{npcs::%arg-1%::entity}%" to player
            send "&7Stages: %{npcs::%arg-1%::stages::*}%" to player
            send "&7Total stages: %size of {npcs::%arg-1%::stages::*}%" to player
        else:
            loop {npcs::*}:
                set {_id} to loop-index parsed as number
                send "&eNPC %{_id}%:" to player
                send "&7Name: %{npcs::%{_id}%::name}%" to player
                send "&7Stages: %{npcs::%{_id}%::stages::*}%" to player

command /npc [<text>] [<number>] [<text>]:
    aliases: npca
    permission: admin.npc
    trigger:
        if arg-1 is not set:
            openNPCMainMenu(player)
            stop
          
        if arg-1 is "create":
            openNPCCreationMenu(player)
          
        else if arg-1 is "list":
            openNPCListMenu(player)
          
        else if arg-1 is "edit" or "e":
            if arg-2 is not set:
                send "&c/npc edit <id>" to player
                stop
            if {npcs::%arg-2%::entity} is not set:
                send "&cNo NPC found with ID %arg-2%" to player
                stop
            openNPCEditMenu(player, arg-2)
          
        else if arg-1 is "wipe":
            set {_count} to 0
            loop {npc.lastid} times:
                set {_id} to loop-number
                if {npcs::%{_id}%::entity} is set:
                    add 1 to {_count}
                    {npcs::%{_id}%::entity}.remove()
                    {npcs::%{_id}%::hint}.remove()
                    delete {npcs::%{_id}%::*}
            delete {npc.lastid}
            send "&cRemoved %{_count}% NPCs from the world" to player
          
        else if arg-1 is "delete" or "del":
            if arg-2 is not set:
                send "&c/npc delete <id>" to player
                stop
            if {npcs::%arg-2%::entity} is not set:
                send "&cNo NPC found with ID %arg-2%" to player
                stop
            {npcs::%arg-2%::entity}.remove()
            {npcs::%arg-2%::hint}.remove()
            delete {npcs::%arg-2%::*}
            send "&cDeleted NPC with ID %arg-2%" to player
          
        else if arg-1 is "lock":
            if arg-2 is not set:
                send "&c/npc lock <id>" to player
                stop
            if {npcs::%arg-2%::entity} is not set:
                send "&cNo NPC found with ID %arg-2%" to player
                stop
            if {npcs::%arg-2%::locked} is true:
                delete {npcs::%arg-2%::locked}
                send "&aUnlocked NPC with ID %arg-2%" to player
            else:
                set {npcs::%arg-2%::locked} to true
                send "&cLocked NPC with ID %arg-2%" to player
              
        else if arg-1 is "skull":
            if arg-2 is not set:
                send "&c/npc skull <id> [texture]" to player
                stop
            if {npcs::%arg-2%::entity} is not set:
                send "&cNo NPC found with ID %arg-2%" to player
                stop
            if arg-3 is set:
                set {npcs::%arg-2%::skull_texture} to arg-3
                updateNPCSkull(arg-2)
                send "&aUpdated skull texture for NPC %arg-2%" to player
            else:
                send "&eCurrent skull texture for NPC %arg-2%: %{npcs::%arg-2%::skull_texture} ? "None"%" to player
              
        else if arg-1 is "help":
            send "" to player
            send "&e&lNPC Commands:" to player
            send "&7/npc &8» &fOpen main NPC menu" to player
            send "&7/npc create &8» &fCreate new NPC" to player
            send "&7/npc list &8» &fList all NPCs" to player
            send "&7/npc edit <id> &8» &fEdit NPC" to player
            send "&7/npc delete <id> &8» &fDelete NPC" to player
            send "&7/npc lock <id> &8» &fLock/unlock NPC" to player
            send "&7/npc skull <id> [texture] &8» &fSet NPC skull" to player
            send "&7/npc wipe &8» &fDelete all NPCs" to player
            send "" to player
          
        else:
            send "&cUnknown argument. Use /npc help for commands" to player

function openNPCMainMenu(p: player):
    create a gui with virtual chest inventory with 3 rows named "&8NPC Management":
        make gui slot 10 with emerald named "&a&lCreate NPC" with lore "&7Click to create a new NPC", "&7at your current location":
            openNPCCreationMenu({_p})
          
        make gui slot 12 with book named "&e&lNPC List" with lore "&7Click to view and edit", "&7all existing NPCs":
            openNPCListMenu({_p})
          
        make gui slot 14 with redstone named "&c&lQuick Actions" with lore "&7Click to access quick", "&7management options":
            openNPCQuickActionsMenu({_p})
          
        make gui slot 16 with paper named "&b&lHelp" with lore "&7Click to view commands", "&7and information":
            close {_p}'s inventory
            make player execute command "npc help"
          
    open the last gui for {_p}

function openNPCQuickActionsMenu(p: player):
    create a gui with virtual chest inventory with 3 rows named "&8Quick Actions":
        make gui slot 11 with barrier named "&c&lWipe All NPCs" with lore "&7Click to remove all NPCs", "&7from the world", "", "&c&lWARNING: &7This cannot be undone!":
            close {_p}'s inventory
            make player execute command "npc wipe"
          
        set {_debug} to "&cOFF"
        if {npc.debug::%{_p}'s uuid%} is set:
            set {_debug} to "&aON"
        make gui slot 13 with redstone torch named "&e&lToggle Debug" with lore "&7Click to toggle debug mode", "&7Current: %{_debug}%":
            toggleNPCDebug({_p})
            openNPCQuickActionsMenu({_p})
          
        make gui slot 15 with arrow named "&7Back to Main Menu" with lore "&7Return to main menu":
            openNPCMainMenu({_p})
          
    open the last gui for {_p}

on quit:
    delete {npc.creating::%player's uuid%::*}
    delete {npc.editing::%player's uuid%::*}

function openNPCEquipmentMenu(p: player, id: number):
    create a gui with virtual chest inventory with 4 rows named "&8Equipment - %{npcs::%{_id}%::name}%":
        if {npcs::%{_id}%::equipment::helmet} is not set:
            set {npcs::%{_id}%::equipment::helmet} to air
        if {npcs::%{_id}%::equipment::chestplate} is not set:
            set {npcs::%{_id}%::equipment::chestplate} to air
        if {npcs::%{_id}%::equipment::leggings} is not set:
            set {npcs::%{_id}%::equipment::leggings} to air
        if {npcs::%{_id}%::equipment::boots} is not set:
            set {npcs::%{_id}%::equipment::boots} to air
        if {npcs::%{_id}%::equipment::mainhand} is not set:
            set {npcs::%{_id}%::equipment::mainhand} to air
        if {npcs::%{_id}%::equipment::offhand} is not set:
            set {npcs::%{_id}%::equipment::offhand} to air
      
        make gui slot 10 with leather helmet named "&e&lHelmet" with lore "&7Current: %{npcs::%{_id}%::equipment::helmet} ? "None"%", "", "&eClick &8» &7Change Item":
            openEquipmentTypeMenu({_p}, {_id}, "helmet")
      
        make gui slot 19 with leather chestplate named "&e&lChestplate" with lore "&7Current: %{npcs::%{_id}%::equipment::chestplate} ? "None"%", "", "&eClick &8» &7Change Item":
            openEquipmentTypeMenu({_p}, {_id}, "chestplate")
      
        make gui slot 28 with leather leggings named "&e&lLeggings" with lore "&7Current: %{npcs::%{_id}%::equipment::leggings} ? "None"%", "", "&eClick &8» &7Change Item":
            openEquipmentTypeMenu({_p}, {_id}, "leggings")
      
        make gui slot 12 with leather boots named "&e&lBoots" with lore "&7Current: %{npcs::%{_id}%::equipment::boots} ? "None"%", "", "&eClick &8» &7Change Item":
            openEquipmentTypeMenu({_p}, {_id}, "boots")
      
        make gui slot 21 with iron sword named "&e&lMain Hand" with lore "&7Current: %{npcs::%{_id}%::equipment::mainhand} ? "None"%", "", "&eClick &8» &7Change Item":
            openEquipmentTypeMenu({_p}, {_id}, "mainhand")
      
        # kalkan, tod
        make gui slot 30 with shield named "&e&lOff Hand" with lore "&7Current: %{npcs::%{_id}%::equipment::offhand} ? "None"%", "", "&eClick &8» &7Change Item":
            openEquipmentTypeMenu({_p}, {_id}, "offhand")
      
        if {npcs::%{_id}%::skull_texture} is set:
            set {_preview} to player head named "&d&lCurrent Head" with lore "&7Has custom texture"
            make gui slot 16 with {_preview}:
                stop
      
        make gui slot 15 with barrier named "&c&lClear All" with lore "&7Click to remove all equipment":
            loop "helmet", "chestplate", "leggings", "boots", "mainhand" and "offhand":
                set {npcs::%{_id}%::equipment::%loop-value%} to air
            updateNPCEquipment({_id})
            openNPCEquipmentMenu({_p}, {_id})
      
        make gui slot 31 with arrow named "&c&lBack" with lore "&7Return to NPC editor":
            openNPCEditMenu({_p}, {_id})
          
    open the last gui for {_p}

function openEquipmentTypeMenu(p: player, id: number, slot: text):
    create a gui with virtual chest inventory with 6 rows named "&8Select %{_slot}% Type":
        set {_items::*} to getValidItems({_slot})
        set {_index} to 0
      
        loop {_items::*}:
            set {_item} to loop-value
            make gui slot {_index} with {_item} named "&e&l%{_item}%" with lore "&7Click to select":
                if {_item} is leather helmet, leather chestplate, leather leggings or leather boots:
                    #openColorSelector({_p}, {_id}, {_slot}, {_item}) # crash 2?
                else:
                    set {npcs::%{_id}%::equipment::%{_slot}%} to {_item}
                    updateNPCEquipment({_id})
                    openNPCEquipmentMenu({_p}, {_id})
            add 1 to {_index}
      
        make gui slot 49 with arrow named "&c&lBack" with lore "&7Return to equipment menu":
            openNPCEquipmentMenu({_p}, {_id})
          
    open the last gui for {_p}
function updateNPCEquipment(id: number):
    set {_npc} to {npcs::%{_id}%::entity}
    if {_npc} is set:
        if {npcs::%{_id}%::skull_texture} is not set:
            {_npc}.getEquipment().setHelmet({npcs::%{_id}%::equipment::helmet})
        {_npc}.getEquipment().setChestplate({npcs::%{_id}%::equipment::chestplate})
        {_npc}.getEquipment().setLeggings({npcs::%{_id}%::equipment::leggings})
        {_npc}.getEquipment().setBoots({npcs::%{_id}%::equipment::boots})
        {_npc}.getEquipment().setItemInMainHand({npcs::%{_id}%::equipment::mainhand})
        {_npc}.getEquipment().setItemInOffHand({npcs::%{_id}%::equipment::offhand})

function getValidItems(slot: text) :: items:
    if {_slot} is "helmet":
        set {_items::*} to leather helmet, chainmail helmet, iron helmet, golden helmet and diamond helmet
        return {_items::*}
    else if {_slot} is "chestplate":
        set {_items::*} to leather chestplate, chainmail chestplate, iron chestplate, golden chestplate and diamond chestplate
        return {_items::*}
    else if {_slot} is "leggings":
        set {_items::*} to leather leggings, chainmail leggings, iron leggings, golden leggings and diamond leggings
        return {_items::*}
    else if {_slot} is "boots":
        set {_items::*} to leather boots, chainmail boots, iron boots, golden boots and diamond boots
        return {_items::*}
    else if {_slot} is "mainhand":
        set {_items::*} to wooden sword, stone sword, iron sword, golden sword, diamond sword, bow, crossbow, trident, wooden axe, stone axe, iron axe, golden axe and diamond axe
        return {_items::*}
    else if {_slot} is "offhand":
        set {_items::*} to shield and totem of undying
        return {_items::*}

function updateNPCSkull(id: number):
    set {_npc} to {npcs::%{_id}%::entity}
    if {_npc} is set:
        if {npcs::%{_id}%::skull_texture} is set:
            set {_head} to player head
            set {_meta} to {_head}.getItemMeta()
            set {_uuid} to UUID.randomUUID()
            set {_profile} to new GameProfile({_uuid}, "CustomHead")
            set {_property} to new Property("textures", {npcs::%{_id}%::skull_texture}, "")
            {_profile}.getProperties().put("textures", {_property})
          
            set {_field} to {_meta}.getClass().getDeclaredField("profile")
            {_field}.setAccessible(true)
            {_field}.set({_meta}, {_profile})
          
            {_head}.setItemMeta({_meta})
            {_npc}.getEquipment().setHelmet({_head})
          
            send "&aApplied skull texture to NPC %{_id}%" to console
            send "&7Texture: %{npcs::%{_id}%::skull_texture}%" to console
        else:
            {_npc}.getEquipment().setHelmet(air)

command /npcskull [<number>] [<text>]:
    permission: admin.npc
    trigger:
        if arg-1 is not set:
            send "&c/npcskull <id> [texture]" to player
            stop
          
        if {npcs::%arg-1%::entity} is not set:
            send "&cNo NPC found with ID %arg-1%" to player
            stop
          
        if arg-2 is set:
            set {npcs::%arg-1%::skull_texture} to arg-2
            updateNPCSkull(arg-1)
            send "&aUpdated skull texture for NPC %arg-1%" to player
        else:
            send "&eCurrent skull texture for NPC %arg-1%: %{npcs::%arg-1%::skull_texture} ? "None"%" to player

on place:
    if event-item is blaze rod:
        if name of event-item contains "Moving NPC #":
            cancel event
            set {_id} to {npc.moving::%player's uuid%}
            if {_id} is set:
                set {npcs::%{_id}%::location} to location of event-block
                set {_npc} to event-block's world.spawn({npcs::%{_id}%::location}, ArmorStand.class)
                {_npc}.setCustomName(colored {npcs::%{_id}%::name})
                {_npc}.setCustomNameVisible(true)
                {_npc}.setVisible(true)
                {_npc}.setGravity(false)
                {_npc}.setSmall(false)
              
                set {_hint_loc} to {npcs::%{_id}%::location}.clone()
                {_hint_loc}.add(2, 0, 0)
                set {_hint} to event-block's world.spawn({_hint_loc}, ArmorStand.class)
                {_hint}.setCustomName(colored "&7&o(Right-click to interact!)")
                {_hint}.setCustomNameVisible(false)
                {_hint}.setVisible(false)
                {_hint}.setGravity(false)
                {_hint}.setMarker(true)
                {_hint}.setSmall(true)
              
                set {npcs::%{_id}%::entity} to {_npc}
                set {npcs::%{_id}%::hint} to {_hint}
              
                updateNPCEquipment({_id})
                if {npcs::%{_id}%::skull_texture} is set:
                    updateNPCSkull({_id})
              
                delete {npc.moving::%player's uuid%}
                remove blaze rod named "&6Moving NPC #%{_id}%" from player's inventory
                send "&aNPC moved successfully!" to player
                openNPCEditMenu(player, {_id})

on right click:
    if player's tool is blaze rod:
        if name of player's tool contains "Moving NPC #":
            set {_id} to {npc.moving::%player's uuid%}
            if {_id} is set:
                set {_npc} to {npcs::%{_id}%::location}.getWorld().spawn({npcs::%{_id}%::location}, ArmorStand.class)
                {_npc}.setCustomName(colored {npcs::%{_id}%::name})
                {_npc}.setCustomNameVisible(true)
                {_npc}.setVisible(true)
                {_npc}.setGravity(false)
                {_npc}.setSmall(false)
              
                set {_hint_loc} to {npcs::%{_id}%::location}.clone()
                {_hint_loc}.add(2, 0, 0)
                set {_hint} to {npcs::%{_id}%::location}.getWorld().spawn({_hint_loc}, ArmorStand.class)
                {_hint}.setCustomName(colored "&7&o(Right-click to interact!)")
                {_hint}.setCustomNameVisible(false)
                {_hint}.setVisible(false)
                {_hint}.setGravity(false)
                {_hint}.setMarker(true)
                {_hint}.setSmall(true)
              
                set {npcs::%{_id}%::entity} to {_npc}
                set {npcs::%{_id}%::hint} to {_hint}
              
                updateNPCEquipment({_id})
                if {npcs::%{_id}%::skull_texture} is set:
                    updateNPCSkull({_id})
              
                delete {npc.moving::%player's uuid%}
                remove blaze rod named "&6Moving NPC #%{_id}%" from player's inventory # crash aq?
                send "&cNPC move cancelled" to player
                openNPCEditMenu(player, {_id})

on quit:
    if {npc.moving::%player's uuid%} is set:
        set {_id} to {npc.moving::%player's uuid%}
        set {_npc} to {npcs::%{_id}%::location}.getWorld().spawn({npcs::%{_id}%::location}, ArmorStand.class)
        {_npc}.setCustomName(colored {npcs::%{_id}%::name})
        {_npc}.setCustomNameVisible(true)
        {_npc}.setVisible(true)
        {_npc}.setGravity(false)
        {_npc}.setSmall(false)
      
        set {_hint_loc} to {npcs::%{_id}%::location}.clone()
        {_hint_loc}.add(2, 0, 0)
        set {_hint} to {npcs::%{_id}%::location}.getWorld().spawn({_hint_loc}, ArmorStand.class)
        {_hint}.setCustomName(colored "&7&o(Right-click to interact!)")
        {_hint}.setCustomNameVisible(false)
        {_hint}.setVisible(false)
        {_hint}.setGravity(false)
        {_hint}.setMarker(true)
        {_hint}.setSmall(true)
      
        set {npcs::%{_id}%::entity} to {_npc}
        set {npcs::%{_id}%::hint} to {_hint}
        delete {npc.moving::%player's uuid%}
Ne işe yarıyor tam anlamadım.
 
Ne işe yarıyor tam anlamadım.
1737618916484.webp

1737618939721.webp

1737618957209.webp


Wynncraft sunucusunda gördüm hoşuma gitti pas atmak için Skript ile yapmak istedim. NPC diyalogları yaratabilirsin.
 
Durum
Üzgünüz bu konu cevaplar için kapatılmıştır...

Hala Discord sunucumuza katılmadın mı?

Büyük bir topluluğun parçası ol, etkinliklere katıl ve özel hediyeler kazanma şansı yakala!

Şimdi Katıl
Üst