-----------------------------------
-- Treasure Chests and Coffers
-----------------------------------
require('scripts/globals/npc_util')
-----------------------------------
xi = xi or {}
xi.treasure = xi.treasure or {}

-----------------------------------
-- Enums
-----------------------------------
local treasureType =
{
    CHEST  = 1,
    COFFER = 2,
}

local keyType =
{
    ZONE_KEY     = 1,
    THIEF_TOOLS  = 2,
    LIVING_KEY   = 3,
    SKELETON_KEY = 4,
}

local respawnType =
{
    IMMEDIATE =   5,
    REGULAR   = 180,
}
-----------------------------------
-- Tables
-----------------------------------
local thiefKeyInfo =
{
--   Key                       Item ID                      Success % Modifier
    [keyType.THIEF_TOOLS ] = { xi.item.SET_OF_THIEFS_TOOLS, 10 },
    [keyType.LIVING_KEY  ] = { xi.item.LIVING_KEY,          15 },
    [keyType.SKELETON_KEY] = { xi.item.SKELETON_KEY,        20 },
}

local npcTable =
{
    ['Treasure_Chest' ] = 1,
    ['Treasure_Coffer'] = 2,
}

local keyTable =
{
    [xi.zone.PSOXJA                ] = { xi.item.PSOXJA_CHEST_KEY,     0                             },
    [xi.zone.OLDTON_MOVALPOLOS     ] = { xi.item.OLDTON_CHEST_KEY,     0                             },
    [xi.zone.NEWTON_MOVALPOLOS     ] = { 0,                            xi.item.NEWTON_COFFER_KEY     },
    [xi.zone.SACRARIUM             ] = { xi.item.SACRARIUM_CHEST_KEY,  0                             },
    [xi.zone.RUAUN_GARDENS         ] = { 0,                            xi.item.RUAUN_COFFER_KEY      },
    [xi.zone.FORT_GHELSBA          ] = { xi.item.GHELSBA_CHEST_KEY,    0                             },
    [xi.zone.YUGHOTT_GROTTO        ] = { xi.item.GHELSBA_CHEST_KEY,    0                             },
    [xi.zone.PALBOROUGH_MINES      ] = { xi.item.PALBOROUGH_CHEST_KEY, 0                             },
    [xi.zone.GIDDEUS               ] = { xi.item.GIDDEUS_CHEST_KEY,    0                             },
    [xi.zone.BEADEAUX              ] = { xi.item.BEADEAUX_CHEST_KEY,   xi.item.BEADEAUX_COFFER_KEY   },
    [xi.zone.DAVOI                 ] = { xi.item.DAVOI_CHEST_KEY,      0                             },
    [xi.zone.MONASTIC_CAVERN       ] = { 0,                            xi.item.DAVOI_COFFER_KEY      },
    [xi.zone.CASTLE_OZTROJA        ] = { xi.item.OZTROJA_CHEST_KEY,    xi.item.OZTROJA_COFFER_KEY    },
    [xi.zone.THE_BOYAHDA_TREE      ] = { 0,                            xi.item.BOYAHDA_COFFER_KEY    },
    [xi.zone.MIDDLE_DELKFUTTS_TOWER] = { xi.item.DELKFUTT_CHEST_KEY,   0                             },
    [xi.zone.UPPER_DELKFUTTS_TOWER ] = { xi.item.DELKFUTT_CHEST_KEY,   0                             },
    [xi.zone.TEMPLE_OF_UGGALEPIH   ] = { 0,                            xi.item.UGGALEPIH_COFFER_KEY  },
    [xi.zone.DEN_OF_RANCOR         ] = { 0,                            xi.item.RANCOR_DEN_COFFER_KEY },
    [xi.zone.CASTLE_ZVAHL_BAILEYS  ] = { xi.item.ZVAHL_CHEST_KEY,      xi.item.ZVAHL_COFFER_KEY      },
    [xi.zone.CASTLE_ZVAHL_KEEP     ] = { xi.item.ZVAHL_CHEST_KEY,      0                             },
    [xi.zone.TORAIMARAI_CANAL      ] = { 0,                            xi.item.TORAIMARI_COFFER_KEY  },
    [xi.zone.KUFTAL_TUNNEL         ] = { 0,                            xi.item.KUFTAL_COFFER_KEY     },
    [xi.zone.SEA_SERPENT_GROTTO    ] = { xi.item.GROTTO_CHEST_KEY,     xi.item.GROTTO_COFFER_KEY     },
    [xi.zone.VELUGANNON_PALACE     ] = { 0,                            xi.item.VELUGANNON_COFFER_KEY },
    [xi.zone.KING_RANPERRES_TOMB   ] = { xi.item.RANPERRE_CHEST_KEY,   0                             },
    [xi.zone.DANGRUF_WADI          ] = { xi.item.DANGRUF_CHEST_KEY,    0                             },
    [xi.zone.INNER_HORUTOTO_RUINS  ] = { xi.item.HORUTOTO_CHEST_KEY,   0                             },
    [xi.zone.ORDELLES_CAVES        ] = { xi.item.ORDELLE_CHEST_KEY,    0                             },
    [xi.zone.OUTER_HORUTOTO_RUINS  ] = { xi.item.HORUTOTO_CHEST_KEY,   0                             },
    [xi.zone.THE_ELDIEME_NECROPOLIS] = { xi.item.ELDIEME_CHEST_KEY,    xi.item.ELDIEME_COFFER_KEY    },
    [xi.zone.GUSGEN_MINES          ] = { xi.item.GUSGEN_CHEST_KEY,     0                             },
    [xi.zone.CRAWLERS_NEST         ] = { xi.item.NEST_CHEST_KEY,       xi.item.NEST_COFFER_KEY       },
    [xi.zone.MAZE_OF_SHAKHRAMI     ] = { xi.item.SHAKHRAMI_CHEST_KEY,  0                             },
    [xi.zone.GARLAIGE_CITADEL      ] = { xi.item.GARLAIGE_CHEST_KEY,   xi.item.GARLAIGE_COFFER_KEY   },
    [xi.zone.FEIYIN                ] = { xi.item.FEIYIN_CHEST_KEY,     0                             },
    [xi.zone.IFRITS_CAULDRON       ] = { 0,                            xi.item.CAULDRON_COFFER_KEY   },
    [xi.zone.QUICKSAND_CAVES       ] = { 0,                            xi.item.QUICKSAND_COFFER_KEY  },
    [xi.zone.LABYRINTH_OF_ONZOZO   ] = { xi.item.ONZOZO_CHEST_KEY,     0                             },
}

local mapTable =
{
    [xi.zone.PSOXJA                ] = { xi.ki.MAP_OF_PSOXJA,              0                                },
    [xi.zone.OLDTON_MOVALPOLOS     ] = { xi.ki.MAP_OF_OLDTON_MOVALPOLOS,   0                                },
    [xi.zone.NEWTON_MOVALPOLOS     ] = { 0,                                xi.ki.MAP_OF_NEWTON_MOVALPOLOS   },
    [xi.zone.SACRARIUM             ] = { 0,                                0                                },
    [xi.zone.RUAUN_GARDENS         ] = { 0,                                xi.ki.MAP_OF_THE_RUAUN_GARDENS   },
    [xi.zone.FORT_GHELSBA          ] = { 0,                                0                                },
    [xi.zone.YUGHOTT_GROTTO        ] = { 0,                                0                                },
    [xi.zone.PALBOROUGH_MINES      ] = { 0,                                0                                },
    [xi.zone.GIDDEUS               ] = { 0,                                0                                },
    [xi.zone.BEADEAUX              ] = { 0,                                0                                },
    [xi.zone.DAVOI                 ] = { 0,                                0                                },
    [xi.zone.MONASTIC_CAVERN       ] = { 0,                                0                                },
    [xi.zone.CASTLE_OZTROJA        ] = { 0,                                0                                },
    [xi.zone.THE_BOYAHDA_TREE      ] = { 0,                                xi.ki.MAP_OF_THE_BOYAHDA_TREE    },
    [xi.zone.MIDDLE_DELKFUTTS_TOWER] = { 0,                                0                                },
    [xi.zone.UPPER_DELKFUTTS_TOWER ] = { 0,                                0                                },
    [xi.zone.TEMPLE_OF_UGGALEPIH   ] = { 0,                                xi.ki.MAP_OF_TEMPLE_OF_UGGALEPIH },
    [xi.zone.DEN_OF_RANCOR         ] = { 0,                                xi.ki.MAP_OF_THE_DEN_OF_RANCOR   },
    [xi.zone.CASTLE_ZVAHL_BAILEYS  ] = { 0,                                0                                },
    [xi.zone.CASTLE_ZVAHL_KEEP     ] = { 0,                                0                                },
    [xi.zone.TORAIMARAI_CANAL      ] = { 0,                                0                                },
    [xi.zone.KUFTAL_TUNNEL         ] = { 0,                                xi.ki.MAP_OF_THE_KUFTAL_TUNNEL   },
    [xi.zone.SEA_SERPENT_GROTTO    ] = { xi.ki.MAP_OF_SEA_SERPENT_GROTTO,  xi.ki.MAP_OF_SEA_SERPENT_GROTTO  },
    [xi.zone.VELUGANNON_PALACE     ] = { 0,                                xi.ki.MAP_OF_VELUGANNON_PALACE   },
    [xi.zone.KING_RANPERRES_TOMB   ] = { 0,                                0                                },
    [xi.zone.DANGRUF_WADI          ] = { 0,                                0                                },
    [xi.zone.INNER_HORUTOTO_RUINS  ] = { 0,                                0                                },
    [xi.zone.ORDELLES_CAVES        ] = { 0,                                0                                },
    [xi.zone.OUTER_HORUTOTO_RUINS  ] = { 0,                                0                                },
    [xi.zone.THE_ELDIEME_NECROPOLIS] = { 0,                                0                                },
    [xi.zone.GUSGEN_MINES          ] = { 0,                                0                                },
    [xi.zone.CRAWLERS_NEST         ] = { 0,                                0                                },
    [xi.zone.MAZE_OF_SHAKHRAMI     ] = { 0,                                0                                },
    [xi.zone.GARLAIGE_CITADEL      ] = { 0,                                0                                },
    [xi.zone.FEIYIN                ] = { 0,                                0                                },
    [xi.zone.IFRITS_CAULDRON       ] = { 0,                                xi.ki.MAP_OF_IFRITS_CAULDRON     },
    [xi.zone.QUICKSAND_CAVES       ] = { 0,                                xi.ki.MAP_OF_THE_QUICKSAND_CAVES },
    [xi.zone.LABYRINTH_OF_ONZOZO   ] = { xi.ki.MAP_OF_LABYRINTH_OF_ONZOZO, 0                                },
}

