From 46dc4568c5c0162b0674ee06bda79a5db9972f98 Mon Sep 17 00:00:00 2001 From: JasXSL Date: Fri, 4 May 2018 01:14:52 +0200 Subject: [PATCH] test quest --- ExiWoW-Ero.toc | 2 + lib_Actions.lua | 31 +++++ lib_Effects.lua | 41 ++++++ lib_Quests.lua | 348 ++++++++++++++++++++++++++++++++++++++++++++++ lib_RPText.lua | 30 ++++ lib_Underwear.lua | 20 +++ 6 files changed, 472 insertions(+) create mode 100644 lib_Quests.lua diff --git a/ExiWoW-Ero.toc b/ExiWoW-Ero.toc index b60ca9a..bf842ed 100644 --- a/ExiWoW-Ero.toc +++ b/ExiWoW-Ero.toc @@ -20,3 +20,5 @@ lib_Underwear.lua lib_Loot.lua # Spells lib_Spells.lua +#Quests +lib_Quests.lua \ No newline at end of file diff --git a/lib_Actions.lua b/lib_Actions.lua index 0d1fbbf..89f413d 100644 --- a/lib_Actions.lua +++ b/lib_Actions.lua @@ -10,6 +10,7 @@ aTable.actions = function(self) local Effect = require("Effect"); local Func = require("Func"); local toggleVibHubProgram = Func.get("toggleVibHubProgram"); + local Condition = require("Condition"); -- Fondle (Public) -- table.insert(out, Action:new({ @@ -133,6 +134,9 @@ aTable.actions = function(self) end })); + + + -- Pulsating mushroom consumable table.insert(out, Action:new({ id = "PULSATING_MUSHROOM", @@ -214,6 +218,33 @@ aTable.actions = function(self) end })); + -- Vine Squirm (Learned action) -- + table.insert(out, Action:new({ + id = "VINE_SQUIRM", + name = "Vine Squirm", + description = "Makes the target's Everliving Vine Thong squirm against their groin, provided they're wearing one.", + texture = "inv_misc_herb_nightmarevine", + cast_time = 2, + charges = 0, + rarity = 3, + cooldown = 3, + cast_sound_success = 47759, + cast_sound_loop = 27, + conditions = { + Condition:new({id="vineThongCheck", type=Condition.Types.RTYPE_UNDIES, data={["EVERLIVING_VINE_THONG"]=true}}), + Condition.get("melee_range"), + Condition.get("sender_not_moving"), + }, + not_defaults = {}, + fn_send = Action.sendRPText, + fn_receive = function(self, sender, target, args) + self:receiveRPText(sender, target, args) -- Default behavior + --TODO: Run effect + Effect.run("VINE_SQUIRM"); + return true + end + })); + return out; end diff --git a/lib_Effects.lua b/lib_Effects.lua index 604093e..35fb6cf 100644 --- a/lib_Effects.lua +++ b/lib_Effects.lua @@ -8,6 +8,7 @@ aTable.effects = function(self) local Action = require("Action"); local RPText = require("RPText"); local Func = require("Func"); + local Event = require("Event"); local out = {}; -- These are Effect effect definitions @@ -226,6 +227,46 @@ aTable.effects = function(self) end, })); + + + + table.insert(out, Effect:new({ + id = "VINE_SQUIRM", + detrimental = true, + duration = 15, + max_stacks = 1, + ticking = 2, + texture = "Interface/Icons/spell_nature_magicimmunity", + name = "Squirming Thong", + description = "Your vine thong is squirming!", + sound_loop = 25152, + onAdd = function(self, binding, fromReload) + Effect.remByTagsNotThis(self, "VINE_THONG"); + Func.get("toggleVibHubProgram")("VINE_THONG", math.huge); + local function onUnderwearChange() + if not ExiWoW.ME:getUnderwear() or ExiWoW.ME:getUnderwear().id ~= "EVERLIVING_VINE_THONG" then + Effect.remByID("VINE_SQUIRM"); + end + end + self.onUnderwearEquip = Event.on(Event.Types.ACTION_UNDERWEAR_EQUIP, onUnderwearChange); + self.onUnderwearRemove = Event.on(Event.Types.ACTION_UNDERWEAR_UNEQUIP, onUnderwearChange); + + end, + onTick = function() + local amount = 0.03; + ExiWoW.ME:addExcitement(amount); + end, + onRemove = function(self) + if self.onUnderwearEquip then Event.off(self.onUnderwearEquip); end + if self.onUnderwearRemove then Event.off(self.onUnderwearRemove); end + Func.get("toggleVibHubProgram")("VINE_THONG"); + end, + tags = {"VINE_THONG"} + })); + + + + -- MossyVine table.insert(out, Effect:new({ id = "MossyVine", diff --git a/lib_Quests.lua b/lib_Quests.lua new file mode 100644 index 0000000..1efd6e8 --- /dev/null +++ b/lib_Quests.lua @@ -0,0 +1,348 @@ +local aName, aTable = ...; +local require = ExiWoW.require + +aTable.quests = function(self) + + local Quest = require("Quest"); + local Objective = Quest.Objective; + local Event = require("Event"); + local Reward = Quest.Reward; + local Timer = require("Timer"); + local Character = require("Character"); + local RPText = require("RPText"); + local UI = require("UI"); + local Condition = require("Condition"); + local Talkbox = require("Talkbox"); + + local out = {} + + -- Undervine 0 + table.insert(out, Quest:new({ + id = "UNDERVINE_0", + name = "Vine Research", + start_text = { + "Ishnu alah, traveler. I need help with some research I'm doing.", + "Life out here tends to get lonely, and I have been working on a way to spice things up a little.", + "I have a spell to craft living vine underwear, but I'm severely lacking in living vines.", + "That's where you come in. Interested?" + }, + journal_entry = "Myria Glenbrook in Lightsong south east in Val'sharah is working on vine-based underwear but is lacking vines.\n\nI could go north to Moonrest and collect small vines from the Deathblossoms there.", + end_journal = "Return to Myria Glenbrook in Lightsong", + questgiver = 70971, + end_text = { + "These vines look a little dead, but it's a start.", + function() + PlaySound(23435, "SFX"); + return "[Myria fashions a makeshift thong from the vines]"; + end, + "There you are, the next step will be to purify them." + }, + rewards = { + Reward:new({ + id = "WITHERED_VINE_THONG", + type = "Underwear" + }) + }, + objectives = { + Objective:new({ + id = "vinesCollected", + name = "Creeping Deathblossom Vines", + num = 15, -- Num of name to do to complete it + onObjectiveEnable = function(self) + self:on(Event.Types.MONSTER_KILL, function(data) + if data.name == "Creeping Deathblossom" or data.name == "Mature Deathblossom" then + PlaySound(1187, "SFX"); + self:add(1); + end + end); + end, -- Raised when objective is activated + onObjectiveDisable = function(self) + end -- Raised when objective is completed or disabled + }), + }, -- You can wrap objectives in {} to create packages + start_events = { + { + event = Event.Types.POINT_REACHED, + data = {zone="Val'sharah", sub="Lightsong", x=60.18, y=84.83, dist=0.21}, + max = 1, + fn = function(self, data) + return true; + end + } + }, + end_events = true + })); + + + -- Undervine 1 + table.insert(out, Quest:new({ + id = "UNDERVINE_1", + name = "Pricks and Goo", + start_text = { + "We have the thong, but it's much too withered to animate.", + "I know of a few reagents that will liven things up a little. Would you be willing to help some more?", + "Lostlight Grotto just east of here has slimes that can lubricate the vines.", + "Lunarwing Shallows to the west is home to Thistleleaf Thorndancers who throw enchanted Quill Barbs at you.", + "For either of the reagents to work, they will have to make direct contact with the thong.", + "The vines SHOULD protect you, but it might still sting. I have no doubts that one such as yourself can handle it!" + }, + journal_entry = + "Myria Glenbrook in Lightsong south east in Val'sharah asked me to infuse the Withered Vine Thong with two reagents.\n\n".. + "For it to work I must first take off my pants and wear the Withered Vine Thong.".. + "The first reagent is ooze from the slimes in Lostlight Grotto, just east of Lightsong. Simply killing the slimes should be enough to make them splatter across the thong.\n\n".. + "The other reagent is quill barbs cast by the Thistleleaf Thorndancers further west and across the road. I should make sure I don't use any shields obstructing the quill barb's path.\n\n" + , + end_journal = "Return to Myria Glenbrook", + questgiver = 70971, + end_text = { + function() + local text = "Excellent! Just a moment."; + if not GetInventoryItemID("player", 7) then + text = text.." Feel free to put your leggings back on."; + end + return text; + end, + function() + PlaySound(3331, "SFX"); + return "[Myria purifies your thong]"; + end, + "A resounding success!" + }, + rewards = { + Reward:new({ + id = "EVERLIVING_VINE_THONG", + type = "Underwear" + }) + }, + onCompletion = function(self) + if ExiWoW.ME:getUnderwear() and ExiWoW.ME:getUnderwear().id == "WITHERED_VINE_THONG" then + ExiWoW.ME:useUnderwear("EVERLIVING_VINE_THONG"); + end + ExiWoW.ME:removeUnderwear("WITHERED_VINE_THONG"); + end, + objectives = { + { + Objective:new({ + id = "wearThong", + name = "Withered Vine Thong Worn", + num = 1, -- Num of name to do to complete it + onObjectiveEnable = function(self) + self.timer = Timer.set(function() + if ExiWoW.ME:getUnderwear() and ExiWoW.ME:getUnderwear().id == "WITHERED_VINE_THONG" then + self:add(1); + end + end, 1, math.huge); + end, -- Raised when objective is activated + onObjectiveDisable = function(self) + if self.timer then Timer.clear(self.timer); end + end -- Raised when objective is completed or disabled + }), + Objective:new({ + id = "removePants", + name = "Pants unequipped", + num = 1, -- Num of name to do to complete it + onObjectiveEnable = function(self) + self.timer = Timer.set(function() + if GetInventoryItemID("player", 7) == nil then + self:add(1); + end + end, 1, math.huge); + end, -- Raised when objective is activated + onObjectiveDisable = function(self) + if self.timer then Timer.clear(self.timer); end + end -- Raised when objective is completed or disabled + }), + }, + { + Objective:new({ + id = "slimeInfusions", + name = "Slime Infusions", + num = 8, -- Num of name to do to complete it + onObjectiveEnable = function(self) + self:on(Event.Types.MONSTER_KILL, function(data) + if + data.name == "Undulating Boneslime" and + GetInventoryItemID("player", 7) == nil and + ExiWoW.ME:getUnderwear() and + ExiWoW.ME:getUnderwear().id == "WITHERED_VINE_THONG" + then + RPText.trigger("BONESLIME_PROC", "none", "player", Character.buildNPC("none", "Undulating Boneslime"), ExiWoW.ME, nil, Event.Types.MONSTER_KILL); + PlaySound(73080, "SFX"); + self:add(1); + end + end); + end, -- Raised when objective is activated + onObjectiveDisable = function(self) + end -- Raised when objective is completed or disabled + }), + Objective:new({ + id = "quillBarbInfusions", + name = "Quill Barb Infusions", + num = 3, -- Num of name to do to complete it + onObjectiveEnable = function(self) + self:on(Event.Types.SPELL_TICK, function(data) + if + data.aura and data.aura.name == "Quill Barb" and + GetInventoryItemID("player", 7) == nil and + ExiWoW.ME:getUnderwear() and + ExiWoW.ME:getUnderwear().id == "WITHERED_VINE_THONG" + then + RPText.trigger("QUILLBARB_PROC", data.unit, "player", Character.buildNPC(data.unit, data.name), ExiWoW.ME, nil, Event.Types.SPELL_TICK); + PlaySound(75922, "SFX"); + self:add(1); + end + end); + end, -- Raised when objective is activated + onObjectiveDisable = function(self) + end -- Raised when objective is completed or disabled + }), + } + }, -- You can wrap objectives in {} to create packages + start_events = { + { + event = Event.Types.POINT_REACHED, + data = {zone="Val'sharah", sub="Lightsong", x=60.18, y=84.83, dist=0.21}, + fn = function(self, data) + if Quest.isCompleted("UNDERVINE_0") then + return true; + end + end + } + }, + end_events = true + })); + + -- Undervine 2 + table.insert(out, Quest:new({ + id = "UNDERVINE_2", + name = "Bear for Honey", + start_text = { + "While you were out I received a visit from a furbolg named Grizzleback.", + "A big, warm man bear with soft fur, wearing only a loincloth to conceal his large...", + "[Myria bites her lower lip]", + "Do you think you could visit Elandris Bladesong and see if he has any honey to present as a gift?", + "I'm sure if you help him defend his home, he'll let you have some. Then could you present it to Grizzleback and tell him it's from me?", + "If all goes well, I'll let you keep the vine thong, and I'll even teach you a spell to make it wiggle pleasantly!" + }, + journal_entry = + "Myria Glenbrook in Lightsong south east in Val'sharah asked me to visit Elandris Bladesong living above Grizzleweald north east of Lightsong.\n\n".. + "I am to collect honey from him and present it to Old Grizzleback in Grizzleweald, as a gift from Myria." + , + end_journal = "Return to Myria Glenbrook", + questgiver = 70971, + end_text = { + "He said he'll meet me? That's wonderful news! Now these woods won't be so lonely.", + "Keep the thong, you've earned it! And take this spell, I won't be needing it anymore!" + }, + rewards = { + Reward:new({ + id = "VINE_SQUIRM", + type = "Charges", + quant = math.huge + }) + }, + objectives = { + Objective:new({ + id = "visitElandris", + name = "Elandris Visited", + num = 1, + onObjectiveEnable = function(self) + -- Success + self:on(Event.Types.POINT_REACHED, function() + if GetQuestsCompleted()[43176] then + UI.talkbox.set(Talkbox:new({ + lines = { + "I am in your debt. I have a jar of honey, it's around here... somewhere.", + "Sorry I am afraid you will have to search my home for it." + }, + displayInfo = 70942, + title = "", + })); + self:add(1); + end + end, {zone="Val'sharah", sub="Bladesong's Retreat", x=67.43, y=69.42, dist=0.25}); + end, + onObjectiveDisable = function(self) + end + }), + Objective:new({ + id = "findHoney", + name = "Forage for Honey", + num = 1, + onObjectiveEnable = function(self) + -- Success + self:on(Event.Types.FORAGE, function() + if math.random() < 0.75 then return false end + if Condition.all({ + Condition:new({ + type = Condition.Types.RTYPE_LOC, + data = {x=67.43, y=69.42, rad=0.25} + }), + Condition:new({ + type = Condition.Types.RTYPE_ZONE, + data = "Val'sharah" + }), + Condition:new({ + type = Condition.Types.RTYPE_SUBZONE, + data = "Bladesong's Retreat" + }), + }, "player", "player", ExiWoW.ME, ExiWoW.ME) then + PlaySound(1217, "SFX"); + UI.talkbox.set(Talkbox:new({ + lines = { + "Ah you found it! Give Myria my regards!", + }, + displayInfo = 70942, + title = "", + })); + self:add(1); + end + end); + end, + onObjectiveDisable = function(self) + end + }), + Objective:new({ + id = "deliverHoney", + name = "Deliver Honey to Grizzleback", + num = 1, + onObjectiveEnable = function(self) + -- Todo: Bind + self:on(Event.Types.GOSSIP_SHOW, function() + if UnitName("target") == "Old Grizzleback" then + UI.talkbox.set(Talkbox:new({ + lines = { + "She said she wanted to see me again AND brought me this honey?", + "Of course! Do you think she could use some druidic rejuvenate magic on me? I may not be as limber anymore, but I bet I can still give her a good time.", + "Tell her that I will be over as soon as we are done with these grells." + }, + displayInfo = 62198, + title = "", + onComplete = function() + self:add(1); + end + })); + end + end); + end, + onObjectiveDisable = function(self) + end + }), + }, -- You can wrap objectives in {} to create packages + start_events = { + { + event = Event.Types.POINT_REACHED, + data = {zone="Val'sharah", sub="Lightsong", x=60.18, y=84.83, dist=0.21}, + fn = function(self, data) + if Quest.isCompleted("UNDERVINE_1") then + return true; + end + end + } + }, + end_events = true + })); + + -- This will cause the property to self delete, it's not needed. + return out +end diff --git a/lib_RPText.lua b/lib_RPText.lua index 1384c59..bfafbaa 100644 --- a/lib_RPText.lua +++ b/lib_RPText.lua @@ -101,6 +101,20 @@ aTable.rpTexts = function(self) })) + -- VINE_SQUIRM -- + table.insert(R, RPText:new({ + id = "VINE_SQUIRM", + sound = 2579, + text_bystander = "%S casts a spell aimed at %T's %Tcrotch!", + text_sender = "You cast cast a squirm spell at %T's %Tundies!", + text_receiver = "%S casts a spell at you, making your %Tundies start to squirm!", + })) + table.insert(R, RPText:new({ + id = "VINE_SQUIRM", + sound = 2579, + text_receiver = "You cast a spell on your %Tundies, making them start squirming!", + })) + -- Throw sand -- table.insert(R, RPText:new({ id = "THROW_SAND", @@ -1629,6 +1643,22 @@ aTable.rpTexts = function(self) })) +-- Quest triggers + -- UNDERVINE_1 + table.insert(R, RPText:new({ + id = "BONESLIME_PROC", + text_receiver = "Warm slime seeps into your %Tundies, lubricating the withered vines!", + fn = Func.get("addExcitement"), + requirements = {} + })); + + table.insert(R, RPText:new({ + id = "QUILLBARB_PROC", + text_receiver = "The Quill Barb smacks against your %Tgroin before being absorbed by the %Tundies!", + fn = Func.get("addExcitementMasochisticCrit"), + requirements = {} + })); + return R; diff --git a/lib_Underwear.lua b/lib_Underwear.lua index abe4cee..21a44d0 100644 --- a/lib_Underwear.lua +++ b/lib_Underwear.lua @@ -19,6 +19,26 @@ aTable.underwear = function(self) tags = {}, })); + table.insert(out, Underwear:new({ + id = "WITHERED_VINE_THONG", + name = "Withered Vine Thong", + icon = "spell_nature_naturetouchdecay", + description = "A thong of dying vines. Not very fashionable.", + --flavor = "It wiggles!", + rarity = 2, + tags = {}, + })); + + table.insert(out, Underwear:new({ + id = "EVERLIVING_VINE_THONG", + name = "Everliving Vine Thong", + icon = "spell_nature_magicimmunity", + description = "A thong woven of everliving green vines.", + flavor = "Favored by druids of Val'sharah!", + rarity = 4, + tags = {}, + })); + -- This will cause the property to self delete, it's not needed. return out