Paste #49119: Untitled Paste

Date: 2018/08/17 09:15:09 UTC-07:00
Type: Denizen Script

View Raw Paste Download This Paste
Copy Link


# Add NBT to items for # of sockets available / total
# Use NBT to manage sockets
# Use events to handle socket effects
# Numbered sockets on each item to handle types separately from current sockets
# Be sure to check each specific numbered slot to avoid exploits

### Relevant NBT values:
## Item (weapon/armor) NBT
# sockets_current (INTEGER) | Number of sockets currently on the item, filled or unfilled
# sockets_max (INTEGER) | Maximum number of sockets possible to exist on the item, whether existing or not
# sockets_can_add (BOOLEAN) | Whether it is possible to add any more sockets to the item, to be removed when sockets_current equals sockets_max
# sockets_open (BOOLEAN) | Whether an item has sockets that are empty
# socket#_type (VALUE) | The type of a socket, e.g. socket1_type "attack"/"defense"/"utility"
# socket#_gem (VALUE) | The gem inserted into a socket
# socket#_empty (BOOLEAN) | True if the numbered socket is empty
## Gem NBT
# gem_type (VALUE) | The type of a gem, e.g. "attack"/"defense"/"utility"
# gem_specific (VALUE) | The actual gem e.g. "crit_chance"/"health_on_hit"/"speed_on_hit"


nbt_craft_prevention:
    type: world
    debug: true
    events:
        on player crafts item:
        - if <context.recipe.filter[nbt[uncraftable]].size> >= 1
        {
            - determine cancelled
        }

SocketMaker:
    type: item
    material: nether_star[flags=li@HIDE_ENCHANTS;nbt=li@uncraftable/true]
    display name: "<&a>Purified Dark Matter"
    lore:
    - "<&6>This coalesced energy has been purged of the darkness inside. It now pulses and radiates in an unstoppable splendor."
    enchantments:
    - MENDING:1

sockets_sword_max:
    type: item
    material: diamond_sword[nbt=li@uncraftable/true|sockets_current/5|sockets_max/5|sockets_can_add/false|sockets_open/true|socket1_type/attack|socket1_empty/true|socket2_type/attack|socket2_empty/true|socket3_type/utility|socket3_empty/true|socket4_type/defense|socket4_empty/true|socket5_type/utility|socket5_empty/true]
    display name: "<&a>Socket Sword of Extreme Testing"
    lore:
    - "<&6>This sword is bonkers, lol."
    - "<&a>Sockets"
    - "EMPTY: ATTACK"
    - "EMPTY: ATTACK"
    - "EMPTY: UTILITY"
    - "EMPTY: DEFENSE"
    - "EMPTY: UTILITY"
    enchantments:
    - MENDING:1

sockets_sword_locked:
    type: item
    material: diamond_sword[nbt=li@uncraftable/true|sockets_current/0|sockets_max/5|sockets_can_add/true|sockets_open/true|socket1_type/attack|socket1_empty/true|socket2_type/attack|socket2_empty/true|socket3_type/utility|socket3_empty/true|socket4_type/defense|socket4_empty/true|socket5_type/utility|socket5_empty/true]
    display name: "<&a>Socket Sword of Extreme Testing"
    lore:
    - "<&6>This sword is bonkers, lol."
    - "<&a>This item has locked sockets!"
    enchantments:
    - MENDING:1

gem_critchance:
    type: item
    material: emerald[flags=li@HIDE_ATTRIBUTES|HIDE_ENCHANTS;nbt=li@uncraftable/true|gem_type/attack|gem_specific/crit_chance]
    display name: "<&a>Gem of Critical Chance"
    lore:
    - "<&a>Gem"
    - "<&c>Attack"
    - "<&6>Adds 0.5% chance of landing a critical hit to an item when socketed."
    enchantments:
    - MENDING:1

# Usage:
# - run add_socket def:<item>|<player>

add_socket:
    type: task
    debug: true
    speed: 0
    definitions: item|player
    script:
    - take <def[item]> from:<def[player].inventory>
    - nbt <def[item]> "sockets_current:<def[item].nbt[sockets_current].add[1]>" "save:edited"
    - if <entry[edited].nbt[sockets_current]||null> == <entry[edited].nbt[sockets_max]>
    {
        - nbt <entry[edited]> "sockets_can_add:!" "save:edited"
    }
    - give <entry[edited].new_item> to:<def[player].inventory>

prismatic_seer:
    type: assignment
    interact scripts:
    - 10 sockets
    actions:
        on assignment:
        - teleport npc <npc.anchor[primsaticseer]>
        - trigger name:proximity toggle:true
        - trigger name:chat toggle:true

prismatic_seer_format:
    type: format
    format: "<dark_green>Prismatic Seer<white><&co> <text>"