local levelTable =
{
    -- [zoneId] = { chest_level, coffer_level },
    [xi.zone.PSOXJA                ] = { 50,  0 },
    [xi.zone.OLDTON_MOVALPOLOS     ] = { 50,  0 },
    [xi.zone.NEWTON_MOVALPOLOS     ] = {  0, 70 },
    [xi.zone.SACRARIUM             ] = { 50,  0 },
    [xi.zone.RUAUN_GARDENS         ] = {  0, 70 },
    [xi.zone.FORT_GHELSBA          ] = { 20,  0 },
    [xi.zone.YUGHOTT_GROTTO        ] = { 20,  0 },
    [xi.zone.PALBOROUGH_MINES      ] = { 30,  0 },
    [xi.zone.GIDDEUS               ] = { 20,  0 },
    [xi.zone.BEADEAUX              ] = { 40, 60 },
    [xi.zone.DAVOI                 ] = { 40,  0 },
    [xi.zone.MONASTIC_CAVERN       ] = {  0, 60 },
    [xi.zone.CASTLE_OZTROJA        ] = { 40, 60 },
    [xi.zone.THE_BOYAHDA_TREE      ] = {  0, 60 },
    [xi.zone.MIDDLE_DELKFUTTS_TOWER] = { 35,  0 },
    [xi.zone.UPPER_DELKFUTTS_TOWER ] = { 35,  0 },
    [xi.zone.TEMPLE_OF_UGGALEPIH   ] = {  0, 60 },
    [xi.zone.DEN_OF_RANCOR         ] = {  0, 65 },
    [xi.zone.CASTLE_ZVAHL_BAILEYS  ] = { 50, 60 },
    [xi.zone.CASTLE_ZVAHL_KEEP     ] = { 50,  0 },
    [xi.zone.TORAIMARAI_CANAL      ] = {  0, 60 },
    [xi.zone.KUFTAL_TUNNEL         ] = {  0, 60 },
    [xi.zone.SEA_SERPENT_GROTTO    ] = { 40, 55 },
    [xi.zone.VELUGANNON_PALACE     ] = {  0, 70 },
    [xi.zone.KING_RANPERRES_TOMB   ] = { 15,  0 },
    [xi.zone.DANGRUF_WADI          ] = { 15,  0 },
    [xi.zone.INNER_HORUTOTO_RUINS  ] = { 15,  0 },
    [xi.zone.ORDELLES_CAVES        ] = { 30,  0 },
    [xi.zone.OUTER_HORUTOTO_RUINS  ] = { 15,  0 },
    [xi.zone.THE_ELDIEME_NECROPOLIS] = { 50, 60 },
    [xi.zone.GUSGEN_MINES          ] = { 30,  0 },
    [xi.zone.CRAWLERS_NEST         ] = { 50, 55 },
    [xi.zone.MAZE_OF_SHAKHRAMI     ] = { 30,  0 },
    [xi.zone.GARLAIGE_CITADEL      ] = { 50, 60 },
    [xi.zone.FEIYIN                ] = { 45,  0 },
    [xi.zone.IFRITS_CAULDRON       ] = {  0, 60 },
    [xi.zone.QUICKSAND_CAVES       ] = {  0, 55 },
    [xi.zone.LABYRINTH_OF_ONZOZO   ] = { 40,  0 },
}

