-----------------------------------
--  Area: Castle Zvahl Baileys
--   NPC: Switchstix
--  Type: Standard NPC
--  @pos 386.091 -13 -17.399 161
-----------------------------------
package.loaded["scripts/zones/Castle_Zvahl_Baileys/TextIDs"] = nil;
require("scripts/zones/Castle_Zvahl_Baileys/TextIDs");
require("scripts/globals/keyitems");
require("scripts/globals/status");
-----------------------------------

local relics = {
   -- Current Stage, Item 1, Item 2, Item 3, # of items, currency type, currency amount, stage #, cs param 8 (manages turn in cutscenes (1-3) and Aegis (4-6))
   -- The various parameters are stored in a subarray for ease of use with return.
   18260, { 1460,  1459,   665,  4,  1456,   4,  1,  1}, -- Spharai
   18261, {16390, 16392, 16396,  4,  1453,  14,  2,  2},
   18262, { 1556,     0,     0,  2,  1450,  61,  3,  3},
   18263, { 1571,  1589,     0,  0,  1457,   1,  4,  3},

   18266, { 4246,   747,  4166,  4,  1456,   4,  1,  1}, -- Mandau
   18267, {16449, 16496, 16452,  4,  1453,  14,  2,  2},
   18268, { 1557,     0,     0,  2,  1450,  61,  3,  3},
   18269, { 1572,  1589,     0,  0,  1457,   1,  4,  3},

   18272, { 1460,   763,   931,  4,  1453,   4,  1,  1}, -- Excalibur
   18273, {16535, 16537, 16542,  4,  1456,  14,  2,  2},
   18274, { 1558,     0,     0,  2,  1450,  61,  3,  3},
   18275, { 1573,  1589,     0,  0,  1454,   1,  4,  3},

   18278, { 1459,   655,   746,  4,  1453,   4,  1,  1}, -- Ragnarok
   18279, {16583, 16584, 16585,  4,  1450,  14,  2,  2},
   18280, { 1559,     0,     0,  2,  1456,  61,  3,  3},
   18281, { 1574,  1589,     0,  0,  1454,   1,  4,  3},

   18284, { 1312,  1463, 13060,  4,  1450,   3,  1,  1}, -- Guttler
   18285, {16657, 16658, 16659,  4,  1453,  14,  2,  2},
   18286, { 1560,     0,     0,  2,  1456,  60,  3,  3},
   18287, { 1575,  1589,     0,  0,  1451,   1,  4,  3},

   18290, { 1461,   658,   720,  4,  1456,   3,  1,  1}, -- Bravura
   18291, {16704, 16705, 16724,  4,  1450,  16,  2,  2},
   18292, { 1561,     0,     0,  2,  1453,  60,  3,  3},
   18293, { 1576,  1589,     0,  0,  1457,   1,  4,  3},

   18296, { 1462,   747,  1294,  4,  1450,   4,  1,  1}, -- Gungnir
   18297, {16834, 16836, 16841,  4,  1456,  16,  2,  2},
   18298, { 1563,     0,     0,  2,  1453,  61,  3,  3},
   18299, { 1578,  1589,     0,  0,  1451,   1,  4,  3},

   18302, { 1458,  1117, 13208,  4,  1450,   5,  1,  1}, -- Apocalypse
   18303, {16774, 16794, 16777,  4,  1453,  16,  2,  2},
   18304, { 1562,     0,     0,  2,  1456,  62,  3,  3},
   18305, { 1577,  1589,     0,  0,  1451,   1,  4,  3},

   18308, { 1467,  1276,  1278,  4,  1456,   4,  1,  1}, -- Kikoku
   18309, {16900, 16903, 16902,  4,  1450,  16,  2,  2},
   18310, { 1564,     0,     0,  2,  1453,  61,  3,  3},
   18311, { 1579,  1589,     0,  0,  1457,   1,  4,  3},

   18314, { 1467,  1409,   657,  4,  1453,   3,  1,  1}, -- Amanomurakumo
   18315, {16966, 16967, 16972,  4,  1450,  15,  2,  2},
   18316, { 1565,     0,     0,  2,  1456,  60,  3,  3},
   18317, { 1580,  1589,     0,  0,  1454,   1,  4,  3},

   18320, { 1461,   746,   830,  4,  1453,   5,  1,  1}, -- Mjollnir
   18321, {17044, 17080, 17043,  4,  1456,  16,  2,  2},
   18322, { 1566,     0,     0,  2,  1450,  62,  3,  3},
   18323, { 1581,  1589,     0,  0,  1454,   1,  4,  3},

   18326, { 1462,  1271,  1415,  4,  1450,   5,  1,  1}, -- Claustrum
   18327, {17088, 17090, 17092,  4,  1456,  16,  2,  2},
   18328, { 1567,     0,     0,  2,  1453,  62,  3,  3},
   18329, { 1582,  1589,     0,  0,  1451,   1,  4,  3},

   18332, { 1468,   830,   654,  4,  1456,   5,  1,  1}, -- Annihilator
   18333, {17248, 17251, 17259,  4,  1450,  15,  2,  2},
   18334, { 1570,     0,     0,  2,  1453,  62,  3,  3},
   18335, { 1585,  1589,     0,  0,  1457,   1,  4,  3},

   18338, { 1458,  1463, 13232,  4,  1450,   3,  1,  1}, -- Gjallarhorn
   18339, {17352, 17351, 17362,  4,  1456,  14,  2,  2},
   18340, { 1569,     0,     0,  2,  1453,  60,  3,  3},
   18341, { 1584,  1589,     0,  0,  1451,   1,  4,  3},

   18344, {  883,  1462,   932,  4,  1453,   4,  1,  1}, -- Yoichinoyumi
   18345, {17161, 17164, 18142,  4,  1453,  15,  2,  2},
   18346, { 1568,     0,     0,  2,  1450,  61,  3,  3},
   18347, { 1583,  1589,     0,  0,  1454,   1,  4,  3},

   15066, {  875,   668,   720,  4,     0,   1,  1,  4}, -- Aegis
   15067, {12301, 12295, 12387,  4,     0,   4,  2,  5},
   15068, { 1821,     0,     0,  2,     0,  20,  3,  6},
   15069, { 1822,  1589,     0,  0,  1454,   1,  4,  6}
};