sockets:
    type: interact
    steps:
        "Player Seen*":
            proximity trigger:
                entry:
                    script:
                    - narrate "format:prismatic_seer_format" "Hello, adventurer. Have you come to unlock the potential of your items?"
                    - narrate "format:prismatic_seer_format" "With the right materials, I can help you manifest the latent powers of your items. Right click me to see my services."
                exit:
                    script:
                    - narrate "format:prismatic_seer_format" "Good luck, adventurer. I'll be here if you need me again."
            click trigger:
                script:
                - narrate "format:prismatic_seer_format" "Okay, here's what I have to offer."
                - wait 1s
                - inventory open d:in@prismatic_seer_menu
"prismatic_seer_menu":
    type: inventory
    title: Item Potential
    size: 45
    slots:
    - "[] [] [] [] [] [] [] [] []"
    - "[] [] [] [] [i@socket_add] [] [] [] []"
    - "[] [] [] [] [] [] [] [] []"
    - "[] [] [] [] [i@gem_add] [] [] [] []"
    - "[] [] [] [] [] [] [] [] []"
socket_add:
    type: item
    material: nether_star[flags=li@HIDE_ATTRIBUTES|HIDE_ENCHANTS]
    display name: "<&a>Add a socket to an item"
    lore:
    - "<&6>Requires <server.flag[SocketAddCost]> Purified Dark Matter and 1 Ingot of Crystallized Experience."
    enchantments:
    - MENDING:1
gem_add:
    type: item
    material: diamond[flags=li@HIDE_ATTRIBUTES|HIDE_ENCHANTS]
    display name: "<&a>Add a gem to a socket"
    lore:
    - "<&6>Requires an item with an open socket and a gem of the appropriate type"
    enchantments:
    - MENDING:1


prismatic_seer_inventory_handler:
    type: world
    events:
        on server start:
        - flag server SocketAddCost:250
        on player clicks in prismatic_seer_menu:
        - determine cancelled
        on player drags in prismatic_seer_menu:
        - determine cancelled
        on player clicks socket_add in prismatic_seer_menu:
        - inventory close d:in@prismatic_seer_menu
#        - narrate "format:prismatic_seer_format" "You clicked the Add a socket option!"
        - announce to_console <player.inventory.list_contents>
        - if <player.inventory.contains.scriptname[SocketMaker].quantity[<server.flag[SocketAddCost]>]> && <player.inventory.contains.scriptname[CrystallizedExperienceIngot].quantity[1]>
        {
#            - narrate "format:prismatic_seer_format" "You have enough bones for a special magic doodad!"
            - if <player.inventory.list_contents.filter[nbt[sockets_can_add]].size||null> >= 1
            {
                - take scriptname:SocketMaker quantity:<server.flag[SocketAddCost]>
                - take scriptname:CrystallizedExperienceIngot quantity:1
                - narrate "format:primsmatic_seer_format" "Okay, now select which of your valid items you'd like to add a socket to."
                - note "in@generic[title=Available Items;size=45;contents=<player.inventory.list_contents.filter[nbt[sockets_can_add]]>]" as:sockets_can_add.<player.uuid>
                - inventory open "d:in@sockets_can_add.<player.uuid>"
            }
            else
            {
                - narrate "format:prismatic_seer_format" "Sorry, it looks like you don't have any items I can add a socket to!"
            }
        }
        else
        {
            - narrate "format:prismatic_seer_format" "Sorry, you don't have enough materials for that!"
        }
        - narrate "format:prismatic_seer_format" "Right click me again if you'd like to choose another option!"
        on player clicks in inventory:
        - if <context.inventory.notable_name||null> != sockets_can_add.<player.uuid>
        {
            - queue clear
        }
        - if <context.item.has_nbt[sockets_can_add]>
        {
            - define item <context.item>
            - take <context.item> from:<player.inventory>
            - nbt <def[item]> "sockets_current:<def[item].nbt[sockets_current].add[1]>" "save:edited"
            - if <entry[edited].nbt[sockets_current]||null> == <entry[edited].nbt[sockets_max]>
            {
                - nbt <entry[edited]> "sockets_can_add:!" "save:edited"
            }
            - give <entry[edited].new_item> to:<player.inventory>
            - narrate "format:primsmatic_seer_format" "Congratulations, a socket has been added to your <def[item].formatted.to_titlecase>!"
        }
        else
        {
            - narrate "format:primsmatic_seer_format" "Something went wrong! It doesn't look like I can add a socket to that item."
        }

        on player clicks gem_add in prismatic_seer_menu:
        - inventory close d:in@prismatic_seer_menu
        - announce to_console <player.inventory.list_contents>
        # Add a check to ensure that there is a gem matching the available sockets before opening the inventory?
        # We're not stopping them from closing it so it might just not matter
        - if <player.inventory.list_contents.filter[nbt[sockets_open]].size||null> >= 1
        {
            - narrate "format:prismatic_seer_format" "Okay, now select which of your valid items you'd like to add a gem to."
            - flag player sockets_gem_add_item:!
            - flag player sockets_gem_add_item_types:!
            - note "in@generic[title=Available Items;size=45;contents=<player.inventory.list_contents.filter[nbt[sockets_open]]>]" as:sockets_open.<player.uuid>
            - inventory open "d:in@sockets_open.<player.uuid>"
        }
        else
        {
            - narrate "format:prismatic_seer_format" "Sorry, you don't have any items I can add a gem to!"
        }