local posTable =
{
    [xi.zone.PSOXJA] =
    {
        [treasureType.CHEST] =
        {
            { -393.000, 16.000, -208.000,   0 },
            { -392.950, 16.000, -236.012,   0 },
            { -349.409, 16.000, -232.783,  20 },
            { -379.409, 16.000, -207.245,  64 },
            { -329.944,  0.247, -271.769, 192 },
            { -322.799, 32.000, -276.970, 161 },
            { -349.915, 32.247, -169.891,  64 },
            { -362.928, 32.000, -236.722, 161 },
            { -389.971, 32.247, -229.970,   0 },
        },
    },

    [xi.zone.OLDTON_MOVALPOLOS] =
    {
        [treasureType.CHEST] =
        {
            { -140.636,  7.999,  200.498, 192 },
            { -138.897,  8.000,  157.084,  66 },
            { -236.521, 12.001,   32.003,   0 },
            {  -32.310, 12.001,  105.692, 192 },
            {  -19.717,  7.973,   66.538, 235 },
            {   67.304, 15.973,  -95.506,  66 },
            {  156.833, 14.000,  -86.775, 192 },
            {  197.942,  7.995,  -76.187, 132 },
            {  186.486,  8.000,  -42.940, 128 },
            {  -87.437, 22.927,  -37.080,  66 },
            { -141.654,  8.000, -251.000,  90 },
            { -142.762,  8.000, -310.777, 192 },
        },
    },

    [xi.zone.NEWTON_MOVALPOLOS] =
    {
        [treasureType.COFFER] =
        {
            { -46.014, 17.980, -26.274,  64 },
            { 348.964, 26.066,   8.791,  60 },
            { 212.428, 19.825, -21.050,   0 },
            {   2.971, 16.000, -22.634, 190 },
            { -68.858, 15.992,  30.021,   0 },
            { -24.070, 16.841,  18.666, 190 },
            { 140.090, 20.000, -44.821,  60 },
            {  94.145, 15.995,  71.251,  90 },
            { 140.432, 19.989,  84.637, 190 },
        },
    },

    [xi.zone.SACRARIUM] =
    {
        [treasureType.CHEST] =
        {
            { 179.709, -7.693,  -97.007, 192 },
            { 111.451, -2.000, -100.159,  65 },
            {   8.974, -2.179, -133.075, 190 },
            { 260.391,  0.000,   21.487,  60 },
            { 177.600,  8.310,  100.000, 130 },
            {  89.034, -2.000,   99.248, 190 },
            {  88.223, -2.000,  -36.017,   0 },
            {  31.021, -2.000,   99.013, 190 },
        },
    },

    [xi.zone.RUAUN_GARDENS] =
    {
        [treasureType.COFFER] =
        {
            { -306.824, -23.999,  230.783, 155 },
            {  -98.092, -24.000,  369.754, 173 },
            { -149.167, -40.200,  446.421,  52 },
            {   75.417, -24.000,  412.146,  73 },
            {  285.520,  -2.600,  375.324, 105 },
            {  454.220, -40.200,   29.944,  66 },
            {  378.977,  -8.000, -133.852,  80 },
            {  295.992, -24.000, -241.582,  21 },
            {  128.749, -34.000, -173.096, 110 },
            { -128.639, -34.000, -173.254,  22 },
            { -377.675, -40.200, -268.597, 230 },
            { -425.500, -36.000,   69.185, 103 },
        },
    },

    [xi.zone.FORT_GHELSBA] =
    {
        [treasureType.CHEST] =
        {
            {  62.583, -61.584,   21.578,  21 },
            { 177.589, -84.118,   47.830,  77 },
            { 114.363, -45.114,  104.614,   0 },
            { 165.383, -32.000,  139.055, 135 },
            { 143.690, -45.584, -102.603,  71 },
        },
    },

    [xi.zone.YUGHOTT_GROTTO] =
    {
        [treasureType.CHEST] =
        {
            {  143.385, -12.362, 132.887,  15 },
            {  363.764, -24.250, 167.509, 170 },
            {  216.953, -12.468,  49.284, 110 },
            {   63.413,  -0.081,  11.611, 133 },
            {   12.770,  -0.383,  36.825,  65 },
            {  -12.144,  -0.206, -63.396, 230 },
            { -151.230,  -0.359, -21.489, 253 },
        },
    },

    [xi.zone.PALBOROUGH_MINES] =
    {
        [treasureType.CHEST] =
        {
            { 250.037, -32.069, 174.156, 227 },
            { 241.950, -31.769,  59.927, 255 },
            { 259.068, -31.625, -71.901, 190 },
            { 219.331, -31.595,   4.665,  60 },
            { 216.795, -31.527, -71.373, 197 },
            { 262.397, -32.202,  87.518, 160 },
            { 179.993, -31.956,  93.280, 190 },
            { 139.909, -31.957, 146.845,  60 },
            {  99.115, -32.000,  83.067, 209 },
            {  21.141, -31.944,  81.473, 111 },
            {  59.776, -31.592,   5.373,  60 },
            {  99.917, -32.000, -41.557,  60 },
        },
    },

    [xi.zone.GIDDEUS] =
    {
        [treasureType.CHEST] =
        {
            { -158.563,  0.999, -226.058,  52 },
            { -103.777, -0.900, -254.271, 150 },
            { -242.625,  0.935, -185.404,  70 },
            { -267.030, -2.156, -263.207, 234 },
            {  -23.626,  0.982, -105.747, 135 },
            {   63.712, -0.900, -254.442, 235 },
            {  125.386, -3.168, -259.326, 132 },
            {  100.137,  1.387, -230.499,   5 },
            {  113.058,  1.000, -224.402,  28 },
            {  182.259,  0.915, -230.619,   1 },
            {  213.192, -2.309, -299.255, 236 },
        },
    },

    [xi.zone.BEADEAUX] =
    {
        [treasureType.CHEST] =
        {
            {  81.814, -3.250,   1.523, 238 },
            { 122.451, -2.468, 132.482, 206 },
            { 159.081, -3.275,  78.207,  18 },
            { 150.931, -2.969,  30.893,  94 },
            { 252.520, -3.000, -56.725, 159 },
            { 161.465, -3.000, -58.075, 139 },
            { 274.491, -3.249,  45.577, 210 },
            { 272.330, -3.338, 125.156, 171 },
            { 170.554, -3.000, 174.293,  40 },
            { 107.592, -3.000, 215.188,  47 },
            {  82.216, -3.196, 117.415, 167 },
            {  22.898, -2.981,  84.606, 214 },
        },
        [treasureType.COFFER] =
        {
            { 216.974, 39.702,  68.790, 135 },
            { 369.956, 24.075,  59.954, 255 },
            { 414.430, 23.859,  91.361, 210 },
            { 380.187, 24.019, 150.749,  60 },
            { 330.943, 24.244,  99.591, 255 },
            { 256.112, 39.805, 149.514,  45 },
            { 187.398, 39.999,  95.752,  45 },
            { 170.601, 39.831,  25.066,  25 },
        },
    },

    [xi.zone.DAVOI] =
    {
        [treasureType.CHEST] =
        {
            {  235.907,  3.629, -251.378,  79 },
            {  290.556,  2.731, -291.040, 169 },
            {  297.370,  3.250, -219.350,  86 },
            {  327.747,  3.500, -190.758, 147 },
            {  165.449, -0.632, -267.748, 190 },
            {  115.242, -0.546, -252.004,  60 },
            {   65.686,  0.628, -347.556, 176 },
            {   63.105, -2.659, -191.565, 133 },
            { -109.608,  2.693,   50.392,  99 },
            {  -59.329, -0.672,   10.691, 191 },
            {  -59.163, -0.459,   69.200,  64 },
            {  -14.535,  0.583,  -67.930, 173 },
        },
    },

    [xi.zone.MONASTIC_CAVERN] =
    {
        [treasureType.COFFER] =
        {
            {   9.376, -1.345, -223.188, 187 },
            { 106.335, -0.829, -106.411, 148 },
            {  60.765, -0.333,  -93.267,  45 },
            {  12.823, -0.390, -144.714, 201 },
            {  37.379, -0.687, -146.255, 168 },
            {  22.771, -1.363, -130.966, 114 },
            {  17.613, -1.386,  -91.632,  60 },
            { -65.136, -0.739, -142.362,  32 },
            { -68.553, -1.002, -186.570,  30 },
            { -21.343, -0.797, -177.934, 107 },
        },
    },

    [xi.zone.CASTLE_OZTROJA] =
    {
        [treasureType.CHEST] =
        {
            {    7.378, -16.293, -193.590, 158 },
            {  -52.531,  24.218,  -12.087,  96 },
            {  -79.345,  23.731,  -39.930,  66 },
            { -107.048,  24.218,  -67.696, 223 },
            {  113.076, -16.326,  -85.606,  43 },
            {   50.230, -16.000, -186.078, 132 },
            {   66.460,  -4.285, -140.403,   0 },
            { -167.569, -16.293,  193.410,  40 },
            { -274.293, -16.285,  193.509, 230 },
            { -206.721, -16.000,   85.103, 192 },
            { -213.101,  -4.285,  139.820, 253 },
            { -102.026, -52.000,  180.448,   5 },
            {  -19.589, -15.750,  -15.309,  65 },
        },
        [treasureType.COFFER] =
        {
            { -102.723, -60.000, -222.555, 223 },
            { -266.089, -15.750,  -20.133,   0 },
            { -262.641, -20.000,  -60.291,   0 },
            { -144.194, -39.729,  -15.149,  34 },
            {  -80.274, -40.203,  -80.277, 130 },
            {  -15.114, -39.745, -134.880, 100 },
            {  -13.623, -39.834, -184.540, 160 },
            {  -60.369, -71.750, -146.231, 193 },
            { -139.729, -71.750,  -53.252,  63 },
            { -100.197, -72.511,  -13.141,  65 },
        },
    },

    [xi.zone.THE_BOYAHDA_TREE] =
    {
        [treasureType.COFFER] =
        {
            {   28.477,  6.335,  145.925,  95 },
            {  -62.707,  8.787,   80.017, 120 },
            { -100.194,  7.716,   71.802,   5 },
            {   26.121,  6.102,   95.937,  27 },
            {   68.144,  6.428,   54.531, 180 },
            {  108.235,  7.085,   26.143, 234 },
            {  136.094, 10.600,   26.152, 139 },
            {  176.461,  8.172,   65.105,  81 },
            {  184.816,  5.867,  -52.454, 200 },
            {  201.244,  8.791, -163.229,   0 },
            {  260.650,  8.445,  -73.685,  66 },
            {  215.152,  8.210,   16.315,  18 },
            {  251.260,  5.078,   24.927,  42 },
            {  251.809,  6.141,  -18.487,  12 },
        },
    },

    [xi.zone.MIDDLE_DELKFUTTS_TOWER] =
    {
        [treasureType.CHEST] =
        {
            { -339.909, -127.601,  20.816, 254 },
            { -420.058, -127.601,  99.913,  65 },
            { -398.356, -127.424,  20.397, 255 },
            { -499.848, -127.601,  20.397,  65 },
            { -359.633, -111.424, -39.286, 105 },
            { -416.369, -112.000,  62.454,  82 },
            { -425.616, -111.424,  -0.879,  60 },
            { -504.196, -112.000,  55.353, 247 },
        },
    },

    [xi.zone.UPPER_DELKFUTTS_TOWER] =
    {
        [treasureType.CHEST] =
        {
            { -380.060, -143.601, 20.603, 191 },
            { -333.356, -144.016, -0.481, 255 },
            { -250.738, -144.019, 72.633, 231 },
            { -220.087, -143.601, 19.370, 191 },
        },
    },

    [xi.zone.TEMPLE_OF_UGGALEPIH] =
    {
        [treasureType.COFFER] =
        {
            { -219.944, -0.800,   30.638, 192 },
            { -130.001,  0.000,   32.935,  65 },
            { -220.044,  0.000,  -19.961, 255 },
            {  -99.999,  0.000,  -15.989, 255 },
            { -122.910, -0.079,  -30.315, 125 },
            { -149.978,  0.000,  -46.935,  65 },
            { -126.637, -0.951,  -86.835,  65 },
            {  -49.102,  0.453, -100.020, 255 },
            {   20.002, -2.011, -143.061, 190 },
            {  -65.184,  0.022,   27.081,  65 },
        },
    },

    [xi.zone.DEN_OF_RANCOR] =
    {
        [treasureType.COFFER] =
        {
            { 371.199, -5.059,  260.752,  95 },
            { -17.924, 36.239, -130.382,  65 },
            {  10.426, 36.024,  -83.844, 255 },
            { -27.783, 44.986,   19.830, 130 },
            {  20.967, 16.957,  -37.771, 188 },
            { -17.675, 15.350,  -69.098,  23 },
            {  59.457, 15.435,  -68.965,  95 },
            { 139.838, 15.080, -131.904, 190 },
            { 122.006, 15.312,  -56.013,  62 },
            { 142.462, 15.834,  -21.777, 105 },
            { 372.407, -5.088,  340.338, 125 },
            { 460.201,  5.092,  331.775,  65 },
        },
    },

    [xi.zone.CASTLE_ZVAHL_BAILEYS] =
    {
        [treasureType.CHEST] =
        {
            {  110.041, -20.002, 106.811, 190 },
            {  -69.716, -19.468,  35.659,   0 },
            { -120.003, -24.000, 136.748, 190 },
            { -120.064, -24.000, 103.328,  65 },
            { -119.996, -24.000, -63.515, 190 },
            { -119.933, -24.000, -95.999,  65 },
            {  -19.920, -20.010, -29.472,  65 },
            {    9.900, -20.000,  12.662,  65 },
            {    9.900, -20.000,  27.921, 190 },
            {  -20.354, -20.200,  68.930, 190 },
            {  110.250, -20.011, -67.377,  65 },
            {   99.899, -24.065,  64.915,  65 },
            {   99.899, -24.077, -25.562, 190 },
            {   57.319, -24.000,  20.112,   0 },
            {   52.638, -24.000,  20.112, 127 },
        },
        [treasureType.COFFER] =
        {
            {  -72.899,  0.137,   19.549, 125 },
            {  -49.542,  0.137,   19.549,   0 },
            {  -59.511,  0.137,   30.749, 190 },
            {  -59.511,  0.137,   10.051,  65 },
            { -223.298, -8.000, -143.759, 190 },
            { -223.298, -8.000,  183.912,  65 },
            {  103.469, -8.000, -143.759, 190 },
            {  103.469, -8.000,  183.912,  65 },
        },
    },

    [xi.zone.CASTLE_ZVAHL_KEEP] =
    {
        [treasureType.CHEST] =
        {
            { -299.787, -48.000, 24.873, 62 },
        },
    },

    [xi.zone.TORAIMARAI_CANAL] =
    {
        [treasureType.COFFER] =
        {
            {  219.993, 16.003,  -49.049,  62 },
            {  -88.634, 16.000,  -31.234, 192 },
            { -191.180, 21.502, -100.104,   0 },
            { -191.211, 21.502, -140.088,   0 },
            {  -59.985, 21.502, -191.163, 192 },
            {  111.091, 21.502, -180.065, 128 },
            {  114.148, 16.000, -226.101, 192 },
            {   72.746, 16.000, -180.041, 128 },
            {   26.746, 16.500, -212.454, 226 },
            {    6.567, 16.000, -180.089,   0 },
            {  179.943, 21.502, -271.297, 192 },
            {  310.808, 21.502, -179.957, 128 },
            {  285.821, 18.000,  -59.620,  66 },
            {  143.977,  9.500, -103.950,  31 },
            {   95.977, 21.500,  -56.045, 159 },
        },
    },

    [xi.zone.KUFTAL_TUNNEL] =
    {
        [treasureType.COFFER] =
        {
            { 103.708, -11.326,  208.367, 191 },
            { 127.993, -11.318,   96.500,  13 },
            { 126.990,  -1.319,   49.802, 181 },
            { 154.813, -10.473,  -68.138, 148 },
            {  41.657, -11.623,   29.949, 106 },
            {  15.489, -11.354,    8.337,   4 },
            { -10.184,  -1.373,  127.082,  45 },
            {  26.277,  -1.554,  134.207, 163 },
            { -15.217,  -1.907,   51.530, 196 },
            { -92.888,  -0.282,    2.676,  10 },
            { -14.067, -11.940, -132.941, 192 },
            { -25.934, -11.000, -142.247,  61 },
            { -27.946, -21.825, -183.709,  30 },
        },
    },

    [xi.zone.SEA_SERPENT_GROTTO] =
    {
        [treasureType.CHEST] =
        {
            { 189.673, 18.999,  30.161, 129 },
            { 173.566, 20.431,  42.832,  16 },
            { 413.783,  8.448, -60.001, 124 },
            { 290.249,  8.469,   1.592,  12 },
            { 333.903, 18.404,  19.769, 128 },
            { 294.336, 18.301, 103.706,  73 },
            { 295.728, 25.854, 187.175, 244 },
            { 292.495, 28.200, 209.096, 254 },
            { 259.991, 28.488, 173.653,  64 },
            { 253.479,  8.156,  48.403, 217 },
            { 186.575,  8.570,  99.976,   3 },
        },
        [treasureType.COFFER] =
        {
            { -184.862, 17.989, -108.860, 207 },
            { -130.961, 29.207,   19.947,   4 },
            { -106.972, 19.055,  -65.469, 114 },
            { -168.173, 18.653,  -92.826,  35 },
            { -130.746, 20.058,  -24.084, 141 },
            { -188.832, 19.446,   56.939, 254 },
            { -220.245, 18.466,   53.843,  65 },
            { -288.582, 17.787,  -73.885, 149 },
            { -227.255, 10.000,  -65.473, 174 },
            { -259.927,  8.705, -133.028, 191 },
            { -356.233, 15.475, -104.030, 254 },
        },
    },

    [xi.zone.VELUGANNON_PALACE] =
    {
        [treasureType.COFFER] =
        {
            {  101.588, 15.837,  380.587,   1 },
            { -380.368, 15.700, -220.126, 128 },
            { -459.988, 16.000,  -73.829, 193 },
            { -434.639, 15.783,  300.084,   0 },
            { -180.435, 15.571,  420.049,   0 },
            {  379.990, 16.000,  394.593,  65 },
            {  434.650, 16.000,  300.083, 128 },
            {  459.977, 16.000,   74.027,  65 },
            {  379.929, 15.574, -219.582,  65 },
        },
    },

    [xi.zone.KING_RANPERRES_TOMB] =
    {
        [treasureType.CHEST] =
        {
            {  150.304,  0.000,  245.834, 250 },
            {  150.304,  0.000,  193.493, 250 },
            {  236.549, -0.210,  149.944, 126 },
            {  203.316,  0.000,  140.128, 250 },
            {  203.316,  0.000,  129.619, 250 },
            {  203.316,  0.000,  119.546, 250 },
            {  213.959,  0.000,  129.619, 126 },
            {  236.549, -0.169,  109.991, 126 },
            {  150.702,  0.000,   85.374, 250 },
            {  150.702,  0.000,   33.969, 250 },
            {  -19.585,  6.630,   14.74,  171 },
            { -118.680,  9.000,   60.010,   0 },
            {  -56.994,  7.359,  155.155, 194 },
            {  -40.195, -0.008, -130.093, 193 },
        },
    },

    [xi.zone.DANGRUF_WADI] =
    {
        [treasureType.CHEST] =
        {
            { -499.709, 3.262, 215.970, 254 },
            { -117.128, 3.970, 134.104,  73 },
            {  -60.745, 3.063, 295.362, 105 },
            {  -62.183, 3.215, 416.434, 105 },
            { -287.324, 3.538, 328.969,  27 },
            { -273.053, 4.406, 332.914,  50 },
            { -100.291, 3.277, 495.744,   0 },
            {  -62.243, 0.228, 564.120,   0 },
            { -206.223, 3.874, 571.662,  60 },
            { -247.736, 3.743, 576.783,  60 },
            { -239.459, 4.000, 505.813, 190 },
            { -198.482, 4.000, 506.684, 190 },
            { -264.091, 3.255, 460.409,  60 },
            { -337.859, 3.228, 384.203, 223 },
            { -419.957, 3.876, 335.875, 195 },
        },
    },

    [xi.zone.INNER_HORUTOTO_RUINS] =
    {
        [treasureType.CHEST] =
        {
            { -177.956, -0.002, -220.058, 125 },
        },
    },

    [xi.zone.ORDELLES_CAVES] =
    {
        [treasureType.CHEST] =
        {
            { -111.515,  27.986,  -90.305, 165 },
            { -109.446,  -0.021,  -90.724, 150 },
            { -108.188,  28.338,  -29.797, 103 },
            { -168.397,  28.112,  -28.818,  40 },
            {  -32.101,  -0.040,  -90.118, 192 },
            {  -50.539,  27.989,  -88.427, 236 },
            {  -51.511,  28.085,  -28.593,   8 },
            {  -15.960,  28.372,  -31.662, 198 },
            {   10.390,  28.396,  -30.526,  94 },
            {    8.064,  27.984,  -90.003, 185 },
            {  -98.103, -27.613, -285.174, 188 },
            { -140.193,   0.546,  176.329, 190 },
            { -112.788,  -0.035,  230.281, 194 },
            { -169.325,   0.008,  231.696, 236 },
            { -167.160,   0.068,  289.223,  62 },
        },
    },

    [xi.zone.OUTER_HORUTOTO_RUINS] =
    {
        [treasureType.CHEST] =
        {
            { -423.066, 0.000, 672.483, 250 },
        },
    },

    [xi.zone.THE_ELDIEME_NECROPOLIS] =
    {
        [treasureType.CHEST] =
        {
            {  171.927,  -7.999,  20.008, 254 },
            {  261.094, -33.250, 100.014,   1 },
            {   98.908, -33.250, 100.046, 127 },
            {   98.894, -33.250, -60.000, 127 },
            {  260.965, -33.250, -59.905,   1 },
            {  179.926, -32.000, -51.239, 193 },
            {  251.208, -32.000,  20.054, 128 },
            { -518.830,  -8.000, 500.082,   1 },
            { -411.948,   8.000, 499.879, 127 },
            { -438.279,   0.350, 304.854, 190 },
        },
        [treasureType.COFFER] =
        {
            {  159.011, -27.999,  161.005,  31 },
            {  179.864, -32.000,   91.100,  64 },
            {  108.749, -32.000,   19.951,   1 },
            {   39.264, -28.000,   -0.712, 223 },
            {  174.753,  -0.418, -100.369,   6 },
            {  299.967,   0.000,   69.413,  63 },
            {  300.082,   0.000,  -29.448, 194 },
            {  188.319,  -0.590,  128.702, 174 },
            { -386.548,  -3.000,  335.046,   2 },
        },
    },

    [xi.zone.GUSGEN_MINES] =
    {
        [treasureType.CHEST] =
        {
            {  -14.130, -39.999, -85.554, 216 },
            {   58.307, -39.959, -52.149, 128 },
            {  141.517, -41.565,  29.685, 204 },
            {  154.561, -41.685, 220.130,  62 },
            {   25.952, -40.100, 191.905,  62 },
            {  -66.074, -39.829, 250.589,  95 },
            { -137.702, -41.291,  -6.666, 245 },
            {   -6.105, -34.100, 113.459,  30 },
            {   -4.463, -20.000, 125.082, 154 },
            {   47.060, -20.199, 164.572, 128 },
            {   56.098, -19.823, 147.475, 128 },
            {   50.596, -19.842, 126.625, 153 },
        },
    },

    [xi.zone.CRAWLERS_NEST] =
    {
        [treasureType.CHEST] =
        {
            {  39.767, -0.178, -313.865,  13 },
            {  98.913, -1.981, -344.437, 255 },
            {  -7.115, -0.562, -382.455,  65 },
            {   9.410, -0.930, -418.559, 199 },
            { -93.078, -0.276, -393.625, 170 },
            { -57.575, -0.238, -279.965, 255 },
            {  24.264, -0.439,  165.450, 218 },
            {  11.445, -0.168,  211.587,  20 },
            {  54.721, -0.346,  233.897,  85 },
            {  35.373, -0.586,  264.295, 148 },
            { -15.799, -0.464,  245.820, 216 },
            { -32.961, -0.351,  294.132,  24 },
            { -89.586, -9.624,   95.296,  46 },
        },
        [treasureType.COFFER] =
        {
            {  -95.676, -0.436,  205.557, 211 },
            { -103.267, -1.766, -392.964, 229 },
            { -185.774, -0.282, -379.022, 235 },
            {  -45.265, -0.477,  224.265, 150 },
            { -113.889, -0.449,  255.583,  22 },
            { -129.480, -0.945,  378.933,  74 },
            { -150.126, -0.904,  341.438, 206 },
        },
    },

    [xi.zone.MAZE_OF_SHAKHRAMI] =
    {
        [treasureType.CHEST] =
        {
            {  290.287, 20.238, -138.060,   9 },
            {  -36.474,  0.063,  -70.480,  94 },
            {  260.698, -1.274,   54.472, 135 },
            {  125.956, 19.805,   10.593,  91 },
            {  -54.923, 18.781,  -19.130,  33 },
            {  -90.151, 15.670, -103.097, 143 },
            { -130.046, 19.263,  -43.970, 241 },
            {  -58.153, 20.000,  -62.085, 211 },
            {  -25.615, 19.763,  -52.841, 130 },
            {    0.785, 20.000, -165.362, 112 },
            {  397.238, -0.351,  -29.854,  63 },
            {  219.757, 18.799,  -63.968,  19 },
            {  239.982, 20.322,  -69.393,  69 },
            {  216.466, 20.200, -144.039, 222 },
            {  231.585, 20.000, -193.004,  11 },
            {  270.951, 20.000, -247.144, 212 },
        },
    },

    [xi.zone.GARLAIGE_CITADEL] =
    {
        [treasureType.CHEST] =
        {
            { -163.053,  0.000, 351.988, 128 },
            { -352.798, 15.602, 266.998, 124 },
            {  -84.561,  5.269, 139.762,   7 },
            {  -62.448,  0.000,  88.577, 128 },
            { -122.826,  0.000, 112.010, 128 },
            { -220.049,  0.000, 167.949,  65 },
            {   14.274,  6.000, 214.198, 101 },
            {   -7.949, -0.143, 296.822, 192 },
            {  -88.405,  4.784, 299.916,   2 },
            { -142.400,  0.000, 328.437, 128 },
        },
        [treasureType.COFFER] =
        {
            {    9.831,  5.781,  10.208, 247 },
            {  -20.193,  5.144,  85.064,  65 },
            {  100.057, -3.250, 103.200,  65 },
            { -183.168, -3.250,  59.951,   0 },
            { -127.756,  0.000, 379.906,   0 },
            {  -20.570, -3.250, 296.848, 193 },
            {   20.042, -9.250, 376.955, 193 },
        },
    },

    [xi.zone.FEIYIN] =
    {
        [treasureType.CHEST] =
        {
            {  170.680, -24.000, 210.826,  91 },
            {  172.161, -24.006, -88.152, 156 },
            {  210.956, -24.000, -31.915, 131 },
            {  112.361, -24.008, -52.220, 226 },
            {  136.771, -24.000,  43.430, 142 },
            {  102.932, -24.000,  76.664,  23 },
            {  170.954, -24.000, 131.078,  92 },
            {   28.788, -16.000, 108.641, 228 },
            {   -8.153, -16.000,  61.675, 232 },
            {  -45.479, -16.009,  93.216,  43 },
            { -116.587, -16.000,  29.954,   2 },
            { -164.008, -16.003,  95.594,  53 },
            { -190.058, -16.000,   3.435, 193 },
            {  -95.248, -16.005, 164.285,  13 },
        },
    },

    [xi.zone.IFRITS_CAULDRON] =
    {
        [treasureType.COFFER] =
        {
            { 190.735, -0.191,  -30.485, 159 },
            { -71.694, 19.585,  -21.956, 208 },
            { -64.669, 20.035,  -38.858,  58 },
            {  24.680, 20.033,  -38.530,  74 },
            {  51.015, 17.523, -131.594,  57 },
            {  -8.835, 18.592, -128.882,  80 },
            { -97.569,  3.927, -183.248,  38 },
            { -21.635, -1.884,  -71.206, 231 },
            {  31.185, -1.912,  -18.542,  86 },
            { 102.903,  3.939,  -97.614, 227 },
            { -67.400,  0.000,  -39.111,   2 },
            { -67.099,  0.000,   -0.796, 255 },
            { 160.900, -0.068,  -22.165, 182 },
        },
    },

    [xi.zone.QUICKSAND_CAVES] =
    {
        [treasureType.COFFER] =
        {
            { 613.598,  -6.057, -680.984, 255 },
            { 540.553, -16.920, -770.118, 192 },
            { 429.401, -16.890, -739.502, 255 },
            { 495.848, -10.863, -827.019, 194 },
            { 629.929, -16.899, -820.711, 255 },
            { 740.357, -16.877, -789.623,  66 },
            { 826.074, -11.118, -733.808,  94 },
            { 867.442,   1.146, -708.477, 156 },
            { 865.615,   1.942, -622.742,  27 },
            { 677.287,   3.220, -581.735, 192 },
        },
    },

    [xi.zone.LABYRINTH_OF_ONZOZO] =
    {
        [treasureType.CHEST] =
        {
            {   50.829,  3.684,  -27.560,   3 },
            {  168.573,  0.470, -139.665, 130 },
            {  110.267,  0.473,  -81.732,   8 },
            {   29.116,  0.000,  -76.713,  20 },
            {   49.899,  9.577,   53.460,  67 },
            {   26.995,  9.516,   23.172,   5 },
            {   -0.125,  9.741,  -52.931, 190 },
            {  -52.487, 13.674,  -68.977, 206 },
            { -136.452, -0.733,  167.586, 117 },
            {  -79.866,  4.695,  -26.886,  71 },
            { -103.552,  4.516,  -93.353, 194 },
            { -132.942,  4.746,  -78.719, 254 },
            { -187.134,  8.952,  -62.005,  31 },
            { -165.973,  8.771,  -93.768, 138 },
        },
    },
}

