XR001's Loot Chest Script

xr001

New member
Jun 8, 2019
2
0
0
Hey folks!

This script is designed to let you quickly and easily create chests that players can find in game that are:
- Specific To Each Player, meaning each player will get their own set of items when opening it.
- Static so the same items appear such as important quest items.
- Randomized based on a loot table so that not every player will receive the same thing.
- Grief proof. If a griefer fills these chests with sand only they will see it!
- Capable of supporting any item you care to place in it (perfect if using PhatLoots or MythicDrops)
- Possibly filled with money! (This Script assumes you use Vault)

While the script has been overhauled recently, the below video is still relevant as how a chest is created has not changed.
Video: https://youtu.be/mD35sMh113s

To Use: Simply copy and paste the script provided into your scripts folder and that's it! The video explains how the command is used.
To add chests (as noted in the script) Use the following in any world script:

on player clicks chest in ChestCuboidName:
- determine passively cancelled
- run StaticChestTSK "def:FileName|ChestName|x,y,z,mapLocationofChest"

NOTE: If adding a Randomized Chest with tables, use RandomChestTSK in place of StaticChestTSK

Version: 1.1

BONUS!
This script, in order to function, requires the Player Data File system that we use on our server Esoteria. While below is not the full on script we use, it is the foundation of how it works. It essentially stores data that you can later access in tags (it is how the system knows if a player has opened a specific chest or not). It is easily expandable as presented!

Code:
###################################################################################################
##INSTRUCTIONS TO CREATE CHEST OPENING SCRIPT                                                    ##
##This is an extremely easy to use script that only requires small world script "on click" events##
##Make a cuboid where the chest to be opened occupies. Then in any World Script include this:    ##
##on player clicks chest in cuboidname:                                                          ##
##- determine passively cancelled                                                                ##
##- run staticchesttsk "def:FileName|ChestName|x,y,z,mapLocationofChest"                                           ##
##                                                                                               ##
##NOTE: If using a Random Chest with loot tables, specify randomchesttsk instead when running!   ##
###################################################################################################

PlayerDataHandler:
  type: world
  events:
    on player joins:
    - if <server.has_file[/PlayerData/<player.uuid>.yml]>:
      - yaml load:/PlayerData/<player.uuid>.yml id:<player.uuid>
      - queue clear
    - if <server.has_file[/PlayerData/<player.uuid>.yml].not>:
      - yaml create id:<player.uuid>
      - yaml savefile:/PlayerData/<player.uuid>.yml id:<player.uuid>
      - yaml load:/PlayerData/<player.uuid>.yml id:<player.uuid>
      - yaml id:<player.uuid> set Name:<player.name>
      - yaml id:<player.uuid> set OpenedChests.Total:0
      - yaml savefile:/PlayerData/<player.uuid>.yml id:<player.uuid>
    on player quits:
    - yaml savefile:/PlayerData/<player.uuid>.yml id:<player.uuid>
    - yaml unload id:<player.uuid>

SmallChestInv:
  type: inventory
  title: Chest
  size: 27
  slots:
  - "[] [] [] [] [] [] [] [] []"
  - "[] [] [] [] [] [] [] [] []"
  - "[] [] [] [] [] [] [] [] []"
  Procedural Items:
  - if <player.has_flag[LootChest]>:
    - if <yaml[<player.uuid>].read[OpenedChests].contains[<player.flag[LootChest].get[2]>]>:
      - determine <yaml[<player.uuid>].read[OpenedChests.<player.flag[LootChest].get[2]>.Items].get[1].to[27]>
    - else:
      - determine <yaml[<player.flag[LootChest].get[1]>].read[<player.flag[LootChest].get[2]>.Items].get[1].to[27]>
  - if <player.has_flag[RandomChest]>:
    - if <yaml[<player.uuid>].read[OpenedChests].contains[<player.flag[CurrentChest].get[1]>]>:
      - determine <yaml[<player.uuid>].read[OpenedChests.<player.flag[CurrentChest].get[1]>.Items].get[1].to[27]>
    - else:
      - determine <yaml[<player.flag[RandomChest].get[1]>].read[<player.flag[CurrentChest].get[1]>.<player.flag[RandomChest].get[2]>.Items].get[1].to[27]>

