From 7b1f95cd7735a16217f5cf92a38ac434cb78e9ec Mon Sep 17 00:00:00 2001 From: Filip Maj Date: Sat, 16 Sep 2017 13:19:10 -0400 Subject: [PATCH] Fixed multiparams not being returned on CallClientFunction(). Was due to bad merge. Added Jorge's scripts. --- .../npc/populace/PopulaceBlackMarketeer.lua | 188 ++++++++++++++++-- .../npc/populace/PopulaceCompanyWarp.lua | 110 +++++++++- .../npc/populace/PopulaceLinkshellManager.lua | 5 + data/scripts/global.lua | 3 +- 4 files changed, 282 insertions(+), 24 deletions(-) diff --git a/data/scripts/base/chara/npc/populace/PopulaceBlackMarketeer.lua b/data/scripts/base/chara/npc/populace/PopulaceBlackMarketeer.lua index 2015e023..9a3a30db 100644 --- a/data/scripts/base/chara/npc/populace/PopulaceBlackMarketeer.lua +++ b/data/scripts/base/chara/npc/populace/PopulaceBlackMarketeer.lua @@ -4,34 +4,190 @@ PopulaceBlackMarketeer Script Functions: -eventTalkWelcome(player) - Start Text -eventSellItemAsk(player, ?, ?) -eventAskMainMenu(player, index) - Shows -eventTalkBye(player) - Says bye text -eventTalkStepBreak() - Ends talk +eventTalkWelcome(player) - Start Text +eventSellItemAsk(player, itemName, tradePrice) - Requires GC Affiliation. Trade menu for Commemorative Coin +eventAskMainMenu(player, index) - Shows menu prompt to purchase with gil or with GC seals +eventTalkBye(player) - Says bye text +eventTalkStepBreak() - Ends talk, NPC turns to face original position -eventSealShopMenuOpen() - -eventSealShopMenuAsk() - -eventSealShopMenuClose() - -eventGilShopMenuOpen() - -eventGilShopMenuAsk() - -eventGilShopMenuClose() - +eventSealShopMenuOpen() - Opens menu for purchasing with grand company seals +eventSealShopMenuAsk() - Returns two values, one that seems to always be true, and an index of purchased item +eventSealShopMenuClose() - Closes seal menu +eventGilShopMenuOpen() - Opens menu for purchasing with gil +eventGilShopMenuAsk() - Returns two values, one that seems to always be true, and an index of purchased item +eventGilShopMenuClose() - Closes gil menu + +Class applies to only three NPCs +Actorclass Id - 1500293 : Momoroon, Limsa Lominsa +Actorclass Id - 1500294 : Gagaroon, Gridania +Actorclass Id - 1500295 : Lalaroon, Ul'dah --]] require ("global") +shopInfo = { -- [ index ] = { itemId, gilPrice, sealPrice, city, itemCategory } +[1001] = {3020202, 100, 10000, 1, 1}, +[1002] = {3020509, 400, 40000, 1, 1}, +[1003] = {3020510, 400, 40000, 1, 1}, +[1004] = {3020504, 1000, 100000, 1, 1}, +[1005] = {3020505, 1000, 100000, 1, 1}, +[1101] = {9040018, 1500, 150000, 1, 2}, +[1102] = {9010025, 2000, 200000, 1, 2}, +[1301] = {2001014, 4000, 400000, 1, 4}, +[2001] = {3020203, 100, 10000, 2, 1}, +[2002] = {3020509, 400, 40000, 2, 1}, +[2003] = {3020510, 400, 40000, 2, 1}, +[2004] = {3020504, 1000, 100000, 2, 1}, +[2005] = {3020505, 1000, 100000, 2, 1}, +[2101] = {9040018, 1500, 150000, 2, 2}, +[2102] = {9010025, 2000, 200000, 2, 2}, +[2301] = {2001015, 4000, 400000, 2, 4}, +[3001] = {3020204, 100, 10000, 3, 1}, +[3002] = {3020509, 400, 40000, 3, 1}, +[3003] = {3020510, 400, 40000, 3, 1}, +[3004] = {3020504, 1000, 100000, 3, 1}, +[3005] = {3020505, 1000, 100000, 3, 1}, +[3101] = {9040018, 1500, 150000, 3, 2}, +[3102] = {9010025, 2000, 200000, 3, 2}, +[3301] = {2001016, 4000, 400000, 3, 4}, +} + function init(npc) return false, false, 0, 0; end function onEventStarted(player, npc, triggerName) - + + commemorativeCoin = 10011251; + commemorativeCoinValue = 25000; + gilCurrency = 1000001; + playerGC = player.gcCurrent + playerGCSeal = 1000200 + playerGC; + callClientFunction(player, "eventTalkWelcome", player); - currancyType = callClientFunction(player, "eventAskMainMenu", player); - callClientFunction(player, "eventSealShopMenuAsk", player); - - + if player:GetInventory(INVENTORY_NORMAL):HasItem(commemorativeCoin) and playerGC > 0 then + -- Checks for player having a commemorative coin, show window trade option if so. + coinChoice = callClientFunction(player, "eventSellItemAsk", player, commemorativeCoin, commemorativeCoinValue); + if coinChoice == 1 then + currencyType = callClientFunction(player, "eventAskMainMenu", player); + elseif coinChoice == 2 then + -- You trade for . + player:SendGameMessage(player, GetWorldMaster(), 25071, MESSAGE_TYPE_SYSTEM, commemorativeCoin, 1, playerGCSeal, 1, 1, commemorativeCoinValue); + player:GetInventory(INVENTORY_NORMAL):RemoveItem(commemorativeCoin, 1); + player:getInventory(INVENTORY_CURRENCY):addItem(playerGCSeal, 25000, 1) + -- TODO: Add handling for checking GC seals limit and not going over it + end + else + -- If no grand company alignment, go straight to the shop that uses gil, otherwise show gc seal option. + if playerGC == 0 then + processGilShop(player); + else + currencyType = callClientFunction(player, "eventAskMainMenu", player); + if currencyType == 1 then + processGilShop(player); + elseif currencyType == 2 then + processSealShop(player); + end + end + end + + callClientFunction(player, "eventTalkBye", player); + callClientFunction(player, "eventTalkStepBreak", player); player:EndEvent(); +end + + +function processGilShop(player) + + callClientFunction(player, "eventGilShopMenuOpen", player); + + while (true) do + unk1, buyResult = callClientFunction(player, "eventGilShopMenuAsk", player); + printf(unk1); + if (buyResult == 0 or buyResult == -1) then + callClientFunction(player, "eventGilShopMenuClose", player); + break; + else + if shopInfo[buyResult] == nil then + -- Prevent server crash from someone trying to buy a non-existent item via packet injection. + break; + else + -- TODO: Add handling to check you're on the right NPC to prevent packet injecting a purchase from anything in the list + if shopInfo[buyResult][5] == 4 then + location = INVENTORY_KEYITEMS; + else + location = INVENTORY_NORMAL; + end + + purchaseItem(player, shopInfo[buyResult][1], 1, 1, shopInfo[buyResult][3], gilCurrency, location); + end + end + end +end + + +function processSealShop(player) + + callClientFunction(player, "eventSealShopMenuOpen", player); + + while (true) do + unk1, buyResult = callClientFunction(player, "eventSealShopMenuAsk", player); + + if (buyResult == 0 or buyResult == -1) then + callClientFunction(player, "eventSealShopMenuClose", player); + break; + else + if shopInfo[buyResult] == nil then + -- Prevent server crash from someone trying to buy a non-existent item via packet injection. + break; + else + -- TODO: Add handling to check you're on the right NPC to prevent packet injecting a purchase from anything in the list + if shopInfo[buyResult][5] == 4 then + location = INVENTORY_KEYITEMS; + else + location = INVENTORY_NORMAL; + end + + purchaseItem(player, shopInfo[buyResult][1], 1, 1, shopInfo[buyResult][2], playerGCSeal, location); + end + end + end +end + +function purchaseItem(player, itemId, quantity, quality, price, currency, location) + + local worldMaster = GetWorldMaster(); + local cost = quantity * price; + local gItemData = GetItemGamedata(itemId); + local isUnique = gItemData.isRare; + + if player:GetInventory(location):HasItem(itemId) and isUnique then + -- You cannot have more than one in your possession at any given time. + player:SendGameMessage(player, worldMaster, 40279, MESSAGE_TYPE_SYSTEM, itemId, quality); + return; + end + + if (not player:GetInventory(location):IsFull() or player:GetInventory(location):IsSpaceForAdd(itemId, quantity)) then + if player:GetInventory(INVENTORY_CURRENCY):HasItem(currency, cost) then + player:GetInventory(INVENTORY_CURRENCY):removeItem(currency, cost) + player:GetInventory(location):AddItem(itemId, quantity, quality); + if currency == 1000001 then + -- You purchase for gil. + player:SendGameMessage(player, worldMaster, 25061, MESSAGE_TYPE_SYSTEM, itemId, quality, quantity, cost); + elseif currency == 1000201 or currency == 1000202 or currency == 1000203 then + -- You exchange for . + player:SendGameMessage(player, GetWorldMaster(), 25275, MESSAGE_TYPE_SYSTEM, itemId, quality, quantity, price, player.gcCurrent); + + end + else + -- You do not have enough gil. (Should never see this aside from packet injection, since client prevents buying if not enough currency) + player:SendGameMessage(player, worldMaster, 25065, MESSAGE_TYPE_SYSTEM); + end + else + -- Your inventory is full. + player:SendGameMessage(player, worldMaster, 60022, MESSAGE_TYPE_SYSTEM); + end + return end \ No newline at end of file diff --git a/data/scripts/base/chara/npc/populace/PopulaceCompanyWarp.lua b/data/scripts/base/chara/npc/populace/PopulaceCompanyWarp.lua index 0b37b92f..9a5481b9 100644 --- a/data/scripts/base/chara/npc/populace/PopulaceCompanyWarp.lua +++ b/data/scripts/base/chara/npc/populace/PopulaceCompanyWarp.lua @@ -5,20 +5,118 @@ PopulaceCompanyWarp Script Functions: eventTalkWelcome(player) - Start Text -eventAskMainMenu(player, index) - Shows teleport menu +eventAskMainMenu(player, index) - Shows teleport menu, hides the teleport location at index value to prevent warping to the spot you're at eventAfterWarpOtherZone(player) - Fades out for warp eventTalkStepBreak() - Ends talk --]] require ("global") +warpNpc = +{ --[actorId] = {warpIndex, cityId} -- ()s around name indicate missing NPC + Aethernet + [1500321] = {1, 1}, -- (Storm Private Gardner) + [1500331] = {2, 1}, -- (Storm Private Rich) + [1500323] = {3, 1}, -- (Storm Private Potter) + [1500330] = {4, 1}, -- (Storm Private Hunt) + [1500322] = {5, 1}, -- (Storm Private Abel) + [1500332] = {6, 1}, -- (Storm Private Stone) + [1500339] = {7, 1}, -- (Storm Private Holt) + [1500324] = {1, 2}, -- serpent_private_white + [1500334] = {2, 2}, -- serpent_private_hill + [1500326] = {3, 2}, -- serpent_private_carver + [1500333] = {4, 2}, -- serpent_private_stone + [1500325] = {5, 2}, -- serpent_private_holmes + [1500335] = {6, 2}, -- serpent_private_kirk + [1500327] = {1, 3}, -- flame_private_newton + [1500337] = {2, 3}, -- (Flame Private Tanner) + [1500329] = {3, 3}, -- (Flame Private Morning) + [1500336] = {4, 3}, -- (Flame Private Covey) + [1500328] = {5, 3}, -- flame_private_allen + [1500338] = {6, 3}, -- (Flame Private Yar) +} + +aethernet = +{ + { -- 1: Limsa + {zone = 230, x = -424.140, y = 42.000, z = 371.988, r = -2.472}, -- 1 - Aetheryte Plaza + {zone = 133, x = -439.744, y = 40.000, z = 234.376, r = 0.287}, -- 2 - Drowning Wench + {zone = 230, x = -498.131, y = 43.622, z = 60.818, r = 0.254}, -- 3 - The Bismarck + {zone = 230, x = -759.331, y = 12.000, z = 239.413, r = -0.869}, -- 4 - Ferry Docks + {zone = 230, x = -623.582, y = 4.000, z = 369.318, r = 1.736}, -- 5 - Fisherman's Bottom + {zone = 230, x = -525.536, y = 18.000, z = 173.735, r = 3.082}, -- 6 - The Octant + {zone = 133, x = -231.711, y = 12.000, z = 193.573, r = -0.786}, -- 7 - Procession of Terns + {zone = 128, x = -20.783, y = 42.214, z = 146.946, r = 2.046}, -- 8 - Zephyr Gate + }, + { -- 2: Gridania + {zone = 206, x = -107.878, y = 17.524, z = -1343.871, r = 0.657}, -- 1 - Aetheryte Plaza + {zone = 155, x = 96.868, y = 3.480, z = -1211.040, r = 2.582}, -- 2 - Carline Canopy + {zone = 206, x = 86.942, y = 19.789, z = -1420.891, r = 2.965}, -- 3 - Atelier Fen-Yil + {zone = 206, x = -84.621, y = 19.061, z = -1502.665, r = 0.756}, -- 4 - Whistling Miller + {zone = 206, x = 205.101, y = 9.526, z = -1245.405, r = -1.749}, -- 5 - Quiver's Hold + {zone = 206, x = 160.578, y = 25.061, z = -1556.662, r = 1.896}, -- 6 - Wailing Barracks + {zone = 150, x = 318.838, y = 4.036, z = -992.071, r = -0.307}, -- 7 - Mistalle Bridges + {zone = 206, x = -192.167, y = 4.466, z = -1061.777, r = -0.026}, -- 8 - Berlends Bridges + }, + { -- 3: Ul'dah + {zone = 175, x = -190.574, y = 190.000, z = 18.086, r = 2.190}, -- 1 - Aetheryte Plaza + {zone = 175, x = -36.513, y = 192.000, z = 37.130, r = -0.490}, -- 2 - Quicksand + {zone = 209, x = -192.971, y = 230.000, z = 209.348, r = 2.860}, -- 3 - Frondale's Phrontistery + {zone = 209, x = -60.243, y = 200.000, z = 257.718, r = -1.276}, -- 4 - Onyx Lane + {zone = 209, x = -147.633, y = 198.000, z = 160.064, r = -1.600}, -- 5 - Gold Court + {zone = 209, x = -263.776, y = 202.000, z = 206.699, r = -3.135}, -- 6 - Arrzaneth Ossuary + {zone = 170, x = -29.721, y = 182.635, z = -76.313, r = 2.625}, -- 7 - Gate of Nald + {zone = 170, x = 129.957, y = 183.862, z = 220.719, r = 1.515}, -- 8 - Gate of Thal + } +} + + + function init(npc) return false, false, 0, 0; end function onEventStarted(player, npc, triggerName) - - callClientFunction(player, "eventAskMainMenu", player, 1); - - player:EndEvent(); -end \ No newline at end of file + local passLimsa = 2001014; + local passGrid = 2001015; + local passUldah = 2001016; + passCheck = 1; -- 0 = Check player for Aetherpass keyitem. 1 = Ignore it. + + npcId = npc:GetActorClassId(); + city = warpNpc[npcId][2]; + + + if city == 1 then + if player:GetInventory(INVENTORY_KEYITEMS):HasItem(passLimsa) then + passCheck = 1; + else + if passCheck == 0 then callClientFunction(player, "eventTalkWelcome", player); end + end; + elseif city == 2 then + if player:GetInventory(INVENTORY_KEYITEMS):HasItem(passGrid) then + passCheck = 1; + else + if passCheck == 0 then callClientFunction(player, "eventTalkWelcome", player); end + end; + elseif city == 3 then + if player:GetInventory(INVENTORY_KEYITEMS):HasItem(passUldah) then + passCheck = 1; + else + if passCheck == 0 then callClientFunction(player, "eventTalkWelcome", player); end + end + end + + if passCheck == 1 then + choice = callClientFunction(player, "eventAskMainMenu", player, warpNpc[npcId][1]); + + if choice == 0 then + --callClientFunction(player, "playereventTalkStepBreak"); + player:EndEvent(); + else + -- callClientFunction(player, "eventAfterWarpOtherZone", player); -- Commented out for now to prevent double fade-to-black for warp + player:EndEvent(); + GetWorldManager():DoZoneChange(player, aethernet[city][choice].zone, nil, 0, 15, aethernet[city][choice].x, aethernet[city][choice].y, aethernet[city][choice].z, aethernet[city][choice].r); + end + end + + player:EndEvent(); +end diff --git a/data/scripts/base/chara/npc/populace/PopulaceLinkshellManager.lua b/data/scripts/base/chara/npc/populace/PopulaceLinkshellManager.lua index f0702f9c..094772c7 100644 --- a/data/scripts/base/chara/npc/populace/PopulaceLinkshellManager.lua +++ b/data/scripts/base/chara/npc/populace/PopulaceLinkshellManager.lua @@ -39,6 +39,11 @@ function onEventStarted(player, npc, triggerName) --Create if (result == 3) then + + player:SendMessage(0x20, "", "" .. tostring(lsName)); + player:SendMessage(0x20, "", "" .. tostring(crestId)); + player:SendMessage(0x20, "", "" .. tostring(command)); + createLinkshell(lsName, crestId); callClientFunction(player, "eventTalkStepMakeupDone"); --Modify diff --git a/data/scripts/global.lua b/data/scripts/global.lua index 1d2e68da..af933ad2 100644 --- a/data/scripts/global.lua +++ b/data/scripts/global.lua @@ -78,8 +78,7 @@ end function callClientFunction(player, functionName, ...) player:RunEventFunction(functionName, ...); - result = coroutine.yield("_WAIT_EVENT", player); - return result; + return coroutine.yield("_WAIT_EVENT", player); end function wait(seconds)