local lootTable =
{
    [xi.zone.PSOXJA] =
    {
        [treasureType.CHEST] =
        {
            { xi.item.NONE,      860 }, -- Gil
            { xi.item.AMETRINE,   20 },
            { xi.item.GARNET,     20 },
            { xi.item.GOSHENITE,  20 },
            { xi.item.ONYX,       20 },
            { xi.item.PERIDOT,    20 },
            { xi.item.SPHENE,     20 },
            { xi.item.TURQUOISE,  20 },
        },
    },

    [xi.zone.OLDTON_MOVALPOLOS] =
    {
        [treasureType.CHEST] =
        {
            { xi.item.NONE,      860 }, -- Gil
            { xi.item.AMETRINE,   20 },
            { xi.item.GOSHENITE,  20 },
            { xi.item.LIGHT_OPAL, 20 },
            { xi.item.ONYX,       20 },
            { xi.item.PERIDOT,    20 },
            { xi.item.SPHENE,     20 },
            { xi.item.TURQUOISE,  20 },
        },
    },

    [xi.zone.NEWTON_MOVALPOLOS] =
    {
        [treasureType.COFFER] =
        {
            { xi.item.NONE,        860 }, -- Gil
            { xi.item.AQUAMARINE,   20 },
            { xi.item.CHRYSOBERYL,  20 },
            { xi.item.JADEITE,      20 },
            { xi.item.MOONSTONE,    20 },
            { xi.item.PAINITE,      20 },
            { xi.item.SUNSTONE,     20 },
            { xi.item.ZIRCON,       20 },
        },
    },

    [xi.zone.SACRARIUM] =
    {
        [treasureType.CHEST] =
        {
            { xi.item.NONE,       900 }, -- Gil
            { xi.item.LIGHT_OPAL,  20 },
            { xi.item.GARNET,      20 },
            { xi.item.ONYX,        20 },
            { xi.item.PERIDOT,     20 },
            { xi.item.SPHENE,      20 },
        },
    },

    [xi.zone.RUAUN_GARDENS] =
    {
        [treasureType.COFFER] =
        {
            { xi.item.NONE,        840 }, -- Gil
            { xi.item.AQUAMARINE,   20 },
            { xi.item.CHRYSOBERYL,  20 },
            { xi.item.FLUORITE,     20 },
            { xi.item.JADEITE,      20 },
            { xi.item.MOONSTONE,    20 },
            { xi.item.PAINITE,      20 },
            { xi.item.SUNSTONE,     20 },
            { xi.item.ZIRCON,       20 },
        },
    },

    [xi.zone.FORT_GHELSBA] =
    {
        [treasureType.CHEST] =
        {
            { xi.item.NONE,             675 }, -- Gil
            { xi.item.COUGAR_BAGHNAKHS, 225 }, -- Item
            { xi.item.AMBER_STONE,       20 },
            { xi.item.AMETHYST,          20 },
            { xi.item.LAPIS_LAZULI,      20 },
            { xi.item.SARDONYX,          20 },
            { xi.item.TOURMALINE,        20 },
        },
    },

    [xi.zone.YUGHOTT_GROTTO] =
    {
        [treasureType.CHEST] =
        {
            { xi.item.NONE,             675 }, -- Gil
            { xi.item.COUGAR_BAGHNAKHS, 225 }, -- Item
            { xi.item.AMBER_STONE,       20 },
            { xi.item.AMETHYST,          20 },
            { xi.item.LAPIS_LAZULI,      20 },
            { xi.item.SARDONYX,          20 },
            { xi.item.TOURMALINE,        20 },
        },
    },

    [xi.zone.PALBOROUGH_MINES] =
    {
        [treasureType.CHEST] =
        {
            { xi.item.NONE,            660 }, -- Gil
            { xi.item.FLAME_BOOMERANG, 220 }, -- Item
            { xi.item.AMBER_STONE,      20 },
            { xi.item.AMETHYST,         20 },
            { xi.item.CLEAR_TOPAZ,      20 },
            { xi.item.LAPIS_LAZULI,     20 },
            { xi.item.SARDONYX,         20 },
            { xi.item.TOURMALINE,       20 },
        },
    },

    [xi.zone.GIDDEUS] =
    {
        [treasureType.CHEST] =
        {
            { xi.item.NONE,           660 }, -- Gil
            { xi.item.SHIELD_EARRING, 220 }, -- Item
            { xi.item.AMBER_STONE,     20 },
            { xi.item.AMETHYST,        20 },
            { xi.item.CLEAR_TOPAZ,     20 },
            { xi.item.LAPIS_LAZULI,    20 },
            { xi.item.SARDONYX,        20 },
            { xi.item.TOURMALINE,      20 },
        },
    },

    [xi.zone.BEADEAUX] =
    {
        [treasureType.CHEST] =
        {
            { xi.item.NONE,        660 }, -- Gil
            { xi.item.ADEPTS_ROPE, 220 }, -- Item
            { xi.item.AMETRINE,     20 },
            { xi.item.GARNET,       20 },
            { xi.item.GOSHENITE,    20 },
            { xi.item.LIGHT_OPAL,   20 },
            { xi.item.SPHENE,       20 },
            { xi.item.TURQUOISE,    20 },
        },
        [treasureType.COFFER] =
        {
            { xi.item.NONE,            615 }, -- Gil
            { xi.item.SCROLL_OF_BURST, 205 }, -- Item
            { xi.item.AQUAMARINE,       20 },
            { xi.item.CHRYSOBERYL,      20 },
            { xi.item.FLUORITE,         20 },
            { xi.item.JADEITE,          20 },
            { xi.item.MOONSTONE,        20 },
            { xi.item.PAINITE,          20 },
            { xi.item.PERIDOT,          20 },
            { xi.item.SUNSTONE,         20 },
            { xi.item.ZIRCON,           20 },
        },
    },

    [xi.zone.DAVOI] =
    {
        [treasureType.CHEST] =
        {
            { xi.item.NONE,          630 }, -- Gil
            { xi.item.ELECTRUM_RING, 210 }, -- Item
            { xi.item.AMETRINE,       20 },
            { xi.item.GARNET,         20 },
            { xi.item.GOSHENITE,      20 },
            { xi.item.LIGHT_OPAL,     20 },
            { xi.item.ONYX,           20 },
            { xi.item.PERIDOT,        20 },
            { xi.item.SPHENE,         20 },
            { xi.item.TURQUOISE,      20 },
        },
    },

    [xi.zone.MONASTIC_CAVERN] =
    {
        [treasureType.COFFER] =
        {
            { xi.item.NONE,             660 }, -- Gil
            { xi.item.PHYSICAL_EARRING, 220 }, -- Item
            { xi.item.CHRYSOBERYL,       20 },
            { xi.item.FLUORITE,          20 },
            { xi.item.JADEITE,           20 },
            { xi.item.MOONSTONE,         20 },
            { xi.item.PAINITE,           20 },
            { xi.item.SUNSTONE,          20 },
        },
    },

    [xi.zone.CASTLE_OZTROJA] =
    {
        [treasureType.CHEST] =
        {
            { xi.item.NONE,             630 }, -- Gil
            { xi.item.ELECTRUM_HAIRPIN, 210 }, -- Item
            { xi.item.AMETRINE,          20 },
            { xi.item.GARNET,            20 },
            { xi.item.GOSHENITE,         20 },
            { xi.item.LIGHT_OPAL,        20 },
            { xi.item.PERIDOT,           20 },
            { xi.item.SARDONYX,          20 },
            { xi.item.SPHENE,            20 },
            { xi.item.TURQUOISE,         20 },
        },
        [treasureType.COFFER] =
        {
            { xi.item.NONE,           630 }, -- Gil
            { xi.item.SAFEGUARD_RING, 210 }, -- Item
            { xi.item.AQUAMARINE,      20 },
            { xi.item.CHRYSOBERYL,     20 },
            { xi.item.FLUORITE,        20 },
            { xi.item.JADEITE,         20 },
            { xi.item.MOONSTONE,       20 },
            { xi.item.PAINITE,         20 },
            { xi.item.SUNSTONE,        20 },
            { xi.item.ZIRCON,          20 },
        },
    },

    [xi.zone.THE_BOYAHDA_TREE] =
    {
        [treasureType.COFFER] =
        {
            { xi.item.NONE,          630 }, -- Gil
            { xi.item.SCREAM_FUNGUS, 210 }, -- Item
            { xi.item.AQUAMARINE,     20 },
            { xi.item.CHRYSOBERYL,    20 },
            { xi.item.FLUORITE,       20 },
            { xi.item.JADEITE,        20 },
            { xi.item.MOONSTONE,      20 },
            { xi.item.PAINITE,        20 },
            { xi.item.SUNSTONE,       20 },
            { xi.item.ZIRCON,         20 },
        },
    },

    [xi.zone.MIDDLE_DELKFUTTS_TOWER] =
    {
        [treasureType.CHEST] =
        {
            { xi.item.NONE,         645 }, -- Gil
            { xi.item.EMETH_PICK,   215 }, -- Item
            { xi.item.AMBER_STONE,   20 },
            { xi.item.AMETHYST,      20 },
            { xi.item.CLEAR_TOPAZ,   20 },
            { xi.item.LAPIS_LAZULI,  20 },
            { xi.item.LIGHT_OPAL,    20 },
            { xi.item.ONYX,          20 },
            { xi.item.TOURMALINE,    20 },
        },
    },

    [xi.zone.UPPER_DELKFUTTS_TOWER] =
    {
        [treasureType.CHEST] =
        {
            { xi.item.NONE,         645 }, -- Gil
            { xi.item.EMETH_PICK,   215 }, -- Item
            { xi.item.AMBER_STONE,   20 },
            { xi.item.AMETHYST,      20 },
            { xi.item.CLEAR_TOPAZ,   20 },
            { xi.item.LAPIS_LAZULI,  20 },
            { xi.item.LIGHT_OPAL,    20 },
            { xi.item.ONYX,          20 },
            { xi.item.TOURMALINE,    20 },
        },
    },

    [xi.zone.TEMPLE_OF_UGGALEPIH] =
    {
        [treasureType.COFFER] =
        {
            { xi.item.NONE,        880 }, -- Gil
            { xi.item.CHRYSOBERYL,  20 },
            { xi.item.FLUORITE,     20 },
            { xi.item.MOONSTONE,    20 },
            { xi.item.PAINITE,      20 },
            { xi.item.SUNSTONE,     20 },
            { xi.item.ZIRCON,       20 },
        },
    },

    [xi.zone.DEN_OF_RANCOR] =
    {
        [treasureType.COFFER] =
        {
            { xi.item.NONE,    960 }, -- Gil
            { xi.item.PAINITE,  20 },
            { xi.item.ZIRCON,   20 },
        },
    },

    [xi.zone.CASTLE_ZVAHL_BAILEYS] =
    {
        [treasureType.CHEST] =
        {
            { xi.item.NONE,         660 }, -- Gil
            { xi.item.PHALANX_RING, 220 }, -- Item
            { xi.item.AMETRINE,      20 },
            { xi.item.GARNET,        20 },
            { xi.item.GOSHENITE,     20 },
            { xi.item.PERIDOT,       20 },
            { xi.item.ONYX,          20 },
            { xi.item.SPHENE,        20 },
        },
        [treasureType.COFFER] =
        {
            { xi.item.NONE,                      630 }, -- Gil
            { xi.item.SCROLL_OF_MAGES_BALLAD_II, 210 }, -- Item
            { xi.item.AQUAMARINE,                 20 },
            { xi.item.CHRYSOBERYL,                20 },
            { xi.item.FLUORITE,                   20 },
            { xi.item.JADEITE,                    20 },
            { xi.item.MOONSTONE,                  20 },
            { xi.item.PAINITE,                    20 },
            { xi.item.SUNSTONE,                   20 },
            { xi.item.ZIRCON,                     20 },
        },
    },

    [xi.zone.CASTLE_ZVAHL_KEEP] =
    {
        [treasureType.CHEST] =
        {
            { xi.item.NONE,         660 }, -- Gil
            { xi.item.PHALANX_RING, 220 }, -- Item
            { xi.item.GARNET,        20 },
            { xi.item.GOSHENITE,     20 },
            { xi.item.LIGHT_OPAL,    20 },
            { xi.item.PERIDOT,       20 },
            { xi.item.SPHENE,        20 },
            { xi.item.TURQUOISE,     20 },
        },
    },

    [xi.zone.TORAIMARAI_CANAL] =
    {
        [treasureType.COFFER] =
        {
            { xi.item.NONE,        860 }, -- Gil
            { xi.item.AQUAMARINE,   20 },
            { xi.item.CHRYSOBERYL,  20 },
            { xi.item.JADEITE,      20 },
            { xi.item.MOONSTONE,    20 },
            { xi.item.PAINITE,      20 },
            { xi.item.SUNSTONE,     20 },
            { xi.item.ZIRCON,       20 },
        },
    },

    [xi.zone.KUFTAL_TUNNEL] =
    {
        [treasureType.COFFER] =
        {
            { xi.item.NONE,        840 }, -- Gil
            { xi.item.AQUAMARINE,   20 },
            { xi.item.CHRYSOBERYL,  20 },
            { xi.item.FLUORITE,     20 },
            { xi.item.JADEITE,      20 },
            { xi.item.MOONSTONE,    20 },
            { xi.item.PAINITE,      20 },
            { xi.item.SUNSTONE,     20 },
            { xi.item.ZIRCON,       20 },
        },
    },

    [xi.zone.SEA_SERPENT_GROTTO] =
    {
        [treasureType.CHEST] =
        {
            { xi.item.NONE,       840 }, -- Gil
            { xi.item.AMETRINE,    20 },
            { xi.item.GARNET,      20 },
            { xi.item.GOSHENITE,   20 },
            { xi.item.LIGHT_OPAL,  20 },
            { xi.item.ONYX,        20 },
            { xi.item.PERIDOT,     20 },
            { xi.item.SPHENE,      20 },
            { xi.item.TURQUOISE,   20 },
        },
        [treasureType.COFFER] =
        {
            { xi.item.NONE,        860 }, -- Gil
            { xi.item.AQUAMARINE,   20 },
            { xi.item.CHRYSOBERYL,  20 },
            { xi.item.FLUORITE,     20 },
            { xi.item.JADEITE,      20 },
            { xi.item.MOONSTONE,    20 },
            { xi.item.PAINITE,      20 },
            { xi.item.SUNSTONE,     20 },
        },
    },

    [xi.zone.VELUGANNON_PALACE] =
    {
        [treasureType.COFFER] =
        {
            { xi.item.NONE,       960 }, -- Gil
            { xi.item.AQUAMARINE,  20 },
            { xi.item.ZIRCON,      20 },
        },
    },

    [xi.zone.KING_RANPERRES_TOMB] =
    {
        [treasureType.CHEST] =
        {
            { xi.item.NONE,          660 }, -- Gil
            { xi.item.BATTLE_GLOVES, 220 }, -- Item
            { xi.item.AMBER_STONE,    20 },
            { xi.item.AMETHYST,       20 },
            { xi.item.CLEAR_TOPAZ,    20 },
            { xi.item.LAPIS_LAZULI,   20 },
            { xi.item.SARDONYX,       20 },
            { xi.item.TOURMALINE,     20 },
        },
    },

    [xi.zone.DANGRUF_WADI] =
    {
        [treasureType.CHEST] =
        {
            { xi.item.NONE,            660 }, -- Gil
            { xi.item.TROPICAL_SHIELD, 220 }, -- Item
            { xi.item.AMBER_STONE,      20 },
            { xi.item.AMETHYST,         20 },
            { xi.item.CLEAR_TOPAZ,      20 },
            { xi.item.LAPIS_LAZULI,     20 },
            { xi.item.SARDONYX,         20 },
            { xi.item.TOURMALINE,       20 },
        },
    },

    [xi.zone.INNER_HORUTOTO_RUINS] =
    {
        [treasureType.CHEST] =
        {
            { xi.item.NONE,         675 }, -- Gil
            { xi.item.MOTH_AXE,     225 }, -- Item
            { xi.item.AMBER_STONE,   20 },
            { xi.item.AMETHYST,      20 },
            { xi.item.CLEAR_TOPAZ,   20 },
            { xi.item.LAPIS_LAZULI,  20 },
            { xi.item.TOURMALINE,    20 },
        },
    },

    [xi.zone.ORDELLES_CAVES] =
    {
        [treasureType.CHEST] =
        {
            { xi.item.NONE,         675 }, -- Gil
            { xi.item.FORCE_BELT,   225 }, -- Item
            { xi.item.AMBER_STONE,   20 },
            { xi.item.AMETHYST,      20 },
            { xi.item.CLEAR_TOPAZ,   20 },
            { xi.item.LAPIS_LAZULI,  20 },
            { xi.item.LIGHT_OPAL,    20 },
            { xi.item.ONYX,          20 },
            { xi.item.SARDONYX,      20 },
            { xi.item.TOURMALINE,    20 },
        },
    },

    [xi.zone.OUTER_HORUTOTO_RUINS] =
    {
        [treasureType.CHEST] =
        {
            { xi.item.NONE,         675 }, -- Gil
            { xi.item.MOTH_AXE,     225 }, -- Item
            { xi.item.AMBER_STONE,   20 },
            { xi.item.AMETHYST,      20 },
            { xi.item.CLEAR_TOPAZ,   20 },
            { xi.item.LAPIS_LAZULI,  20 },
            { xi.item.TOURMALINE,    20 },
        },
    },

    [xi.zone.THE_ELDIEME_NECROPOLIS] =
    {
        [treasureType.CHEST] =
        {
            { xi.item.NONE,       660 }, -- Gil
            { xi.item.FALCASTRA,  220 }, -- Item
            { xi.item.AMETRINE,    20 },
            { xi.item.GARNET,      20 },
            { xi.item.GOSHENITE,   20 },
            { xi.item.LIGHT_OPAL,  20 },
            { xi.item.ONYX,        20 },
            { xi.item.SPHENE,      20 },
        },
        [treasureType.COFFER] =
        {
            { xi.item.NONE,           675 }, -- Gil
            { xi.item.VILE_ELIXIR_P1, 225 }, -- Item
            { xi.item.CHRYSOBERYL,     20 },
            { xi.item.FLUORITE,        20 },
            { xi.item.MOONSTONE,       20 },
            { xi.item.PAINITE,         20 },
            { xi.item.SUNSTONE,        20 },
        },
    },

    [xi.zone.GUSGEN_MINES] =
    {
        [treasureType.CHEST] =
        {
            { xi.item.NONE,         645 }, -- Gil
            { xi.item.REPLICA_MAUL, 215 }, -- Item
            { xi.item.AMBER_STONE,   20 },
            { xi.item.AMETHYST,      20 },
            { xi.item.CLEAR_TOPAZ,   20 },
            { xi.item.LAPIS_LAZULI,  20 },
            { xi.item.LIGHT_OPAL,    20 },
            { xi.item.ONYX,          20 },
            { xi.item.TOURMALINE,    20 },
        },
    },

    [xi.zone.CRAWLERS_NEST] =
    {
        [treasureType.CHEST] =
        {
            { xi.item.NONE,       630 }, -- Gil
            { xi.item.GIGANT_AXE, 210 }, -- Item
            { xi.item.AMETRINE,    20 },
            { xi.item.GARNET,      20 },
            { xi.item.GOSHENITE,   20 },
            { xi.item.LIGHT_OPAL,  20 },
            { xi.item.ONYX,        20 },
            { xi.item.PERIDOT,     20 },
            { xi.item.SPHENE,      20 },
            { xi.item.TURQUOISE,   20 },
        },
        [treasureType.COFFER] =
        {
            { xi.item.NONE,        660 }, -- Gil
            { xi.item.HI_RERAISER, 220 }, -- Item
            { xi.item.AQUAMARINE,   20 },
            { xi.item.CHRYSOBERYL,  20 },
            { xi.item.JADEITE,      20 },
            { xi.item.PAINITE,      20 },
            { xi.item.SUNSTONE,     20 },
            { xi.item.ZIRCON,       20 },
        },
    },

    [xi.zone.MAZE_OF_SHAKHRAMI] =
    {
        [treasureType.CHEST] =
        {
            { xi.item.NONE,         630 }, -- Gil
            { xi.item.HEAT_ROD,     210 }, -- Item
            { xi.item.AMBER_STONE,   20 },
            { xi.item.AMETHYST,      20 },
            { xi.item.CLEAR_TOPAZ,   20 },
            { xi.item.LAPIS_LAZULI,  20 },
            { xi.item.LIGHT_OPAL,    20 },
            { xi.item.ONYX,          20 },
            { xi.item.SARDONYX,      20 },
            { xi.item.TOURMALINE,    20 },
        },
    },

    [xi.zone.GARLAIGE_CITADEL] =
    {
        [treasureType.CHEST] =
        {
            { xi.item.NONE,       630 }, -- Gil
            { xi.item.PYRO_ROBE,  210 }, -- Item
            { xi.item.AMETRINE,    20 },
            { xi.item.GARNET,      20 },
            { xi.item.GOSHENITE,   20 },
            { xi.item.LIGHT_OPAL,  20 },
            { xi.item.ONYX,        20 },
            { xi.item.PERIDOT,     20 },
            { xi.item.SPHENE,      20 },
            { xi.item.TURQUOISE,   20 },
        },
        [treasureType.COFFER] =
        {
            { xi.item.NONE,            705 }, -- Gil
            { xi.item.LIGHT_GAUNTLETS, 235 }, -- Item
            { xi.item.CHRYSOBERYL,      20 },
            { xi.item.JADEITE,          20 },
            { xi.item.MOONSTONE,        20 },
        },
    },

    [xi.zone.FEIYIN] =
    {
        [treasureType.CHEST] =
        {
            { xi.item.NONE,       630 }, -- Gil
            { xi.item.LIFE_BELT,  210 }, -- Item
            { xi.item.AMETRINE,    20 },
            { xi.item.GARNET,      20 },
            { xi.item.GOSHENITE,   20 },
            { xi.item.LIGHT_OPAL,  20 },
            { xi.item.ONYX,        20 },
            { xi.item.PERIDOT,     20 },
            { xi.item.SPHENE,      20 },
            { xi.item.TURQUOISE,   20 },
        },
    },

    [xi.zone.IFRITS_CAULDRON] =
    {
        [treasureType.COFFER] =
        {
            { xi.item.NONE,        880 }, -- Gil
            { xi.item.AQUAMARINE,   20 },
            { xi.item.CHRYSOBERYL,  20 },
            { xi.item.FLUORITE,     20 },
            { xi.item.MOONSTONE,    20 },
            { xi.item.PAINITE,      20 },
            { xi.item.SUNSTONE,     20 },
        },
    },

    [xi.zone.QUICKSAND_CAVES] =
    {
        [treasureType.COFFER] =
        {
            { xi.item.NONE,        880 }, -- Gil
            { xi.item.AQUAMARINE,   20 },
            { xi.item.CHRYSOBERYL,  20 },
            { xi.item.FLUORITE,     20 },
            { xi.item.JADEITE,      20 },
            { xi.item.PAINITE,      20 },
            { xi.item.SUNSTONE,     20 },
        },
    },

    [xi.zone.LABYRINTH_OF_ONZOZO] =
    {
        [treasureType.CHEST] =
        {
            { xi.item.NONE,       840 }, -- Gil
            { xi.item.AMETRINE,    20 },
            { xi.item.GARNET,      20 },
            { xi.item.GOSHENITE,   20 },
            { xi.item.LIGHT_OPAL,  20 },
            { xi.item.ONYX,        20 },
            { xi.item.PERIDOT,     20 },
            { xi.item.SPHENE,      20 },
            { xi.item.TURQUOISE,   20 },
        },
    },
}