DoubleChestInv:
  type: inventory
  title: Large Chest
  size: 54
  slots:
  - "[] [] [] [] [] [] [] [] []"
  - "[] [] [] [] [] [] [] [] []"
  - "[] [] [] [] [] [] [] [] []"
  - "[] [] [] [] [] [] [] [] []"
  - "[] [] [] [] [] [] [] [] []"
  - "[] [] [] [] [] [] [] [] []"
  Procedural Items:
  - if <player.has_flag[LootChest]>:
    - if <yaml[<player.uuid>].read[OpenedChests].contains[<player.flag[LootChest].get[2]>]>:
      - determine <yaml[<player.uuid>].read[OpenedChests.<player.flag[LootChest].get[2]>.Items].get[1].to[27]>
    - else:
      - determine <yaml[<player.flag[LootChest].get[1]>].read[<player.flag[LootChest].get[2]>.Items].get[1].to[27]>
  - if <player.has_flag[RandomChest]>:
    - if <yaml[<player.uuid>].read[OpenedChests].contains[<player.flag[CurrentChest].get[1]>]>:
      - determine <yaml[<player.uuid>].read[OpenedChests.<player.flag[CurrentChest].get[1]>.Items].get[1].to[27]>
    - else:
      - determine <yaml[<player.flag[RandomChest].get[1]>].read[<player.flag[CurrentChest].get[1]>.<player.flag[RandomChest].get[2]>.Items].get[1].to[27]>

SaveChestIt:
  type: item
  material: writable_book
  display name: Click Here To Save
  lore:
  - "Click here to save this inventory."
  - "When you use /lootchest again, it will"
  - "populate with your last saved inventory."
  - "You can clear this saved inventory by"
  - "using /lootchest Delete"
  
LootChestInv:
  type: inventory
  title: Set Loot Chest Items
  size: 54
  slots:
  - "[] [] [] [] [] [] [] [] []"
  - "[] [] [] [] [] [] [] [] []"
  - "[] [] [] [] [] [] [] [] []"
  - "[] [] [] [] [] [] [] [] []"
  - "[] [] [] [] [] [] [] [] []"
  - "[] [] [] [] [] [] [] [] [i@SaveChestIt]"
  Procedural Items:
  - if <player.has_flag[EditLootChest]>:
    - determine <yaml[<player.flag[EditLootChest].get[1]>].read[<player.flag[EditLootChest].get[2]>.Items]>
    - queue clear
  - if <player.has_flag[SavedLootChest]>:
    - determine <yaml[<player.uuid>].read[SavedLootChest.Items]>
    - queue clear

RandomChestInv:
  type: inventory
  title: Set Random Chest Items
  size: 54
  slots:
  - "[] [] [] [] [] [] [] [] []"
  - "[] [] [] [] [] [] [] [] []"
  - "[] [] [] [] [] [] [] [] []"
  - "[] [] [] [] [] [] [] [] []"
  - "[] [] [] [] [] [] [] [] []"
  - "[] [] [] [] [] [] [] [] [i@SaveChestIt]"
  Procedural Items:
  - if <player.has_flag[EditRandomChest]>:
    - determine <yaml[<player.flag[EditRandomChest].get[1]>].read[<player.flag[EditRandomChest].get[2]>.<player.flag[EditRandomChest].get[3]>.Items]>
    - queue clear
  - if <player.has_flag[SavedLootChest]>:
    - determine <yaml[<player.uuid>].read[SavedLootChest.Items]>
    - queue clear

RandomChestProc:
  type: procedure
  script:
    - define Chance 0
    - foreach <yaml[<player.flag[RandomChest].get[1]>].list_keys[<player.flag[CurrentChest].get[1]>]> {
      - define Chance <def[Chance].add[<yaml[<player.flag[RandomChest].get[1]>].read[<player.flag[CurrentChest].get[1]>.<def[value]>.Chance]>]>
      }
    - define Random <util.random.decimal[0].to[<def[Chance]>]>
    - foreach <yaml[<player.flag[RandomChest].get[1]>].list_keys[<player.flag[CurrentChest].get[1]>]> {
      - define Table <yaml[<player.flag[RandomChest].get[1]>].read[<player.flag[CurrentChest].get[1]>.<def[value]>.Chance]>
      - if <def[Random]> <= <def[Table]> {
        - determine <def[value]>
        - queue clear
        } else {
        - define Random <def[Random].sub[<def[Table]>]>
        }
      }
          