function hasRelic(entity,checktype)
   -- Type 1 == Player is triggering NPC
   -- Type 2 == Player is trading an item

   if checktype == 1 then
      for i=1, table.getn(relics), 2 do -- Step through the array grabbing every second (2) value, and see if it matches that itemid.
         if (entity:hasItem(relics[i],LOC_INVENTORY)) then -- Specifically checks inventory, so that items in other containers (mog safe, satchel, etc) will be ignored.
            return relics[i];
         end
      end
   elseif checktype == 2 then
      for i=1, table.getn(relics),2 do
         if (entity:hasItemQty(relics[i],1)) then
            return relics[i];
         end
      end
   end
end;

function getRelicParameters(itemid)
   for i=1, table.getn(relics), 2 do
      if (relics[i] == itemid) then -- If you've found the right itemid, return the array stored in the next value.
         return relics[i + 1];
      end
   end
end;

-----------------------------------
-- onTrade Action
-----------------------------------

function onTrade(player,npc,trade)
   local itemid = hasRelic(trade,2);
   local eventParams = {}; -- item1, item2, item3, num_items, currencytype, currencyamount, finalvar
   local currentRelic = player:getVar("RELIC_IN_PROGRESS"); -- Stores which item has been taken from the player
   local relicWait = player:getVar("RELIC_DUE_AT"); -- Stores time that relic can be retrieved after
   local relicDupe = player:getVar("RELIC_MAKE_ANOTHER"); -- Stores a value that the player has acknowledged they can't hold the item they want to make yet they're making it anyway.
   local count = trade:getItemCount();
   local gil = trade:getGil();
   local tradeOK = false;

   -- Starting a stage upgrade.
   -- No relics in progress, found a relic in the trade with other items, and (doesn't already own next stage, or (owns it and has acknowledged this is a bad idea))
   if (currentRelic == 0 and itemid ~= nil and gil == 0 and count > 1 and (player:hasItem(itemid+1) == false or (player:hasItem(itemid+1) == true and relicDupe == 1))) then
      eventParams = getRelicParameters(itemid);

         -- Stage 1->2 or 2->3, 3 items + relic itself
         if(count == eventParams[4] and trade:hasItemQty(eventParams[1],1) and trade:hasItemQty(eventParams[2],1) and
            trade:hasItemQty(eventParams[3],1) and trade:hasItemQty(itemid,1)) then
               tradeOK = true;

         -- Stage 3->4, just check for attestation + relic itself
         elseif(count == eventParams[4] and trade:hasItemQty(eventParams[1],1) and trade:hasItemQty(itemid,1)) then
            tradeOK = true;

         -- Stage 4->5, Shard + Necropschye + relic itself
         elseif(count == eventParams[4] and trade:hasItemQty(eventParams[1],1) and trade:hasItemQty(eventParams[2],1) and trade:hasItemQty(itemid,1)) then
            tradeOK = true;
         end

         -- Trade is valid, so set vars, complete trade, and give a CS
         if tradeOK == true then
            player:setVar("RELIC_IN_PROGRESS",itemid);
            player:tradeComplete();
            player:startEvent(11, itemid, eventParams[1], eventParams[2], eventParams[3], eventParams[5], eventParams[6], 0, eventParams[8]);
         end

   -- Already owns the next stage and hasn't acknowledged this is a bad idea yet.
   elseif (itemid ~= nil and relicDupe ~= 1 and player:hasItem(itemid+1) == true) then
      player:startEvent(20,itemid);

   -- Trading a new relic with one already in progress.  Offer cancellation.
   elseif (currentRelic ~= 0 and itemid ~= nil) then
      player:startEvent(87);

   -- Has turned in a relic and items, has not turned in currency (no wait), so they must be bringing currency
   elseif (currentRelic ~= 0 and relicWait == 0 and gil == 0) then
      eventParams = getRelicParameters(currentRelic);

      -- Has currencyamount of currencytype, and nothing additional.  See below for Aegis, since it's different.
      if (count == eventParams[6] and trade:hasItemQty(eventParams[5],eventParams[6])) then
         tradeOK = true;

      -- Aegis uses all three currency types for the first 3 stages.  It has currencytype 0 in these situations.
      elseif (count == eventParams[6] * 3 and eventParams[5] == 0) then
         -- Has currencyamount of all three currencies
         if (trade:hasItemQty(1450,eventParams[6]) and trade:hasItemQty(1453,eventParams[6]) and trade:hasItemQty(1456,eventParams[6])) then
            tradeOK = true;
         end
      end

      -- Trade is valid, so set variables, complete the trade, and give a CS to acknowledge it.
      if (tradeOK == true) then

         -- Stage is stored in array value 7

         -- Stage 1->2, wait until next game day
         if (eventParams[7] == 1) then
            player:setVar("RELIC_DUE_AT",getMidnight());

         -- Stage 2->3, wait RELIC_2ND_UPGRADE_WAIT_TIME (604800s / 1 week default)
         elseif (eventParams[7] == 2) then
            player:setVar("RELIC_DUE_AT",os.time() + RELIC_2ND_UPGRADE_WAIT_TIME);

         -- Stage 3->4, wait RELIC_3RD_UPGRADE_WAIT_TIME (295200s / 3 days 10 hours default)
         elseif (eventParams[7] == 3) then
            player:setVar("RELIC_DUE_AT",os.time() + RELIC_3RD_UPGRADE_WAIT_TIME);
         end
         player:tradeComplete();
         player:startEvent(13, currentRelic, eventParams[5], eventParams[6], 0, 0, 0, 0, eventParams[8]);
      end
   end

end;

-----------------------------------
-- onTrigger Action
-----------------------------------

function onTrigger(player,npc)
   local itemid = hasRelic(player,1);
   local eventParams = {}; -- item1, item2, item3, num_items, currencytype, currencyamount, finalvar
   local currentRelic = player:getVar("RELIC_IN_PROGRESS");
   local relicWait = player:getVar("RELIC_DUE_AT"); -- Stores time that relic can be retrieved after
   local relicConquest = player:getVar("RELIC_CONQUEST_WAIT");

   -- Working on a relic, waiting on completion, and time hasn't passed yet, so tell them to wait longer.
   if (currentRelic ~= 0 and relicWait ~= 0 and relicWait > os.time()) then
      eventParams = getRelicParameters(currentRelic);

      -- Determine cutscene to play by Stage
      if (eventParams[7] == 1) then
         player:startEvent(15, 0, 0, 0, 0, 0, 0, 0, eventParams[8]);
      elseif (eventParams[7] == 2) then
         player:startEvent(18, 0, 0, 0, 0, 0, 0, 0, eventParams[8]);
      elseif (eventParams[7] == 3) then
         player:startEvent(51, 0, 0, 0, 0, 0, 0, 0, eventParams[8]);
      end

   -- Working on a relic, waiting on completion, and time has passed.
   elseif (currentRelic ~= 0 and relicWait ~= 0 and relicWait <= os.time()) then
      eventParams = getRelicParameters(currentRelic);

      -- Determine the cutscene to play by Stage
      if (eventParams[7] == 1) then
         player:startEvent(16, currentRelic, 0, 0, 0, 0, 0, 0, eventParams[8]);
      elseif (eventParams[7] == 2) then
         player:startEvent(19, currentRelic, 0, 0, 0, 0, 0, 0, eventParams[8]);
      elseif (eventParams[7] == 3) then
         player:startEvent(52, currentRelic, 0, 0, 0, 0, 0, 0, eventParams[8]);
      end

   -- Working on a relic and not waiting, so currency is due
   elseif (currentRelic ~= 0 and relicWait == 0) then
      eventParams = getRelicParameters(currentRelic);
      player:startEvent(12, currentRelic, eventParams[5], eventParams[6], 0, 0, 0, 0, eventParams[8]);

   -- No relic, or waiting until next conquest tally.
   elseif (itemid == nil or relicConquest > os.time()) then
      player:startEvent(10);

   -- Found a relic and conquest tally is not due (0, or passed), time to explain a stage
   elseif (itemid ~= nil and relicConquest <= os.time()) then
      eventParams = getRelicParameters(itemid);

      -- Determine stage based on eventParams[7]
      if (eventParams[7] == 1) then
         player:startEvent(14, itemid, eventParams[1], eventParams[2], eventParams[3], 0, 0, 0, eventParams[8]);
      elseif (eventParams[7] == 2) then
         player:startEvent(17, itemid, eventParams[1], eventParams[2], eventParams[3], 0, 0, 0, eventParams[8]);
      elseif (eventParams[7] == 3) then
         player:startEvent(50, itemid, eventParams[1], 0, 0, 0, 0, 0, eventParams[8]);

      -- Stage 4 logic starts here.  Every weapon has its own cutscene.
      elseif (eventParams[7] == 4) then
         switch (itemid): caseof
         { -- Fragment for body, Necropsyche for soul
            [18263] = function (x) player:startEvent(68, eventParams[1], eventParams[2], eventParams[5], eventParams[6], itemid); end, -- Spharai
            [18269] = function (x) player:startEvent(69, eventParams[1], eventParams[2], eventParams[5], eventParams[6], itemid); end, -- Mandau
            [18275] = function (x) player:startEvent(70, eventParams[1], eventParams[2], eventParams[5], eventParams[6], itemid); end, -- Excalibur
            [18281] = function (x) player:startEvent(71, eventParams[1], eventParams[2], eventParams[5], eventParams[6], itemid); end, -- Ragnarok
            [18287] = function (x) player:startEvent(72, eventParams[1], eventParams[2], eventParams[5], eventParams[6], itemid); end, -- Guttler
            [18293] = function (x) player:startEvent(73, eventParams[1], eventParams[2], eventParams[5], eventParams[6], itemid); end, -- Bravura
            [18299] = function (x) player:startEvent(75, eventParams[1], eventParams[2], eventParams[5], eventParams[6], itemid); end, -- Gungnir
            [18305] = function (x) player:startEvent(74, eventParams[1], eventParams[2], eventParams[5], eventParams[6], itemid); end, -- Apocalypse
            [18311] = function (x) player:startEvent(76, eventParams[1], eventParams[2], eventParams[5], eventParams[6], itemid); end, -- Kikoku
            [18317] = function (x) player:startEvent(77, eventParams[1], eventParams[2], eventParams[5], eventParams[6], itemid); end, -- Amanomurakumo
            [18323] = function (x) player:startEvent(78, eventParams[1], eventParams[2], eventParams[5], eventParams[6], itemid); end, -- Mjollnir
            [18329] = function (x) player:startEvent(79, eventParams[1], eventParams[2], eventParams[5], eventParams[6], itemid); end, -- Claustrum
            [18335] = function (x) player:startEvent(81, eventParams[1], eventParams[2], eventParams[5], eventParams[6], itemid); end, -- Annihilator
            [18341] = function (x) player:startEvent(82, eventParams[2], eventParams[1], eventParams[5], eventParams[6], itemid); end, -- Gjallarhorn
            [18347] = function (x) player:startEvent(80, eventParams[1], eventParams[2], eventParams[5], eventParams[6], itemid); end, -- Yoichinoyumi
            [15069] = function (x) player:startEvent(86, eventParams[2], eventParams[1], eventParams[5], eventParams[6], itemid); end, -- Aegis
         }
      end

   -- Should never happen, but should be here just in case.
   else
      player:startEvent(10);
   end
end;

-----------------------------------
-- onEventUpdate
-----------------------------------

function onEventUpdate(player,csid,option)
   -- printf("Update CSID: %u",csid);
   -- printf("Update RESULT: %u",option);

   -- Handles the displayed currency types and amounts for Aegis Stage 1->2, 2->3, and 3->4 based on option.
   if ((csid == 11 or csid == 12 or csid == 13) and option ~= 0) then
      if (option == 1) then
         player:updateEvent(15066, 1453, 1, 1456, 1, 1450, 1);
      elseif (option == 2) then
         player:updateEvent(15067, 1453, 4, 1456, 4, 1450, 4);
      elseif (option == 3) then
         player:updateEvent(15068, 1453, 20, 1456, 20, 1450, 20);
      end
   end
end;

-----------------------------------
-- onEventFinish
-----------------------------------

function onEventFinish(player,csid,option)
   -- printf("Finish CSID: %u",csid);
   -- printf("Finish RESULT: %u",option);

   local reward = player:getVar("RELIC_IN_PROGRESS");

   -- User is cancelling a relic.  Null everything out, it never happened.
   if (csid == 87 and option == 666) then
      player:setVar("RELIC_IN_PROGRESS",0);
      player:setVar("RELIC_DUE_AT",0);
      player:setVar("RELIC_MAKE_ANOTHER",0);
      player:setVar("RELIC_CONQUEST_WAIT",0);

   -- User is okay with making a relic they cannot possibly accept
   elseif (csid == 20 and option == 1) then
      player:setVar("RELIC_MAKE_ANOTHER",1);

   -- Picking up a finished relic.
   elseif ((csid == 16 or csid == 19 or csid == 52) and reward ~= 0) then
      if (player:getFreeSlotsCount() < 1) then
         player:messageSpecial(ITEM_CANNOT_BE_OBTAINED,reward+1);
      else
         player:addItem(reward+1);
         player:messageSpecial(ITEM_OBTAINED,reward+1);
         player:setVar("RELIC_IN_PROGRESS",0);
         player:setVar("RELIC_DUE_AT",0);
         player:setVar("RELIC_MAKE_ANOTHER",0);
         player:setVar("RELIC_CONQUEST_WAIT",getConquestTally());
      end

   -- Stage 4 cutscenes
   elseif ((csid >= 68 and csid <= 82) or csid == 86) then
      player:setVar("RELIC_CONQUEST_WAIT",0);
      switch (csid): caseof
      {
         [68] = function (x) player:setVar("RELIC_IN_PROGRESS",18263); end, -- Spharai
         [69] = function (x) player:setVar("RELIC_IN_PROGRESS",18269); end, -- Mandau
         [70] = function (x) player:setVar("RELIC_IN_PROGRESS",18275); end, -- Excalibur
         [71] = function (x) player:setVar("RELIC_IN_PROGRESS",18281); end, -- Ragnarok
         [72] = function (x) player:setVar("RELIC_IN_PROGRESS",18287); end, -- Guttler
         [73] = function (x) player:setVar("RELIC_IN_PROGRESS",18293); end, -- Bravura
         [75] = function (x) player:setVar("RELIC_IN_PROGRESS",18299); end, -- Gungnir
         [74] = function (x) player:setVar("RELIC_IN_PROGRESS",18305); end, -- Apocalypse
         [76] = function (x) player:setVar("RELIC_IN_PROGRESS",18311); end, -- Kikoku
         [77] = function (x) player:setVar("RELIC_IN_PROGRESS",18317); end, -- Amanomurakumo
         [78] = function (x) player:setVar("RELIC_IN_PROGRESS",18323); end, -- Mjollnir
         [79] = function (x) player:setVar("RELIC_IN_PROGRESS",18329); end, -- Claustrum
         [81] = function (x) player:setVar("RELIC_IN_PROGRESS",18335); end, -- Annihilator
         [82] = function (x) player:setVar("RELIC_IN_PROGRESS",18341); end, -- Gjallarhorn
         [80] = function (x) player:setVar("RELIC_IN_PROGRESS",18347); end, -- Yoichinoyumi
         [86] = function (x) player:setVar("RELIC_IN_PROGRESS",15069); end, -- Aegis
      }
   end
end;