-----------------------------------
-- Local functions
-----------------------------------
local function moveTreasure(npc, respawnTime)
    local zoneId         = npc:getZoneID()
    local containerType  = npcTable[npc:getName()]
    local positions      = posTable[zoneId][containerType]
    local chosenPosition = positions[math.random(1, #positions)]
    local hideTime       = respawnTime or 1800

    npc:setLocalVar('opened', 1)

    npc:queue(5000, function(npcEntity)
        npcEntity:entityAnimationPacket(xi.animationString.STATUS_DISAPPEAR)
        npcEntity:setLocalVar('opened', 0)
    end)

    npc:queue(7000, function(npcEntity)
        npcEntity:hideNPC(hideTime)
    end)

    npc:queue(10000, function(npcEntity)
        npcEntity:setPos(chosenPosition[1], chosenPosition[2], chosenPosition[3], chosenPosition[4])
        npcEntity:entityAnimationPacket(xi.animationString.STATUS_VISIBLE)
        npcEntity:setLocalVar('traded', 0)
    end)
end

local function openAndMoveTreasure(npc, respawnTime)
    npc:entityAnimationPacket(xi.animationString.OPEN_CRATE_GLOW)
    moveTreasure(npc, respawnTime)
end

local function trapAndMoveTreasure(npc, respawnTime)
    npc:entityAnimationPacket(xi.animationString.OPEN_CRATE_SMOKE)
    moveTreasure(npc, respawnTime)
end

local function handleGilDistribution(player, treasureLevel)
    local zoneId              = player:getZoneID()
    local playersInZoneTable  = {} -- Table with player objects both in alliance and in current player zone.
    local membersInZoneNumber = 1  -- Amount of entities (players and trusts) in alliance and in current player zone. It does start at 1.

    -- Calculate player members in zone. Alliance members count for gil obtention purposes.
    local allianceMembers = player:getAlliance()
    for i = 1, #allianceMembers do
        local allianceMember = allianceMembers[i]
        if zoneId == allianceMembers[i]:getZoneID() then
            membersInZoneNumber = utils.clamp(membersInZoneNumber + 1, 1, 6)
            if allianceMember:isPC() then
                table.insert(playersInZoneTable, allianceMember)
            end
        end
    end

    -- Calculate trusts. Trusts count as players for gil obtention puroposes but not for gil division.
    local partyMembers = player:getPartyWithTrusts()
    for i = 1, #partyMembers do
        local partyMember = partyMembers[i]
        if partyMember:isTrust() then
            membersInZoneNumber = utils.clamp(membersInZoneNumber + 1, 1, 6)
        end
    end

    -- Calculate gil.
    local gilPerEntity = 0
    if #playersInZoneTable > 0 then
        gilPerEntity = membersInZoneNumber * treasureLevel ^ 2 + membersInZoneNumber * treasureLevel * math.random(0, treasureLevel)
        gilPerEntity = math.floor(gilPerEntity / #playersInZoneTable)
    end

    -- Distribute gil.
    for i = 1, #playersInZoneTable do
        npcUtil.giveCurrency(playersInZoneTable[i], 'gil', gilPerEntity, true)
    end
end

-----------------------------------
-- Public functions
-----------------------------------
xi.treasure.initZone = function(zone)
    local zoneId = zone:getID()
    local ID     = zones[zoneId]

    if ID.npc.TREASURE_CHEST then
        local npc = GetNPCByID(ID.npc.TREASURE_CHEST)
        if npc then
            npc:setStatus(xi.status.NORMAL)
            moveTreasure(npc, respawnType.IMMEDIATE)
        end
    end

    if ID.npc.TREASURE_COFFER then
        local npc = GetNPCByID(ID.npc.TREASURE_COFFER)
        if npc then
            npc:setStatus(xi.status.NORMAL)
            moveTreasure(npc, respawnType.IMMEDIATE)
        end
    end
end

--[[
ID.text.CHEST_UNLOCKED - 8 : This chest is locked. It can be opened with %.
ID.text.CHEST_UNLOCKED - 7 : This chest is empty.
ID.text.CHEST_UNLOCKED - 6 : Your inventory is full. You cannot carry any more items.
ID.text.CHEST_UNLOCKED - 5 : You must be closer to the chest to open it.
ID.text.CHEST_UNLOCKED - 4 : % opens the chest and finds %.
ID.text.CHEST_UNLOCKED - 3 : The item in this chest cannot be handled by the other members of your party. % receives the %.
ID.text.CHEST_UNLOCKED - 2 : % obtains a key item, %, from the chest.
ID.text.CHEST_UNLOCKED - 1 : You obtain a key item, %, from the chest.
ID.text.CHEST_UNLOCKED + 0 : You unlock the chest!
ID.text.CHEST_UNLOCKED + 1 : % fails to open the chest.
ID.text.CHEST_UNLOCKED + 2 : The chest was trapped!
ID.text.CHEST_UNLOCKED + 3 : You cannot open the chest when you are in a weakened state.
ID.text.CHEST_UNLOCKED + 4 : The chest was a mimic!
ID.text.CHEST_UNLOCKED + 5 : You cannot open the chest while participating in the moogle event.
ID.text.CHEST_UNLOCKED + 6 : The chest was but an illusion...
ID.text.CHEST_UNLOCKED + 7 : The chest appears to be locked. If only you had %, perhaps you could open it...
]]--

xi.treasure.onTrade = function(player, npc, trade, bypassType, bypassReward)
    -- Treasure data.
    local zoneId        = player:getZoneID()
    local ID            = zones[zoneId]
    local containerType = npcTable[npc:getName()]

    -- Fetch data.
    local treasureKey   = keyTable[zoneId][containerType]
    local treasureLevel = levelTable[zoneId][containerType] -- Used for Gil and THF tool calculations.
    local treasureMap   = mapTable[zoneId][containerType]
    local itemTable     = lootTable[zoneId][containerType]

    -- Early return: Distance check.
    if player:checkDistance(npc) > 2 then
        player:messageSpecial(ID.text.CHEST_UNLOCKED - 5)
        return
    end

    -- Early return: Treasure is already open.
    if
        npc:getLocalVar('opened') ~= 0 or
        npc:getLocalVar('traded') ~= 0
    then
        player:messageSpecial(ID.text.CHEST_UNLOCKED - 7)
        return
    end

    -----------------------------------
    -- Validate trade.
    -----------------------------------
    local keyUsed = 0

    -- Validate zone key.
    if trade:getItemQty(treasureKey) == 1 then
        keyUsed = keyType.ZONE_KEY
    end

    -- Validate THF tools.
    if player:getMainJob() == xi.job.THF then
        if trade:getItemQty(xi.item.SET_OF_THIEFS_TOOLS) == 1 then
            keyUsed = keyType.THIEF_TOOLS
        elseif trade:getItemQty(xi.item.LIVING_KEY) == 1 then
            keyUsed = keyType.LIVING_KEY
        elseif trade:getItemQty(xi.item.SKELETON_KEY) == 1 then
            keyUsed = keyType.SKELETON_KEY
        end
    end

    -- Early return: Invalid trade.
    if
        keyUsed == 0 or
        trade:getItemCount() ~= 1
    then
        player:messageSpecial(ID.text.CHEST_UNLOCKED + 7, treasureKey)
        return
    end

    -- Early return: Player has no room for items.
    if player:getFreeSlotsCount() == 0 then
        player:messageSpecial(ID.text.CHEST_UNLOCKED - 6)
        return
    end

    -- Early return: Can't lockpick while weakened.
    if
        keyUsed ~= keyType.ZONE_KEY and
        player:hasStatusEffect(xi.effect.WEAKNESS)
    then
        player:messageSpecial(ID.text.CHEST_UNLOCKED + 3)
        return
    end

    -----------------------------------
    -- Attempt to open treasure.
    -----------------------------------
    -- Player animations.
    player:setFreezeFlag(true)
    player:setRotation(player:getFacingAngle(npc))
    player:sendEmote(npc, xi.emote.KNEEL, xi.emoteMode.MOTION)
    player:delStatusEffect(xi.effect.SNEAK)
    player:delStatusEffect(xi.effect.DEODORIZE)
    npc:setLocalVar('traded', 1)

    if keyUsed ~= keyType.ZONE_KEY then
        local levelFactor = utils.clamp(player:getMainLvl() / treasureLevel, 0, 2)
        local successRate = utils.clamp(25 * levelFactor + thiefKeyInfo[keyUsed][2], 0, 95)

        -- Fail.
        if math.random(1, 100) > successRate then
            player:tradeComplete()

            local outcome = math.random(1, containerType + 1)
            -- Nothing happens
            if outcome == 1 then
                player:timer(2000, function(playerEntity)
                    playerEntity:messageName(ID.text.CHEST_UNLOCKED + 1, playerEntity)
                    npc:setLocalVar('traded', 0)
                end)

                player:timer(4000, function(playerEntity)
                    playerEntity:setFreezeFlag(false)
                end)

                return

            -- It's a trap!
            elseif outcome == 2 then
                player:timer(2000, function(playerEntity)
                    playerEntity:addStatusEffect(xi.effect.WEAKNESS, 1, 0, math.random(300, 10800)) -- 5 minutes to 3 hours
                    playerEntity:messageSpecial(ID.text.CHEST_UNLOCKED + 2)
                    trapAndMoveTreasure(npc, respawnType.REGULAR)
                end)

                player:timer(4000, function(playerEntity)
                    playerEntity:setFreezeFlag(false)
                end)

                return

            -- Mimic (Coffers only)
            else
                player:timer(2000, function(playerEntity)
                    local mimicId = ID.mob.MIMIC
                    local mimic   = GetMobByID(mimicId)

                    if not mimic then
                        playerEntity:messageName(ID.text.CHEST_UNLOCKED + 1, playerEntity)
                        npc:setLocalVar('traded', 0)
                        return
                    end

                    mimic:setSpawn(npc:getXPos(), npc:getYPos(), npc:getZPos(), npc:getRotPos())
                    npcUtil.popFromQM(playerEntity, npc, mimicId, { claim = true, hide = 5 })
                    playerEntity:messageSpecial(ID.text.CHEST_UNLOCKED + 4)
                    moveTreasure(npc, respawnType.IMMEDIATE)
                    playerEntity:setFreezeFlag(false)
                end)

                return
            end
        end
    end

    -----------------------------------
    -- Handle quest item reward.
    -----------------------------------
    if bypassType == 1 then
        player:tradeComplete()
        player:timer(2000, function(playerEntity)
            if npcUtil.giveItem(playerEntity, bypassReward) then
                playerEntity:messageSpecial(ID.text.CHEST_UNLOCKED)
                openAndMoveTreasure(npc, respawnType.REGULAR)
            end
        end)

        player:timer(4000, function(playerEntity)
            playerEntity:setFreezeFlag(false)
        end)

        npc:setLocalVar('traded', 0)
        return

    -----------------------------------
    -- Handle quest Key Item reward.
    -----------------------------------
    elseif bypassType == 2 then
        player:tradeComplete()
        player:timer(2000, function(playerEntity)
            playerEntity:messageSpecial(ID.text.CHEST_UNLOCKED - 1, bypassReward) -- TODO: message -2 seems to be for other party members?
            playerEntity:addKeyItem(bypassReward)
            openAndMoveTreasure(npc, respawnType.REGULAR)
        end)

        player:timer(4000, function(playerEntity)
            playerEntity:setFreezeFlag(false)
        end)

        return
    end

    -----------------------------------
    -- Handle map Key Item.
    -----------------------------------
    if
        treasureMap > 0 and
        not player:hasKeyItem(treasureMap)
    then
        player:tradeComplete()
        player:timer(2000, function(playerEntity)
            playerEntity:messageSpecial(ID.text.CHEST_UNLOCKED - 1, treasureMap) -- TODO: message -2 seems to be for other party members?
            playerEntity:addKeyItem(treasureMap)
            openAndMoveTreasure(npc, respawnType.REGULAR)
        end)

        player:timer(4000, function(playerEntity)
            playerEntity:setFreezeFlag(false)
        end)

        return
    end

    -----------------------------------
    -- Handle Illusion.
    -----------------------------------
    if GetSystemTime() < npc:getLocalVar('illusionCooldown') then
        player:timer(2000, function(playerEntity)
            playerEntity:messageSpecial(ID.text.CHEST_UNLOCKED + 6)
            moveTreasure(npc, respawnType.REGULAR)
        end)

        player:timer(4000, function(playerEntity)
            playerEntity:setFreezeFlag(false)
        end)

        return
    end

    -----------------------------------
    -- Handle regular loot.
    -----------------------------------
    local roll   = math.random(1, 1000)
    local itemId = xi.item.NONE
    local weight = 0
    for i = 1, #itemTable do
        weight = weight + itemTable[i][2]
        if roll <= weight then
            itemId = itemTable[i][1]
            break
        end
    end

    -- Gil
    if itemId == xi.item.NONE then
        -- Distribute gil.
        player:timer(2000, function(playerEntity)
            playerEntity:tradeComplete()
            playerEntity:messageSpecial(ID.text.CHEST_UNLOCKED)
            handleGilDistribution(playerEntity, treasureLevel)
            openAndMoveTreasure(npc, respawnType.REGULAR)
        end)

        player:timer(4000, function(playerEntity)
            playerEntity:setFreezeFlag(false)
        end)

    -- Items (Gems or others)
    else
        player:timer(2000, function(playerEntity)
            playerEntity:tradeComplete()
            playerEntity:addTreasure(itemId, npc)
            playerEntity:messageSpecial(ID.text.CHEST_UNLOCKED)
            openAndMoveTreasure(npc, respawnType.REGULAR)
        end)

        player:timer(4000, function(playerEntity)
            playerEntity:setFreezeFlag(false)
        end)
    end

    -- Handle illusion timers.
    if containerType == treasureType.CHEST then
        npc:setLocalVar('illusionCooldown', GetSystemTime() + math.random(xi.settings.main.CHEST_MIN_ILLUSION_TIME, xi.settings.main.CHEST_MAX_ILLUSION_TIME))
    else
        npc:setLocalVar('illusionCooldown', GetSystemTime() + math.random(xi.settings.main.COFFER_MIN_ILLUSION_TIME, xi.settings.main.COFFER_MAX_ILLUSION_TIME))
    end
end

xi.treasure.onTrigger = function(player, npc)
    local zoneId = player:getZoneID()
    local ID     = zones[zoneId]

    if npc:getLocalVar('opened') == 0 then
        player:messageSpecial(ID.text.CHEST_UNLOCKED - 8, keyTable[zoneId][npcTable[npc:getName()]])
    else
        player:messageSpecial(ID.text.CHEST_UNLOCKED - 7)
    end
end