LootChestCMD:
  type: command
  name: lootchest
  usage: /lootchest
  permission: denizen.randomchest
  description: "Use to create a Loot Chest. /lootchest [FileName] [ChestName] Table:[Name] Chance:[Decimal] Location:[cu@x,y,z,map|x,y,z,map] Money:[amount] [Edit] [Delete] To make a static chest, do not include Table: and Chance:. To Edit an existing Table or Static Chest, exclude Location: and add the Edit argument. Use the Delete argument by itself to clear a Saved Chest."
  script:
##Delete Arguments##
    - if <context.args.contains[Delete]> {
      - if <context.args.get[1]> == Delete {
        - yaml id:<player.uuid> set SavedLootChest:!
        - yaml savefile:/PlayerData/<player.uuid>.yml id:<player.uuid>
        - flag player SavedLootChest:!
        - narrate "Loot Chest Template Cleared."
        - queue clear
        }
      - if <server.has_file[/Chests/<context.args.get[1]>.yml].not> {
        - narrate "The file specified: <context.args.get[1]>, does not exist! Did you type in the name correctly?"
        - queue clear
        }
      - yaml load:/Chests/<context.args.get[1]>.yml id:<context.args.get[1]>
      - if <yaml[<context.args.get[1]>].contains[<context.args.get[2]>].not> {
        - narrate "The Chest: <context.args.get[2]>, does not exist in File: <context.args.get[1]>! Did you specify the correct file and chest names?"
        - queue clear
        }
      - if <context.args.filter[starts_with[Table:]].is_empty.not> {
        - yaml id:<context.args.get[1]> set <context.args.get[2]>:<-:<context.args.map_get[Table].split_by[<&co>]>
        - narrate "Table: <context.args.map_get[Table].split_by[<&co>]> deleted from Chest: <context.args.get[2]> in File: <context.args.get[1]>.yml"
        } else {
        - note remove as:<context.args.get[2]>
        - note remove as:<context.args.get[2]>chest
        - execute as_op "denizen save"
        - yaml id:<context.args.get[1]> set <context.args.get[2]>:!
        - narrate "Chest: <context.args.get[2]> has been removed from File: <context.args.get[1]>.yml"
        }
      - yaml savefile:/Chests/<context.args.get[1]>.yml id:<context.args.get[1]>
      - yaml unload id:<context.args.get[1]>
      - queue clear
      }
##Edit Arguments##
    - if <context.args.contains[Edit]> {
      - if <server.has_file[/Chests/<context.args.get[1]>.yml].not> {
        - narrate "The file specified: <context.args.get[1]>, does not exist! Did you type in the name correctly?"
        - queue clear
        }
      - yaml load:/Chests/<context.args.get[1]>.yml id:<context.args.get[1]>
      - if <yaml[<context.args.get[1]>].contains[<context.args.get[2]>].not> {
        - narrate "The Chest: <context.args.get[2]>, does not exist in File: <context.args.get[1]>! Did you specify the correct file and chest names?"
        - queue clear
        }
      - if <context.args.filter[starts_with[Table:]].is_empty> && <context.args.filter[starts_with[Chance:]].is_empty.not> {
        - narrate "You must specify a drop table to edit a Random Chest."
        - queue clear
        }
      - if <context.args.filter[starts_with[Table:]].is_empty> && <context.args.filter[starts_with[Chance:]].is_empty> {
        - if <context.args.filter[starts_with[Location:]].is_empty.not> {
          - note remove as:<context.args.get[2]>
          - note remove as:<context.args.get[2]>chest
          - note <context.args.map_get[Location].split_by[<&co>]> as:<context.args.get[2]>
          - note l@<context.args.map_get[Location].split_by[<&co>].after[cu@].before[|]> as:<context.args.get[2]>chest
          - execute as_op "denizen save"
          }
        - flag player EditLootChest:|:<context.args.get[1]>|<context.args.get[2]>
        - if <context.args.filter[starts_with[Money:]].is_empty.not> {
          - yaml id:<context.args.get[1]> set <context.args.get[2]>.Money:<context.args.map_get[money].split_by[<&co>]>
          - yaml savefile:/Chests/<context.args.get[1]>.yml id:<context.args.get[1]>
          }
        - inventory open d:in@LootChestInv
        - queue clear
        }
      - if <context.args.filter[starts_with[Table:]].is_empty.not> {
        - if <context.args.filter[starts_with[Chance:]].is_empty.not> {
          - if <context.args.map_get[Chance].split_by[<&co>].starts_with[0].not> {
            - narrate "You must add a 0 when specifying your Chance decimal! Ex: Chance:0.25."
            - queue clear
            }
          - yaml id:<context.args.get[1]> set <context.args.get[2]>.<context.args.map_get[Table].split_by[<&co>]>.Chance:<context.args.map_get[Chance].split_by[<&co>]>
          }
        - if <context.args.filter[starts_with[Location:]].is_empty.not> {
          - note remove as:<context.args.get[2]>
          - note remove as:<context.args.get[2]>chest
          - note <context.args.map_get[Location].split_by[<&co>]> as:<context.args.get[2]>
          - note l@<context.args.map_get[Location].split_by[<&co>].after[cu@].before[|]> as:<context.args.get[2]>chest
          - execute as_op "denizen save"
          }
        - if <context.args.filter[starts_with[Money:]].is_empty.not> {
          - yaml id:<context.args.get[1]> set <context.args.get[2]>.<context.args.map_get[Table].split_by[<&co>]>.Money:<context.args.map_get[money].split_by[<&co>]>
          }
        - flag player EditRandomChest:|:<context.args.get[1]>|<context.args.get[2]>|<context.args.map_get[Table].split_by[<&co>]>
        - yaml savefile:/Chests/<context.args.get[1]>.yml id:<context.args.get[1]>
        - yaml load:/Chests/<context.args.get[1]>.yml id:<context.args.get[1]>
        - inventory open d:in@RandomChestInv
        - queue clear
        }
      }
    - if <context.args.filter[starts_with[Chance:]].is_empty.not> && <context.args.filter[starts_with[Table:]].is_empty> {
      - narrate "You must specify a Drop Table name for a Randomized Chest. If you want to make a static chest, use the command without the Table and Chance arguments."
      - queue clear
      }