## Use this if you want to make an inventory of only the items for which the player has gems in their inventory, rather than all items with open sockets
# This script will return a list of open socket types in the player's inventory
#        if <context.item.has_nbt[sockets_open]>
#        {
#            - define sockets_open_types li@
#            - foreach <player.inventory.list_contents>
#            {
#                - define item <def[value]>
#                - foreach <def[value].nbt_keys.filter[matches[socket[0-9]+\_type]]>
#                {
#                    - define sockets_open_types <def[sockets_open_types].include[<def[item].nbt[<def[value]>]>]>
#                }
#            }
#            - define sockets_open_types <def[sockets_open_types].deduplicate>
#            - announce to_console "sockets_open_types is <def[sockets_open_types]>"
#        }
        - narrate "format:prismatic_seer_format" "Right click me again if you'd like to choose another option!"
        # Inventory manager for list of items with open sockets to add a gem to
        on player clicks in notable:
        - if <context.inventory.notable_name||null> == sockets_open.<player.uuid>
        {
            - inventory close d:in@sockets_open.<player.uuid>
            - note remove as:in@sockets_open.<player.uuid> 
            - if <context.item.has_nbt[sockets_open]>
            {
                - define item_sockets_type_list li@
                - define item_sockets_empty li@
                - define valid_gems li@
                - define item_sockets_types li@
                - flag player sockets_gem_add_item:<context.item>
                # Should save a list of empty sockets e.g. "li@socket1_empty|socket2_empty" etc.
                - flag player sockets_gem_add_item_empty:!|:<context.item.nbt_keys.filter[matches[socket[0-9]+\_empty]]>
                - define item_sockets_empty <context.item.nbt_keys.filter[matches[socket[0-9]+\_empty]]>
                # Returns the empty socket nbt keys, swapped to "type" e.g. "li@socket1_type|socket2_type" etc.
                - define item_sockets_type_list <def[item_sockets_empty].parse[replace[empty].with[type]]>
                # Should save a list of empty socket type keys e.g. "li@socket1_type|socket2_type" etc.
                - flag player sockets_gem_add_item_slot_type_list:<def[item_sockets_type_list]>
                - define item_sockets_type_list <def[item_sockets_type_list].deduplicate>
                - foreach <def[item_sockets_type_list]>
                {
                    - define valid_gems <def[valid_gems].include[<player.inventory.list_contents.filter[nbt[gem_type].is[==].to[<context.item.nbt[<def[value]>]>]]||null>]>
                    - define item_sockets_types <def[item_sockets_types].include[<context.item.nbt[<def[value]>]>]>
                }
                - flag player sockets_gem_add_item_types:!|:<def[item_sockets_types]>
                - define valid_gems <def[valid_gems].deduplicate>
                - if <def[valid_gems].size> >= 1
                {
                    - narrate "format:prismatic_seer_format" "Okay, here are the gems you can add to that item."
                    # Saves a list of empty socket type keys
                    #- flag player sockets_gem_add_item_types:<def[item_sockets_type_list]>
                    - note "in@generic[title=Available Gems;size=45;contents=<def[valid_gems]>]" as:sockets_gem_add.<player.uuid>
                    - inventory open "d:in@sockets_gem_add.<player.uuid>"
                }
                else
                {
                    - narrate "format:prismatic_seer_format" "Something went wrong! It doesn't look like I can add a gem to that item."
                }
            }
            else
            {
                - narrate "format:prismatic_seer_format" "Something went wrong! It doesn't look like I can add a gem to that item."
            }
        }
        # Inventory manager for list of gems that can be added to the item in question
        - if <context.inventory.notable_name||null> != sockets_gem_add.<player.uuid>
        {
            - queue clear
        }
        - if <player.flag[sockets_gem_add_item_types].contains[<context.item.nbt[gem_type]||null>]>
        {
            # Returns "li@socket1_empty|socket2_empty" etc
            - foreach <player.flag[sockets_gem_add_item_empty].as_list>
            {
                - if <player.flag[sockets_gem_add_item].as_item.nbt[<def[value].replace[empty].with[type]>]> == <context.item.nbt[gem_type]||null>
                {
                    - inventory close d:in@sockets_gem_add.<player.uuid>
                    - note remove as:in@sockets_gem_add.<player.uuid>
                    - narrate "format:prismatic_seer_format" "This is where I tell you that I added the gem to the socket!"
                    - announce to_console "Hooray!"
                    - foreach stop
                }
            }
        }
        else
        {
            - inventory close d:in@sockets_gem_add.<player.uuid>
            - note remove as:in@sockets_gem_add.<player.uuid>
            - narrate "format:prismatic_seer_format" "Sorry, I can't add that gem to that item!"
        }