##Static Chest##
    - if <context.args.filter[starts_with[Table:]].is_empty> && <context.args.filter[starts_with[Chance:]].is_empty> {
      - if <context.args.filter[starts_with[Location:]].is_empty.not> {
        - note <context.args.map_get[Location].split_by[<&co>]> as:<context.args.get[2]>
        - execute as_op "denizen save"
        }
      - if <server.has_file[/Chests/<context.args.get[1]>.yml].not> {
        - yaml create id:<context.args.get[1]>   
        } else {
        - yaml load:/Chests/<context.args.get[1]>.yml id:<context.args.get[1]>
        - if <yaml[<context.args.get[1]>].contains[<context.args.get[2]>]> {
          - narrate "That Chest already exists! To edit this Chest, include the word Edit when you use /lootchest. Ex: /lootchest <context.args.get[1]> <context.args.get[2]> Edit | To Delete it, use Delete instead of Edit"
          - yaml unload id:<context.args.get[1]>
          - queue clear
          }
        }
      - if <context.args.filter[starts_with[Money:]].is_empty.not> {
        - yaml id:<context.args.get[1]> set <context.args.get[2]>.Money:<context.args.map_get[money].split_by[<&co>]>
        } else {
        - yaml id:<context.args.get[1]> set <context.args.get[2]>.Money:0
        }
      - yaml savefile:/Chests/<context.args.get[1]>.yml id:<context.args.get[1]>
      - yaml load:/Chests/<context.args.get[1]>.yml id:<context.args.get[1]>
      - flag player SetLootChest:|:<context.args.get[1]>|<context.args.get[2]>
      - inventory open d:in@LootChestInv
      - queue clear
      }
##Randomized Chest
    - if <context.args.filter[starts_with[Location:]].is_empty.not> {
      - note <context.args.map_get[Location].split_by[<&co>]> as:<context.args.get[2]>
      - note l@<context.args.map_get[Location].split_by[<&co>].after[cu@].before[|]> as:<context.args.get[2]>chest
      - execute as_op "denizen save"
      }
    - if <server.has_file[/Chests/<context.args.get[1]>.yml].not> {
      - yaml create id:<context.args.get[1]>
      - yaml load:/Chests/<context.args.get[1]>.yml id:<context.args.get[1]>
      } else {
      - yaml load:/Chests/<context.args.get[1]>.yml id:<context.args.get[1]>
      - if <yaml[<context.args.get[1]>].list_keys[<context.args.get[2]>].contains[<context.args.map_get[Table].split_by[<&co>]>]> {
        - narrate "That Table already exists! To edit this Table, include the word Edit when you use /lootchest. Ex: /lootchest <context.args.get[1]> <context.args.get[2]> <context.args.filter[starts_with[Table:]].after[li@]> Edit | To Delete it, use Delete instead of Edit"
        - yaml unload id:<context.args.get[1]>
        - queue clear
        }
      - if <context.args.map_get[Chance].split_by[<&co>].starts_with[0].not> {
        - narrate "You must add a 0 when specifying your Chance decimal! Ex: Chance:0.25"
        - queue clear
        }
      }
    - yaml id:<context.args.get[1]> set <context.args.get[2]>.<context.args.map_get[Table].split_by[<&co>]>.Chance:<context.args.map_get[Chance].split_by[<&co>]>
    - if <context.args.filter[starts_with[Money:]].is_empty.not> {
      - yaml id:<context.args.get[1]> set <context.args.get[2]>.<context.args.map_get[Table].split_by[<&co>]>.Money:<context.args.map_get[money].split_by[<&co>]>
      } else {
      - yaml id:<context.args.get[1]> set <context.args.get[2]>.<context.args.map_get[Table].split_by[<&co>]>.Money:0
      }
    - yaml savefile:/Chests/<context.args.get[1]>.yml id:<context.args.get[1]>
    - flag player SetRandomChest:|:<context.args.get[1]>|<context.args.get[2]>|<context.args.map_get[Table].split_by[<&co>]>
    - inventory open d:in@RandomChestInv
    
ChestSystemHandler:
  type: world
  events:
    on player clicks SaveChestIt in LootChestInv:
    - determine passively cancelled
    - yaml id:<player.uuid> set SavedLootChest.Items:!
    - foreach <player.open_inventory.list_contents> {
      - yaml id:<player.uuid> set SavedLootChest.Items:->:<def[value]>
      }
    - yaml savefile:/PlayerData/<player.uuid>.yml id:<player.uuid>
    - flag player SavedLootChest
    - narrate "LootChest Template Saved"
    on player clicks SaveChestIt in RandomChestInv:
    - determine passively cancelled
    - yaml id:<player.uuid> set SavedLootChest.Items:!
    - foreach <player.open_inventory.list_contents.before[i@SaveChestIt]> {
      - yaml id:<player.uuid> set SavedLootChest.Items:->:<def[value]>
      }
    - yaml savefile:/PlayerData/<player.uuid>.yml id:<player.uuid>
    - inventory close
    - flag player SavedLootChest
    - narrate "LootChest Template Saved"
    on player closes LootChestInv:
    - if <player.has_flag[EditLootChest]> {
      - yaml id:<player.flag[EditLootchest].get[1]> set <player.flag[EditLootchest].get[2]>.Items:!
      - foreach <context.inventory.list_contents.before[i@SaveChestIt]> {
        - yaml id:<player.flag[EditLootchest].get[1]> set <player.flag[EditLootchest].get[2]>.Items:->:<def[value]>
        }
      - yaml savefile:/Chests/<player.flag[EditLootChest].get[1]>.yml id:<player.flag[EditLootChest].get[1]>
      - narrate "Chest: <player.flag[EditLootChest].get[2]> in File: <player.flag[EditLootChest].get[1]> successfully editted."
      - yaml unload id:<player.flag[EditLootChest].get[1]>
      - flag player EditLootChest:!
      - queue clear
      }
    - foreach <context.inventory.list_contents.before[i@SaveChestIt]> {
      - yaml id:<player.flag[SetLootchest].get[1]> set <player.flag[SetLootchest].get[2]>.Items:->:<def[value]>
    }
    - yaml savefile:/Chests/<player.flag[SetLootchest].get[1]>.yml id:<player.flag[SetLootchest].get[1]>
    - narrate "Chest: <player.flag[SetLootChest].get[2]> saved to File: <player.flag[SetLootChest].get[1]>"
    - yaml unload id:<player.flag[SetLootChest].get[1]>
    - flag player SetLootChest:!
    on player closes RandomChestInv:
    - if <player.has_flag[EditRandomChest]>:
      - yaml id:<player.flag[EditRandomChest].get[1]> set <player.flag[EditRandomChest].get[2]>.<player.flag[EditRandomChest].get[3]>.Items:!
      - foreach <context.inventory.list_contents.before[i@SaveChestIt]>:
        - yaml id:<player.flag[EditRandomChest].get[1]> set <player.flag[EditRandomChest].get[2]>.<player.flag[EditRandomChest].get[3]>.Items:->:<def[value]>
      - yaml savefile:/Chests/<player.flag[EditRandomChest].get[1]>.yml id:<player.flag[EditRandomChest].get[1]>
      - narrate "Table: <player.flag[EditRandomChest].get[3]> for Chest: <player.flag[EditRandomChest].get[2]> in File: <player.flag[EditRandomChest].get[1]> successfully editted!"
      - yaml unload id:<player.flag[EditRandomChest].get[1]>
      - flag player EditRandomChest:!
      - queue clear
    - foreach <context.inventory.list_contents.before[i@SaveChestIt]>:
      - yaml id:<player.flag[SetRandomChest].get[1]> set <player.flag[SetRandomChest].get[2]>.<player.flag[SetRandomChest].get[3]>.Items:->:<def[value]>
    - yaml savefile:/Chests/<player.flag[SetRandomChest].get[1]>.yml id:<player.flag[SetRandomChest].get[1]>
    - narrate "Table: <player.flag[SetRandomChest].get[3]> created for Chest: <player.flag[SetRandomChest].get[2]> in File: <player.flag[SetRandomChest].get[1]>"
    - yaml unload id:<player.flag[SetRandomChest].get[1]>
    - flag player SetRandomChest:!
    on player closes SmallChestInv:
    - if <player.has_flag[LootChest]>:
      - animatechest <player.flag[CurrentChest]> close sound:true
      - if <yaml[<player.uuid>].read[OpenedChests].contains[<player.flag[LootChest].get[2]>].not>:
        - if <yaml[<player.flag[LootChest].get[1]>].read[<player.flag[LootChest].get[2]>.Money]> != 0:
          - money give quantity:<yaml[<player.flag[LootChest].get[1]>].read[<player.flag[LootChest].get[2]>.Money]>
          - narrate "You found $<yaml[<player.flag[LootChest].get[1]>].read[<player.flag[LootChest].get[2]>.Money]> in the chest!"
        - yaml unload id:<player.flag[LootChest].get[1]>
      - yaml id:<player.uuid> set OpenedChests.<player.flag[LootChest].get[2]>.Items:!
      - if <context.inventory.is_empty>:
        - yaml id:<player.uuid> set OpenedChests.<player.flag[LootChest].get[2]>.Items:->:i@air
      - else:
        - foreach <context.inventory.list_contents>:
          - yaml id:<player.uuid> set OpenedChests.<player.flag[LootChest].get[2]>.Items:->:<def[value]>
      - yaml savefile:/PlayerData/<player.uuid>.yml id:<player.uuid>
      - flag player LootChest:!
      - queue clear
    - if <player.has_flag[RandomChest]>:
      - animatechest <player.flag[CurrentChest].get[2]> close sound:true
      - if <yaml[<player.uuid>].read[OpenedChests].contains[<player.flag[CurrentChest].get[1]>].not>:
        - if <yaml[<player.flag[RandomChest].get[1]>].read[<player.flag[CurrentChest].get[1]>.<player.flag[RandomChest].get[2]>.Money]> != 0:
          - money give quantity:<yaml[<player.flag[RandomChest].get[1]>].read[<player.flag[CurrentChest].get[1]>.<player.flag[RandomChest].get[2]>.Money]>
          - narrate "You found $<yaml[<player.flag[RandomChest].get[1]>].read[<player.flag[CurrentChest].get[1]>.<player.flag[RandomChest].get[2]>.Money]> in the chest!"
        - yaml unload id:<player.flag[RandomChest].get[1]>
      - yaml id:<player.uuid> set OpenedChests.<player.flag[CurrentChest].get[1]>.Items:!
      - if <context.inventory.is_empty>:
        - yaml id:<player.uuid> set OpenedChests.<player.flag[CurrentChest].get[1]>.Items:->:i@air
      - else:
        - foreach <context.inventory.list_contents>:
          - yaml id:<player.uuid> set OpenedChests.<player.flag[CurrentChest].get[1]>.Items:->:<def[value]>
      - yaml savefile:/PlayerData/<player.uuid>.yml id:<player.uuid>
      - flag player CurrentChest:!
      - flag player RandomChest:!
      - queue clear
    on player closes DoubleChestInv:
    - if <player.has_flag[LootChest]>:
      - animatechest <player.flag[CurrentChest]> close sound:true
      - if <yaml[<player.uuid>].read[OpenedChests].contains[<player.flag[LootChest].get[2]>].not>:
        - if <yaml[<player.flag[LootChest].get[1]>].read[<player.flag[LootChest].get[2]>.Money]> != 0:
          - money give quantity:<yaml[<player.flag[LootChest].get[1]>].read[<player.flag[LootChest].get[2]>.Money]>
          - narrate "You found $<yaml[<player.flag[LootChest].get[1]>].read[<player.flag[LootChest].get[2]>.Money]> in the chest!"
        - yaml unload id:<player.flag[LootChest].get[1]>
      - yaml id:<player.uuid> set OpenedChests.<player.flag[LootChest].get[2]>.Items:!
      - if <context.inventory.is_empty>:
        - yaml id:<player.uuid> set OpenedChests.<player.flag[LootChest].get[2]>.Items:->:i@air
      - else:
        - foreach <context.inventory.list_contents>:
          - yaml id:<player.uuid> set OpenedChests.<player.flag[LootChest].get[2]>.Items:->:<def[value]>
      - yaml savefile:/PlayerData/<player.uuid>.yml id:<player.uuid>
      - flag player LootChest:!
      - queue clear
    - if <player.has_flag[RandomChest]>:
      - animatechest <player.flag[CurrentChest].get[2]> close sound:true
      - if <yaml[<player.uuid>].read[OpenedChests].contains[<player.flag[CurrentChest].get[1]>].not>:
        - if <yaml[<player.flag[RandomChest].get[1]>].read[<player.flag[CurrentChest].get[1]>.<player.flag[RandomChest].get[2]>.Money]> != 0:
          - money give quantity:<yaml[<player.flag[RandomChest].get[1]>].read[<player.flag[CurrentChest].get[1]>.<player.flag[RandomChest].get[2]>.Money]>
          - narrate "You found $<yaml[<player.flag[RandomChest].get[1]>].read[<player.flag[CurrentChest].get[1]>.<player.flag[RandomChest].get[2]>.Money]> in the chest!"
        - yaml unload id:<player.flag[RandomChest].get[1]>
      - yaml id:<player.uuid> set OpenedChests.<player.flag[CurrentChest].get[1]>.Items:!
      - if <context.inventory.is_empty>:
        - yaml id:<player.uuid> set OpenedChests.<player.flag[CurrentChest].get[1]>.Items:->:i@air
      - else:
        - foreach <context.inventory.list_contents>:
          - yaml id:<player.uuid> set OpenedChests.<player.flag[CurrentChest].get[1]>.Items:->:<def[value]>
      - yaml savefile:/PlayerData/<player.uuid>.yml id:<player.uuid>
      - flag player CurrentChest:!
      - flag player RandomChest:!
      - queue clear

RandomChestTSK:
  type: task
  definitions: File|Chest|Location
  script:
    - if <yaml[<player.uuid>].read[OpenedChests].contains[<def[chest]>].not>:
      - yaml load:/Chests/<def[File]>.yml id:<def[File]>
      - flag player RandomChest:<def[File]>
      - flag player CurrentChest:<def[chest]>
      - flag player CurrentChest:|:<def[Location]>
      - flag player RandomChest:|:<proc[RandomChestProc]>
      - animatechest <def[Location]> open sound:true
      - inventory open d:in@SmallChestInv
      - yaml id:<player.uuid> set OpenedChests.Total:+:1
    - else:
      - flag player CurrentChest:<def[chest]>
      - flag player CurrentChest:|:<def[Location]>
      - flag player RandomChest:<def[chest]>
      - animatechest <def[Location]> open sound:true
      - inventory open d:in@SmallChestInv
      
StaticChestTSK:
  type: task
  definitions: File|Chest|Location
  script:
    - if <yaml[<player.uuid>].read[OpenedChests].contains[<def[Chest]>].not>:
      - flag player LootChest:<def[File]>
      - flag player LootChest:|:<def[Chest]>
      - flag player CurrentChest:<def[Location]>
      - yaml load:/Chests/<def[File]>.yml id:<def[File]>
      - animatechest <def[location]> open sound:true
      - inventory open d:in@SmallChestInv
      - yaml id:<player.uuid> set OpenedChests.Total:+:1
    - else:
      - flag player LootChest:<def[File]>
      - flag player LootChest:|:<def[Chest]>
      - flag player CurrentChest:<def[Location]>
      - animatechest <def[location]> open sound:true
      - inventory open d:in@SmallChestInv