diff --git a/game/modules/tome/data/chats/alchemist-derth.lua b/game/modules/tome/data/chats/alchemist-derth.lua new file mode 100644 index 0000000000000000000000000000000000000000..4c4211263bded238256e46f987b03d6d952cd6c6 --- /dev/null +++ b/game/modules/tome/data/chats/alchemist-derth.lua @@ -0,0 +1,521 @@ +-- ToME - Tales of Maj'Eyal +-- Copyright (C) 2009, 2010 Nicolas Casalini +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +-- Nicolas Casalini "DarkGod" +-- darkgod@te4.org + +local art_list = mod.class.Object:loadList("/data/general/objects/brotherhood-artifacts.lua") +local ing_list = mod.class.Object:loadList("/data/general/objects/elixir-ingredients.lua") +local alchemist_num = 1 +local other_alchemist_nums = {2, 3, 4} +local q = game.player:hasQuest("brotherhood-of-alchemists") +local final_reward = "LIFEBINDING_EMERALD" +local e = { + { + short_name = "fox", + name = "elixir of the fox", + id = "ELIXIR_FOX", + start = "fox_start", + almost = "fox_almost_done", + full = "elixir_of_the_fox", + full_2 = "elixir_of_avoidance", + full_3 = "elixir_of_precision", + poached = "fox_poached", + }, + { + short_name = "avoidance", + name = "elixir of avoidance", + id = "ELIXIR_AVOIDANCE", + start = "avoidance_start", + almost = "avoidance_almost_done", + full = "elixir_of_avoidance", + full_2 = "elixir_of_the_fox", + full_3 = "elixir_of_precision", + poached = "avoidance_poached", + }, + { + short_name = "precision", + name = "elixir of precision", + id = "ELIXIR_PRECISION", + start = "precision_start", + almost = "precision_almost_done", + full = "elixir_of_precision", + full_2 = "elixir_of_the_fox", + full_3 = "elixir_of_avoidance", + poached = "precision_poached", + }, +} + +--cond function for turning in non-final elixirs +--checks that player has quest and elixir ingredients, hasn't completed it yet, has started that elixir, and hasn't completed both other elixirs since that would make this the last one: +local function turn_in(npc, player, n) -- n is the index of the elixir we're checking on + return q and q:check_ingredients(player, e[n].short_name, n) -- make sure we have the quest and the elixir's ingredients + and not q:isCompleted(e[n].almost) and not q:isCompleted(e[n].full) --make sure we haven't finished the quest already + and q:isCompleted(e[n].start) --make sure we've been given the task to make this elixir + and not (q:isCompleted(e[n].full_2) and q:isCompleted(e[n].full_3)) --make sure we haven't already finished both the other elixirs, since that would make this the final one which requires a special dialog. +end + +--cond function for turning in final elixir with index n +--checks that player has quest and elixir ingredients, hasn't completed it yet, has started that elixir, and both the other elixirs are done +local function turn_in_final(npc, player, n) -- n is the index of the elixir we're checking on + return q and q:check_ingredients(player, e[n].short_name, n) -- make sure we have the quest and the elixir's ingredients + and not q:isCompleted(e[n].almost) and not q:isCompleted(e[n].full) --make sure we haven't finished the quest already + and q:isCompleted(e[n].start) --make sure we've been given the task to make this elixir + and (q:isCompleted(e[n].full_2) and q:isCompleted(e[n].full_3)) --make sure the other two elixirs are made, thus making this the final turn-in +end + +--cond function for turning in poached (completed by somebody besides you) elixirs +--checks that the player has the quest and elixir ingredients, hasn't turned it in, the task is complete anyway, the task has actually been started, and that it's been poached +local function turn_in_poached(npc, player, n) -- n is the index of the elixir we're checking on + return q and q:check_ingredients(player, e[n].short_name, n) -- make sure we have the quest and the elixir's ingredients + and not q:isCompleted(e[n].almost) --make sure we haven't turned it in already + and q:isCompleted(e[n].full) --make sure that, even though we haven't turned it in, the elixir has been made for this alchemist + and q:isCompleted(e[n].start) --make sure we've been given the task to make this elixir + and q:isCompleted(e[n].poached) --make sure this task has been poached +end + +local function more_aid(npc, player) + return not (q:isCompleted(e[1].full) and q:isCompleted(e[2].full) and q:isCompleted(e[3].full)) --make sure all the elixirs aren't already made + --Next, for each of the three elixirs, make sure it's not the case that: + --1) we're either working on it or... 2) we've started (but not finished) the elixir and it got poached. + and not ((q:isCompleted(e[1].start) and not q:isCompleted(e[1].full)) or (q:isCompleted(e[1].start) and q:isCompleted(e[1].poached) and q:isCompleted(e[1].almost)) ) + and not ((q:isCompleted(e[2].start) and not q:isCompleted(e[2].full)) or (q:isCompleted(e[2].start) and q:isCompleted(e[2].poached) and q:isCompleted(e[2].almost)) ) + and not ((q:isCompleted(e[3].start) and not q:isCompleted(e[3].full)) or (q:isCompleted(e[3].start) and q:isCompleted(e[3].poached) and q:isCompleted(e[3].almost)) ) +end + +local function give_bits(npc, player, n) -- n is the index of the elixir we're checking on + return q and q:check_ingredients(player, e[n].short_name) -- make sure we have the quest and the elixir's ingredients + and q:isCompleted(e[n].start) --make sure we've started the task + and not q:isCompleted(e[n].full) --... but not finished +end + +local function empty_handed(npc, player, n) -- n is the index of the elixir we're checking on + return q and q:check_ingredients(player, e[n].short_name, n) -- make sure we have the quest and the elixir's ingredients + and q:isCompleted(e[n].start) --make sure we've started the task + and not q:isCompleted(e[n].almost) --make sure we've not turned the stuff in before... + and q:isCompleted(e[n].full) --... and yet the elixir is already made (poached!) +end + +--Make the alchemist's reaction to your turn-in vary depending on whether he lost. +local function alchemist_reaction_complete(npc, player, lose, other_alch, other_elixir) + if lose == true then + return ([[Pfaugh. You're too late. %s has already finished. But I suppose it doesn't do any harm to take these and give you your undeserved reward.]]):format(other_alch) + else + return ([[Ah, excellent. Hand them over, if you please. You should know that in your overlong absence, %s has managed to create a %s. I'll be most put out if he steals my rightful spot.]]):format(other_alch, other_elixir) + end +end + +if not q or (q and not q:isCompleted(e[1].start) and not q:isCompleted(e[2].start) and not q:isCompleted(e[3].start)) then + +-- Here's the dialog that pops up if the player has never worked for this alchemist before: +newChat{ id="welcome", + text = [[#LIGHT_GREEN#*A human robed in immaculate white satin opens the door and eyes you appraisingly.*#WHITE# +Ah, an adventurer. I was just thinking that I needed a new one.]], + answers = { + {"That sounds promising. And ominous.", jump="ominous"}, + {"[leave]"}, + } +} + +newChat{ id="ominous", + text = [[Indeed, it is both promising and ominous. I can reward you handsomely for your efforts, but they will lead you into deadly peril to which, I assume, the previous three fellows who went off on my errand never to return can attest.]], + answers = { + {"What do you propose?", jump="proposal"}, + } +} + +newChat{ id="proposal", + text = [[Good adventurer, I am an alchemist, and quite a good one. This year, for the first time, the great Brotherhood of Alchemists has invited my application to their number. I'll not try your patience with the details of the application process, but suffice to say that it is grueling. Fortunately, a mere three tasks now stand between me and acceptance.]], + answers = { + {"How can I help?", jump="help"}, + } +} + +newChat{ id="help", + text = [[I require ingredients for three potent mixtures. Obviously, since I seek your aid, none of them is to be found by simply strolling to the local herbalist's. No, they will need to be forcibly parted from their owners who will, just as obviously, put up a fight. I've yet to encounter a naga who would be persuaded to hand over his tongue! Ha! Oh, I am droll at times.]], + answers = { + {"I specialize in separating vital body parts from monsters. What do you offer in return?", jump="competition"}, + } +} + +newChat{ id="competition", + text = [[Why, I will let you share in the fruits of my labors! Each of the three mixtures I shall produce in a quantity sufficient to create three doses: one for me, one for the Brotherhood and their confounded trial... and one for you. I must tell you that time is of the essence. I am not the only one who the Brotherhood invited this year, yet they will accept only one applicant-- the first to complete their trials. I know of at least three others laboring furiously to take my rightful place. Should your aid see me through, then I will reward you beyond even the remarkable elixirs. I've an ancient Lifebinding Emerald that grants great powers of health and healing when used properly. What say you?]], + answers = { + {"I accept.", jump="choice", action = function(npc, player) player:grantQuest("brotherhood-of-alchemists") end,}, + {"I cannot aid you at this time."}, + } +} + +newChat{ id="choice", + text = [[Excellent. Now then, I've three elixirs I'm working on. I'll burden you with only one at a time, since I've learned the hard way about the hazards of overloading an adventurer's brain. Here are your options: the elixir of the fox, which makes you as nimble and cunning as a fox; the elixir of avoidance, which sharpens your natural inclinations to get out of the way of incoming harm; or the elixir of precision, which grants intuitive understanding of an enemy's most sensitive spots. Which would you like to aid me with?]], + answers = { + {"The "..e[1].name..".", jump="list", + cond = function(npc, player) return not game.player:hasQuest("brotherhood-of-alchemists"):isCompleted(e[1].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[1].start) + game.player:hasQuest("brotherhood-of-alchemists"):update_needed_ingredients(player) + end, + on_select=function(npc, player) + local o = art_list[e[1].id] + o:identify(true) + game.tooltip_x, game.tooltip_y = 1, 1 + game.tooltip:displayAtMap(nil, nil, game.w, game.h, "#GOLD#"..o.name.."#LAST#\n"..tostring(o:getDesc())) + end, + }, + {"The "..e[2].name..".", jump="list", + cond = function(npc, player) return not game.player:hasQuest("brotherhood-of-alchemists"):isCompleted(e[2].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[2].start) + game.player:hasQuest("brotherhood-of-alchemists"):update_needed_ingredients(player) + end, + on_select=function(npc, player) + local o = art_list[e[2].id] + o:identify(true) + game.tooltip_x, game.tooltip_y = 1, 1 + game.tooltip:displayAtMap(nil, nil, game.w, game.h, "#GOLD#"..o.name.."#LAST#\n"..tostring(o:getDesc())) + end, + }, + {"The "..e[3].name..".", jump="list", + cond = function(npc, player) return not game.player:hasQuest("brotherhood-of-alchemists"):isCompleted(e[3].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[3].start) + game.player:hasQuest("brotherhood-of-alchemists"):update_needed_ingredients(player) + end, + on_select=function(npc, player) + local o = art_list[e[3].id] + o:identify(true) + game.tooltip_x, game.tooltip_y = 1, 1 + game.tooltip:displayAtMap(nil, nil, game.w, game.h, "#GOLD#"..o.name.."#LAST#\n"..tostring(o:getDesc())) + end, + }, + {"[leave]"}, + } +} + +newChat{ id="list", + text = [[Here's a list of the ingredients I'm missing. Please attempt to not lose your life in their pursuit. I'll be most put out if I must wait another year.]], + answers = { + {"I'll be off."}, + } +} + +-- Quest is complete; nobody answers the door +elseif q and q:isStatus(q.DONE) then +newChat{ id="welcome", + text = [[#LIGHT_GREEN#*The door is locked and nobody responds to your knocks*#WHITE#]], + answers = { + {"[Leave]"}, + } +} + + +else -- Here's the dialog that pops up if the player *has* worked with this alchemist before (either done quests or is in the middle of one): + +local other_alch, other_elixir, player_loses, alch_picked, e_picked = q:competition(player, other_alchemist_nums) + +newChat{ id="welcome", + text = [[#LIGHT_GREEN#*The alchemist opens his door.*#WHITE# +Ah, you again.]], + answers = { + -- If not the final elixir: + {"I've returned with the ingredients for the "..e[1].name..".", jump="complete", + cond = function(npc, player) return turn_in(npc, player, 1) end, + action = function(npc, player) + q:on_turnin(player, alch_picked, e_picked, false) + end, + }, + {"I've returned with the ingredients for the "..e[2].name..".", jump="complete", + cond = function(npc, player) return turn_in(npc, player, 2) end, + action = function(npc, player) + q:on_turnin(player, alch_picked, e_picked, false) + end, + }, + {"I've returned with the ingredients for the "..e[3].name..".", jump="complete", + cond = function(npc, player) return turn_in(npc, player, 3) end, + action = function(npc, player) + q:on_turnin(player, alch_picked, e_picked, false) + end, + }, + + -- If the final elixir: + {"I've returned with the ingredients for the "..e[1].name..".", jump="totally-complete", + cond = function(npc, player) return turn_in_final(npc, player, 1) end, + }, + {"I've returned with the ingredients for the "..e[2].name..".", jump="totally-complete", + cond = function(npc, player) return turn_in_final(npc, player, 2) end, + }, + {"I've returned with the ingredients for the "..e[3].name..".", jump="totally-complete", + cond = function(npc, player) return turn_in_final(npc, player, 3) end, + }, + + -- If the elixir got made while you were out: + {"I've returned with the ingredients for the "..e[1].name..".", jump="poached", + cond = function(npc, player) return turn_in_poached(npc, player, 1) end, + }, + {"I've returned with the ingredients for the "..e[2].name..".", jump="poached", + cond = function(npc, player) return turn_in_poached(npc, player, 2) end, + }, + {"I've returned with the ingredients for the "..e[3].name..".", jump="poached", + cond = function(npc, player) return turn_in_poached(npc, player, 3) end, + }, + + --Don't let player work on multiple elixirs for the same alchemist. + --See comments in more_aid function above for all the gory detail + {"I've come to offer more aid.", jump="choice", + cond = function(npc, player) return more_aid(npc, player) end, + }, + {"[leave]"}, + } +} + +--Not final elixir: +newChat{ id="complete", + text = alchemist_reaction_complete(npc, player, player_loses, other_alch, other_elixir), + answers = { + {"[Give him the monster bits.]", jump="complete2", + cond = function(npc, player) return give_bits(npc, player, 1) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[1].almost) + q:remove_ingredients(player, e[1].short_name, 1) + end + }, + {"[Give him the monster bits.]", jump="complete2", + cond = function(npc, player) return give_bits(npc, player, 2) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[2].almost) + q:remove_ingredients(player, e[2].short_name, 2) + end + }, + {"[Give him the monster bits.]", jump="complete2", + cond = function(npc, player) return give_bits(npc, player, 3) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[3].almost) + q:remove_ingredients(player, e[3].short_name, 3) + end + }, +-- {"Sorry, it seems I lack some stuff. I will be back."}, + } +} + +--Final elixir: +newChat{ id="totally-complete", + text = [[#LIGHT_GREEN#*The alchemist grins and motions impatiently for the ingredients.*#WHITE# +Wonderful, absolutely wonderful! The final step! Here, let me have those!]], + answers = { + {"[Give him the monster bits]", jump="totally-complete2", + cond = function(npc, player) return give_bits(npc, player, 1) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[1].almost) + q:remove_ingredients(player, e[1].short_name, 1) + end + }, + {"[Give him the monster bits]", jump="totally-complete2", + cond = function(npc, player) return give_bits(npc, player, 2) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[2].almost) + q:remove_ingredients(player, e[2].short_name, 2) + end + }, + {"[Give him the monster bits]", jump="totally-complete2", + cond = function(npc, player) return give_bits(npc, player, 3) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[3].almost) + q:remove_ingredients(player, e[3].short_name, 3) + end + }, + --{"Sorry, it seems I lack some stuff. I will be back."}, + } +} + +--Not final elixir: +newChat{ id="complete2", + text = [[Wait here while I perform my art. I'll have your reward within the hour.]], + answers = { + {"[Wait]", jump="complete3"}, + + } +} + +--Final Elixir: +newChat{ id="totally-complete2", + text = [[A final wait for you, my good adventurer, and then I shall return with both your rewards! Haha, complete at last!]], + answers = { + {"[Wait]", jump="totally-complete3"}, + + } +} + +--Not final elixir: +newChat{ id="complete3", + text = [[#LIGHT_GREEN#*The alchemist finally returns and hands you a small vial of fine glass.*#WHITE# +Enjoy your reward.]], + answers = { + {"Thank you. I'll be off.", + cond = function(npc, player) return q and q:isCompleted(e[1].almost) and not q:isCompleted(e[1].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[1].full) + q:reward(player, e[1].id) + q:update_needed_ingredients(player) + end + }, + {"Thank you. I'll be off.", + cond = function(npc, player) return q and q:isCompleted(e[2].almost) and not q:isCompleted(e[2].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[2].full) + q:reward(player, e[2].id) + q:update_needed_ingredients(player) + end + }, + {"Thank you. I'll be off.", + cond = function(npc, player) return q and q:isCompleted(e[3].almost) and not q:isCompleted(e[3].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[3].full) + q:reward(player, e[3].id) + q:update_needed_ingredients(player) + end + }, + } +} + +--Final elixir: +newChat{ id="totally-complete3", + text = [[#LIGHT_GREEN#*The alchemist finally returns with a vial and a green gem.*#WHITE# +Enjoy the fruits of your labors, adventurer. I know I will. To show my appreciation, I shall name my firstborn after... er, what was your name, then? Haha, I jest. Oh, I do go on when I'm giddy. Fare you well.]], + answers = { + {"Thank you. I'll be off.", + cond = function(npc, player) return q and q:isCompleted(e[1].almost) and not q:isCompleted(e[1].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[1].full) + q:reward(player, e[1].id) + q:reward(player, final_reward) + q:update_needed_ingredients(player) + q:winner_is(player, alchemist_num) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.DONE) + + end + }, + {"Thank you. I'll be off.", + cond = function(npc, player) return q and q:isCompleted(e[2].almost) and not q:isCompleted(e[2].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[2].full) + q:reward(player, e[2].id) + q:reward(player, final_reward) + q:update_needed_ingredients(player) + q:winner_is(player, alchemist_num) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.DONE) + end + }, + {"Thank you. I'll be off.", + cond = function(npc, player) return q and q:isCompleted(e[3].almost) and not q:isCompleted(e[3].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[3].full) + q:reward(player, e[3].id) + q:reward(player, final_reward) + q:update_needed_ingredients(player) + q:winner_is(player, alchemist_num) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.DONE) + end + }, + } +} + +newChat{ id="choice", + text = [[Excellent. With which would you like to aid me?]], + answers = { + {"The "..e[1].name..".", jump="list", + cond = function(npc, player) return not q:isCompleted(e[1].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[1].start) + q:update_needed_ingredients(player) + end, + on_select=function(npc, player) + local o = art_list[e[1].id] + o:identify(true) + game.tooltip_x, game.tooltip_y = 1, 1 + game.tooltip:displayAtMap(nil, nil, game.w, game.h, "#GOLD#"..o.name.."#LAST#\n"..tostring(o:getDesc())) + end, + }, + {"The "..e[2].name..".", jump="list", + cond = function(npc, player) return not q:isCompleted(e[2].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[2].start) + q:update_needed_ingredients(player) + end, + on_select=function(npc, player) + local o = art_list[e[2].id] + o:identify(true) + game.tooltip_x, game.tooltip_y = 1, 1 + game.tooltip:displayAtMap(nil, nil, game.w, game.h, "#GOLD#"..o.name.."#LAST#\n"..tostring(o:getDesc())) + end, + }, + {"The "..e[3].name..".", jump="list", + cond = function(npc, player) return not q:isCompleted(e[3].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[3].start) + q:update_needed_ingredients(player) + end, + on_select=function(npc, player) + local o = art_list[e[3].id] + o:identify(true) + game.tooltip_x, game.tooltip_y = 1, 1 + game.tooltip:displayAtMap(nil, nil, game.w, game.h, "#GOLD#"..o.name.."#LAST#\n"..tostring(o:getDesc())) + end, + }, + {"[leave]"}, + } +} + +newChat{ id="list", + text = [[Here's a list of the ingredients I'm missing. Please attempt to not lose your life in their pursuit. I'll be most put out if I must wait another year.]], + answers = { + {"I'll be off."}, + } +} + +-- If the elixir got made while you were out: +newChat{ id="poached", + text = [[Terribly sorry, but I've already made the elixir without your aid. I've no reward to give you, and no reason to do so if I did.]], + answers = { + {"Hrmph.", + cond = function(npc, player) return empty_handed(npc, player, 1) end, + action = function(npc, player) + q:remove_ingredients(player, e[1].short_name, 1) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[1].almost) + q:update_needed_ingredients(player) + end, + }, + {"Hrmph.", + cond = function(npc, player) return empty_handed(npc, player, 2) end, + action = function(npc, player) + q:remove_ingredients(player, e[2].short_name, 2) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[2].almost) + q:update_needed_ingredients(player) + end, + }, + {"Hrmph.", + cond = function(npc, player) return empty_handed(npc, player, 3) end, + action = function(npc, player) + q:remove_ingredients(player, e[3].short_name, 3) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[3].almost) + q:update_needed_ingredients(player) + end, + }, + } +} + +end + +return "welcome" diff --git a/game/modules/tome/data/chats/alchemist-elvala.lua b/game/modules/tome/data/chats/alchemist-elvala.lua new file mode 100644 index 0000000000000000000000000000000000000000..62b06f7e7e2db318da20a7df484fddc1bebde221 --- /dev/null +++ b/game/modules/tome/data/chats/alchemist-elvala.lua @@ -0,0 +1,522 @@ +-- ToME - Tales of Maj'Eyal +-- Copyright (C) 2009, 2010 Nicolas Casalini +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +-- Nicolas Casalini "DarkGod" +-- darkgod@te4.org + +local art_list = mod.class.Object:loadList("/data/general/objects/brotherhood-artifacts.lua") +local ing_list = mod.class.Object:loadList("/data/general/objects/elixir-ingredients.lua") +local alchemist_num = 2 +local other_alchemist_nums = {1, 3, 4} +local q = game.player:hasQuest("brotherhood-of-alchemists") +local final_reward = "ELIXIR_INVULNERABILITY" +local e = { + { + short_name = "mysticism", + name = "elixir of mysticism", + id = "ELIXIR_MYSTICISM", + start = "mysticism_start", + almost = "mysticism_almost_done", + full = "elixir_of_mysticism", + full_2 = "elixir_of_the_savior", + full_3 = "elixir_of_mastery", + poached = "mysticism_poached", + }, + { + short_name = "savior", + name = "elixir of the savior", + id = "ELIXIR_SAVIOR", + start = "savior_start", + almost = "savior_almost_done", + full = "elixir_of_the_savior", + full_2 = "elixir_of_mysticism", + full_3 = "elixir_of_mastery", + poached = "savior_poached", + }, + { + short_name = "mastery", + name = "elixir of mastery", + id = "ELIXIR_MASTERY", + start = "mastery_start", + almost = "mastery_almost_done", + full = "elixir_of_mastery", + full_2 = "elixir_of_mysticism", + full_3 = "elixir_of_the_savior", + poached = "mastery_poached", + }, +} + +--cond function for turning in non-final elixirs +--checks that player has quest and elixir ingredients, hasn't completed it yet, has started that elixir, and hasn't completed both other elixirs since that would make this the last one: +local function turn_in(npc, player, n) -- n is the index of the elixir we're checking on + return q and q:check_ingredients(player, e[n].short_name, n) -- make sure we have the quest and the elixir's ingredients + and not q:isCompleted(e[n].almost) and not q:isCompleted(e[n].full) --make sure we haven't finished the quest already + and q:isCompleted(e[n].start) --make sure we've been given the task to make this elixir + and not (q:isCompleted(e[n].full_2) and q:isCompleted(e[n].full_3)) --make sure we haven't already finished both the other elixirs, since that would make this the final one which requires a special dialog. +end + +--cond function for turning in final elixir with index n +--checks that player has quest and elixir ingredients, hasn't completed it yet, has started that elixir, and both the other elixirs are done +local function turn_in_final(npc, player, n) -- n is the index of the elixir we're checking on + return q and q:check_ingredients(player, e[n].short_name, n) -- make sure we have the quest and the elixir's ingredients + and not q:isCompleted(e[n].almost) and not q:isCompleted(e[n].full) --make sure we haven't finished the quest already + and q:isCompleted(e[n].start) --make sure we've been given the task to make this elixir + and (q:isCompleted(e[n].full_2) and q:isCompleted(e[n].full_3)) --make sure the other two elixirs are made, thus making this the final turn-in +end + +--cond function for turning in poached (completed by somebody besides you) elixirs +--checks that the player has the quest and elixir ingredients, hasn't turned it in, the task is complete anyway, the task has actually been started, and that it's been poached +local function turn_in_poached(npc, player, n) -- n is the index of the elixir we're checking on + return q and q:check_ingredients(player, e[n].short_name, n) -- make sure we have the quest and the elixir's ingredients + and not q:isCompleted(e[n].almost) --make sure we haven't turned it in already + and q:isCompleted(e[n].full) --make sure that, even though we haven't turned it in, the elixir has been made for this alchemist + and q:isCompleted(e[n].start) --make sure we've been given the task to make this elixir + and q:isCompleted(e[n].poached) --make sure this task has been poached +end + +local function more_aid(npc, player) + return not (q:isCompleted(e[1].full) and q:isCompleted(e[2].full) and q:isCompleted(e[3].full)) --make sure all the elixirs aren't already made + --Next, for each of the three elixirs, make sure it's not the case that: + --1) we're either working on it or... 2) we've started (but not finished) the elixir and it got poached. + and not ((q:isCompleted(e[1].start) and not q:isCompleted(e[1].full)) or (q:isCompleted(e[1].start) and q:isCompleted(e[1].poached) and q:isCompleted(e[1].almost)) ) + and not ((q:isCompleted(e[2].start) and not q:isCompleted(e[2].full)) or (q:isCompleted(e[2].start) and q:isCompleted(e[2].poached) and q:isCompleted(e[2].almost)) ) + and not ((q:isCompleted(e[3].start) and not q:isCompleted(e[3].full)) or (q:isCompleted(e[3].start) and q:isCompleted(e[3].poached) and q:isCompleted(e[3].almost)) ) +end + +local function give_bits(npc, player, n) -- n is the index of the elixir we're checking on + return q and q:check_ingredients(player, e[n].short_name) -- make sure we have the quest and the elixir's ingredients + and q:isCompleted(e[n].start) --make sure we've started the task + and not q:isCompleted(e[n].full) --... but not finished +end + +local function empty_handed(npc, player, n) -- n is the index of the elixir we're checking on + return q and q:check_ingredients(player, e[n].short_name, n) -- make sure we have the quest and the elixir's ingredients + and q:isCompleted(e[n].start) --make sure we've started the task + and not q:isCompleted(e[n].almost) --make sure we've not turned the stuff in before... + and q:isCompleted(e[n].full) --... and yet the elixir is already made (poached!) +end + +--Make the alchemist's reaction to your turn-in vary depending on whether he lost. +local function alchemist_reaction_complete(npc, player, lose, other_alch, other_elixir) + if lose == true then + return ([[Too late! Argh, too late. %s has already finished. I'll make the elixir and reward you as promised, but only because the Brotherhood breaks the fingers of non-member alchemists who rook people. Members, on the other hand...]]):format(other_alch) + else + return ([[Give them here. You took long enough; %s cooked up a %s in your absence. Be quicker about the next one lest I make a 'mistake' in brewing your reward.]]):format(other_alch, other_elixir) + end +end + +if not q or (q and not q:isCompleted(e[1].start) and not q:isCompleted(e[2].start) and not q:isCompleted(e[3].start)) then + +-- Here's the dialog that pops up if the player has never worked for this alchemist before: +newChat{ id="welcome", + text = [[#LIGHT_GREEN#*A shabbily-dressed elf opens the door, scratching his head in apparent puzzlement.*#WHITE# +Another adventurer? Or have we met? I can't tell people apart unless they wear brightly-colored headbands. You need to help me.]], + answers = { + {"I am indeed an adventurer. Go on.", jump="ominous"}, + {"[leave]"}, + } +} + +newChat{ id="ominous", + text = [[Three elixirs stand between me and acceptance into the Brotherhood of Alchemists, unless I've been through that already. I'm never quite sure. But I think that's the case. Bring me the ingredients.]], + answers = { + {"What elixirs? What ingredients?", jump="proposal"}, + } +} + +newChat{ id="proposal", + text = [[The ones that I need to get before the other alchemists get them. Can't have some lesser hack sneaking into the Brotherhood.]], + answers = { + {"You're making little sense.", jump="help"}, + } +} + +newChat{ id="help", + text = [[#LIGHT_GREEN#*He raises his voice and gestures exaggeratedly, seemingly taking you for an idiot.*#WHITE# +Me need pieces of scary monsters for happy-making drink. You get me pieces. You probably get eaten by monsters, me have this conversation yet again with other bonehead.]], + answers = { + {"I've been known to kill the occasional monster. Is there a reward in it for me?", jump="competition"}, + } +} + +newChat{ id="competition", + text = [[It finally understands! You get a dose of every elixir you help me make. And if your help gets me into the Brotherhood, I've got half an Elixir of Invulnerability lying around that I'll give you. Don't try anything; I've already downed the other half.]], + answers = { + {"I accept.", jump="choice", action = function(npc, player) player:grantQuest("brotherhood-of-alchemists") end,}, + {"I cannot aid you at this time."}, + } +} + +newChat{ id="choice", + text = [[Three elixirs I need. I'll show you the ingredients to one at a time. Are you interested in the Elixir of Mysticism, the Elixir of the Savior, or the Elixir of Mastery?]], + answers = { + {"The "..e[1].name..".", jump="list", + cond = function(npc, player) return not game.player:hasQuest("brotherhood-of-alchemists"):isCompleted(e[1].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[1].start) + game.player:hasQuest("brotherhood-of-alchemists"):update_needed_ingredients(player) + end, + on_select=function(npc, player) + local o = art_list[e[1].id] + o:identify(true) + game.tooltip_x, game.tooltip_y = 1, 1 + game.tooltip:displayAtMap(nil, nil, game.w, game.h, "#GOLD#"..o.name.."#LAST#\n"..tostring(o:getDesc())) + end, + }, + {"The "..e[2].name..".", jump="list", + cond = function(npc, player) return not game.player:hasQuest("brotherhood-of-alchemists"):isCompleted(e[2].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[2].start) + game.player:hasQuest("brotherhood-of-alchemists"):update_needed_ingredients(player) + end, + on_select=function(npc, player) + local o = art_list[e[2].id] + o:identify(true) + game.tooltip_x, game.tooltip_y = 1, 1 + game.tooltip:displayAtMap(nil, nil, game.w, game.h, "#GOLD#"..o.name.."#LAST#\n"..tostring(o:getDesc())) + end, + }, + {"The "..e[3].name..".", jump="list", + cond = function(npc, player) return not game.player:hasQuest("brotherhood-of-alchemists"):isCompleted(e[3].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[3].start) + game.player:hasQuest("brotherhood-of-alchemists"):update_needed_ingredients(player) + end, + on_select=function(npc, player) + local o = art_list[e[3].id] + o:identify(true) + game.tooltip_x, game.tooltip_y = 1, 1 + game.tooltip:displayAtMap(nil, nil, game.w, game.h, "#GOLD#"..o.name.."#LAST#\n"..tostring(o:getDesc())) + end, + }, + {"[leave]"}, + } +} + +newChat{ id="list", + text = [[Here's a list of the monster bits I need. Now hurry up; I'm not getting any saner here.]], + answers = { + {"So I see. I'll be off."}, + } +} + +-- Quest is complete; nobody answers the door +elseif q and q:isStatus(q.DONE) then +newChat{ id="welcome", + text = [[#LIGHT_GREEN#*The door is locked and nobody responds to your knocks*#WHITE#]], + answers = { + {"[Leave]"}, + } +} + + +else -- Here's the dialog that pops up if the player *has* worked with this alchemist before (either done quests or is in the middle of one): + +local other_alch, other_elixir, player_loses, alch_picked, e_picked = q:competition(player, other_alchemist_nums) + +newChat{ id="welcome", + text = [[#LIGHT_GREEN#*The shabby elf opens his door.*#WHITE# +Do I know you?]], + answers = { + -- If not the final elixir: + {"I've returned with the ingredients for the "..e[1].name..".", jump="complete", + cond = function(npc, player) return turn_in(npc, player, 1) end, + action = function(npc, player) + q:on_turnin(player, alch_picked, e_picked, false) + end, + }, + {"I've returned with the ingredients for the "..e[2].name..".", jump="complete", + cond = function(npc, player) return turn_in(npc, player, 2) end, + action = function(npc, player) + q:on_turnin(player, alch_picked, e_picked, false) + end, + }, + {"I've returned with the ingredients for the "..e[3].name..".", jump="complete", + cond = function(npc, player) return turn_in(npc, player, 3) end, + action = function(npc, player) + q:on_turnin(player, alch_picked, e_picked, false) + end, + }, + + -- If the final elixir: + {"I've returned with the ingredients for the "..e[1].name..".", jump="totally-complete", + cond = function(npc, player) return turn_in_final(npc, player, 1) end, + }, + {"I've returned with the ingredients for the "..e[2].name..".", jump="totally-complete", + cond = function(npc, player) return turn_in_final(npc, player, 2) end, + }, + {"I've returned with the ingredients for the "..e[3].name..".", jump="totally-complete", + cond = function(npc, player) return turn_in_final(npc, player, 3) end, + }, + + -- If the elixir got made while you were out: + {"I've returned with the ingredients for the "..e[1].name..".", jump="poached", + cond = function(npc, player) return turn_in_poached(npc, player, 1) end, + }, + {"I've returned with the ingredients for the "..e[2].name..".", jump="poached", + cond = function(npc, player) return turn_in_poached(npc, player, 2) end, + }, + {"I've returned with the ingredients for the "..e[3].name..".", jump="poached", + cond = function(npc, player) return turn_in_poached(npc, player, 3) end, + }, + + --Don't let player work on multiple elixirs for the same alchemist. + --See comments in more_aid function above for all the gory detail + {"I've come to offer more aid.", jump="choice", + cond = function(npc, player) return more_aid(npc, player) end, + }, + {"[leave]"}, + } +} + +--Not final elixir: +newChat{ id="complete", + text = alchemist_reaction_complete(npc, player, player_loses, other_alch, other_elixir), + answers = { + {"[Give him the monster bits.]", jump="complete2", + cond = function(npc, player) return give_bits(npc, player, 1) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[1].almost) + q:remove_ingredients(player, e[1].short_name, 1) + end + }, + {"[Give him the monster bits.]", jump="complete2", + cond = function(npc, player) return give_bits(npc, player, 2) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[2].almost) + q:remove_ingredients(player, e[2].short_name, 2) + end + }, + {"[Give him the monster bits.]", jump="complete2", + cond = function(npc, player) return give_bits(npc, player, 3) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[3].almost) + q:remove_ingredients(player, e[3].short_name, 3) + end + }, +-- {"Sorry, it seems I lack some stuff. I will be back."}, + } +} + +--Final elixir: +newChat{ id="totally-complete", + text = [[#LIGHT_GREEN#*The elf claps his scarred hands together.*#WHITE# +Exceptional work, lackey! The final elixir awaits! Oh, yes. Membership will be mine. And revenge. Ohhhh yes.]], + answers = { + {"[Give him the monster bits]", jump="totally-complete2", + cond = function(npc, player) return give_bits(npc, player, 1) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[1].almost) + q:remove_ingredients(player, e[1].short_name, 1) + end + }, + {"[Give him the monster bits]", jump="totally-complete2", + cond = function(npc, player) return give_bits(npc, player, 2) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[2].almost) + q:remove_ingredients(player, e[2].short_name, 2) + end + }, + {"[Give him the monster bits]", jump="totally-complete2", + cond = function(npc, player) return give_bits(npc, player, 3) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[3].almost) + q:remove_ingredients(player, e[3].short_name, 3) + end + }, + --{"Sorry, it seems I lack some stuff. I will be back."}, + } +} + +--Not final elixir: +newChat{ id="complete2", + text = [[Contain your impatience while I prepare these. I'll have the elixir within the hour.]], + answers = { + {"[Wait]", jump="complete3"}, + + } +} + +--Final Elixir: +newChat{ id="totally-complete2", + text = [[Perfection. Wait here.]], + answers = { + {"[Wait]", jump="totally-complete3"}, + + } +} + +--Not final elixir: +newChat{ id="complete3", + text = [[#LIGHT_GREEN#*The elf finally returns and tosses you a small vial of fine glass.*#WHITE# +Side effects may include some slight mental imbalances.]], + answers = { + {"Thank you. I'll be off.", + cond = function(npc, player) return q and q:isCompleted(e[1].almost) and not q:isCompleted(e[1].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[1].full) + q:reward(player, e[1].id) + q:update_needed_ingredients(player) + end + }, + {"Thank you. I'll be off.", + cond = function(npc, player) return q and q:isCompleted(e[2].almost) and not q:isCompleted(e[2].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[2].full) + q:reward(player, e[2].id) + q:update_needed_ingredients(player) + end + }, + {"Thank you. I'll be off.", + cond = function(npc, player) return q and q:isCompleted(e[3].almost) and not q:isCompleted(e[3].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[3].full) + q:reward(player, e[3].id) + q:update_needed_ingredients(player) + end + }, + } +} + +--Final elixir: +newChat{ id="totally-complete3", + text = [[#LIGHT_GREEN#*The alchemist finally returns with two vials.*#WHITE# +I have no idea who you are, but I'm pretty sure that I'm supposed to give these to somebody as a reward. If some adventurer kills you and takes them, then apparently you're not the fellow I'm looking for.]], + answers = { + {"Thank you. I'll be off.", + cond = function(npc, player) return q and q:isCompleted(e[1].almost) and not q:isCompleted(e[1].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[1].full) + q:reward(player, e[1].id) + q:reward(player, final_reward) + q:update_needed_ingredients(player) + q:winner_is(player, alchemist_num) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.DONE) + + end + }, + {"Thank you. I'll be off.", + cond = function(npc, player) return q and q:isCompleted(e[2].almost) and not q:isCompleted(e[2].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[2].full) + q:reward(player, e[2].id) + q:reward(player, final_reward) + q:update_needed_ingredients(player) + q:winner_is(player, alchemist_num) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.DONE) + end + }, + {"Thank you. I'll be off.", + cond = function(npc, player) return q and q:isCompleted(e[3].almost) and not q:isCompleted(e[3].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[3].full) + q:reward(player, e[3].id) + q:reward(player, final_reward) + q:update_needed_ingredients(player) + q:winner_is(player, alchemist_num) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.DONE) + end + }, + } +} + +newChat{ id="choice", + text = [[Which of the remaining elixirs interests you?]], + answers = { + {"The "..e[1].name..".", jump="list", + cond = function(npc, player) return not q:isCompleted(e[1].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[1].start) + q:update_needed_ingredients(player) + end, + on_select=function(npc, player) + local o = art_list[e[1].id] + o:identify(true) + game.tooltip_x, game.tooltip_y = 1, 1 + game.tooltip:displayAtMap(nil, nil, game.w, game.h, "#GOLD#"..o.name.."#LAST#\n"..tostring(o:getDesc())) + end, + }, + {"The "..e[2].name..".", jump="list", + cond = function(npc, player) return not q:isCompleted(e[2].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[2].start) + q:update_needed_ingredients(player) + end, + on_select=function(npc, player) + local o = art_list[e[2].id] + o:identify(true) + game.tooltip_x, game.tooltip_y = 1, 1 + game.tooltip:displayAtMap(nil, nil, game.w, game.h, "#GOLD#"..o.name.."#LAST#\n"..tostring(o:getDesc())) + end, + }, + {"The "..e[3].name..".", jump="list", + cond = function(npc, player) return not q:isCompleted(e[3].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[3].start) + q:update_needed_ingredients(player) + end, + on_select=function(npc, player) + local o = art_list[e[3].id] + o:identify(true) + game.tooltip_x, game.tooltip_y = 1, 1 + game.tooltip:displayAtMap(nil, nil, game.w, game.h, "#GOLD#"..o.name.."#LAST#\n"..tostring(o:getDesc())) + end, + }, + {"[leave]"}, + } +} + +newChat{ id="list", + text = [[Here's a list of the ingredients I'm missing. Please follow the directions carefully, or the resulting elixir could be more fatal than either of us would hope.]], + answers = { + {"I'll be off."}, + } +} + +-- If the elixir got made while you were out: +newChat{ id="poached", + text = [[Already made it. Best pick up the pace next time, adventurer.]], + answers = { + {"Hrmph.", + cond = function(npc, player) return empty_handed(npc, player, 1) end, + action = function(npc, player) + q:remove_ingredients(player, e[1].short_name, 1) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[1].almost) + q:update_needed_ingredients(player) + end, + }, + {"Hrmph.", + cond = function(npc, player) return empty_handed(npc, player, 2) end, + action = function(npc, player) + q:remove_ingredients(player, e[2].short_name, 2) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[2].almost) + q:update_needed_ingredients(player) + end, + }, + {"Hrmph.", + cond = function(npc, player) return empty_handed(npc, player, 3) end, + action = function(npc, player) + q:remove_ingredients(player, e[3].short_name, 3) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[3].almost) + q:update_needed_ingredients(player) + end, + }, + } +} + +end + +return "welcome" diff --git a/game/modules/tome/data/chats/alchemist-hermit.lua b/game/modules/tome/data/chats/alchemist-hermit.lua new file mode 100644 index 0000000000000000000000000000000000000000..30754e3b2b333d0a5d34709ed4f3da7da289c2c7 --- /dev/null +++ b/game/modules/tome/data/chats/alchemist-hermit.lua @@ -0,0 +1,526 @@ +-- ToME - Tales of Maj'Eyal +-- Copyright (C) 2009, 2010 Nicolas Casalini +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +-- Nicolas Casalini "DarkGod" +-- darkgod@te4.org + +local art_list = mod.class.Object:loadList("/data/general/objects/brotherhood-artifacts.lua") +local ing_list = mod.class.Object:loadList("/data/general/objects/elixir-ingredients.lua") +local alchemist_num = 3 +local other_alchemist_nums = {1, 2, 4} +local q = game.player:hasQuest("brotherhood-of-alchemists") +local final_reward = "INFUSION_WILD_GROWTH" +local e = { + { + short_name = "force", + name = "elixir of explosive force", + cap_name = "ELIXIR OF EXPLOSIVE FORCE", + id = "ELIXIR_FORCE", + start = "force_start", + almost = "force_almost_done", + full = "elixir_of_explosive_force", + full_2 = "elixir_of_serendipity", + full_3 = "elixir_of_focus", + poached = "force_poached", + }, + { + short_name = "serendipity", + name = "elixir of serendipity", + cap_name = "ELIXIR OF SERENDIPITY", + id = "ELIXIR_SERENDIPITY", + start = "serendipity_start", + almost = "serendipity_almost_done", + full = "elixir_of_serendipity", + full_2 = "elixir_of_explosive_force", + full_3 = "elixir_of_focus", + poached = "serendipity_poached", + }, + { + short_name = "focus", + name = "elixir of focus", + cap_name = "ELIXIR OF FOCUS", + id = "ELIXIR_FOCUS", + start = "focus_start", + almost = "focus_almost_done", + full = "elixir_of_focus", + full_2 = "elixir_of_explosive_force", + full_3 = "elixir_of_serendipity", + poached = "focus_poached", + }, +} + +--cond function for turning in non-final elixirs +--checks that player has quest and elixir ingredients, hasn't completed it yet, has started that elixir, and hasn't completed both other elixirs since that would make this the last one: +local function turn_in(npc, player, n) -- n is the index of the elixir we're checking on + return q and q:check_ingredients(player, e[n].short_name, n) -- make sure we have the quest and the elixir's ingredients + and not q:isCompleted(e[n].almost) and not q:isCompleted(e[n].full) --make sure we haven't finished the quest already + and q:isCompleted(e[n].start) --make sure we've been given the task to make this elixir + and not (q:isCompleted(e[n].full_2) and q:isCompleted(e[n].full_3)) --make sure we haven't already finished both the other elixirs, since that would make this the final one which requires a special dialog. +end + +--cond function for turning in final elixir with index n +--checks that player has quest and elixir ingredients, hasn't completed it yet, has started that elixir, and both the other elixirs are done +local function turn_in_final(npc, player, n) -- n is the index of the elixir we're checking on + return q and q:check_ingredients(player, e[n].short_name, n) -- make sure we have the quest and the elixir's ingredients + and not q:isCompleted(e[n].almost) and not q:isCompleted(e[n].full) --make sure we haven't finished the quest already + and q:isCompleted(e[n].start) --make sure we've been given the task to make this elixir + and (q:isCompleted(e[n].full_2) and q:isCompleted(e[n].full_3)) --make sure the other two elixirs are made, thus making this the final turn-in +end + +--cond function for turning in poached (completed by somebody besides you) elixirs +--checks that the player has the quest and elixir ingredients, hasn't turned it in, the task is complete anyway, the task has actually been started, and that it's been poached +local function turn_in_poached(npc, player, n) -- n is the index of the elixir we're checking on + return q and q:check_ingredients(player, e[n].short_name, n) -- make sure we have the quest and the elixir's ingredients + and not q:isCompleted(e[n].almost) --make sure we haven't turned it in already + and q:isCompleted(e[n].full) --make sure that, even though we haven't turned it in, the elixir has been made for this alchemist + and q:isCompleted(e[n].start) --make sure we've been given the task to make this elixir + and q:isCompleted(e[n].poached) --make sure this task has been poached +end + +local function more_aid(npc, player) + return not (q:isCompleted(e[1].full) and q:isCompleted(e[2].full) and q:isCompleted(e[3].full)) --make sure all the elixirs aren't already made + --Next, for each of the three elixirs, make sure it's not the case that: + --1) we're either working on it or... 2) we've started (but not finished) the elixir and it got poached. + and not ((q:isCompleted(e[1].start) and not q:isCompleted(e[1].full)) or (q:isCompleted(e[1].start) and q:isCompleted(e[1].poached) and q:isCompleted(e[1].almost)) ) + and not ((q:isCompleted(e[2].start) and not q:isCompleted(e[2].full)) or (q:isCompleted(e[2].start) and q:isCompleted(e[2].poached) and q:isCompleted(e[2].almost)) ) + and not ((q:isCompleted(e[3].start) and not q:isCompleted(e[3].full)) or (q:isCompleted(e[3].start) and q:isCompleted(e[3].poached) and q:isCompleted(e[3].almost)) ) +end + +local function give_bits(npc, player, n) -- n is the index of the elixir we're checking on + return q and q:check_ingredients(player, e[n].short_name) -- make sure we have the quest and the elixir's ingredients + and q:isCompleted(e[n].start) --make sure we've started the task + and not q:isCompleted(e[n].full) --... but not finished +end + +local function empty_handed(npc, player, n) -- n is the index of the elixir we're checking on + return q and q:check_ingredients(player, e[n].short_name, n) -- make sure we have the quest and the elixir's ingredients + and q:isCompleted(e[n].start) --make sure we've started the task + and not q:isCompleted(e[n].almost) --make sure we've not turned the stuff in before... + and q:isCompleted(e[n].full) --... and yet the elixir is already made (poached!) +end + +--Make the alchemist's reaction to your turn-in vary depending on whether he lost. +local function alchemist_reaction_complete(npc, player, lose, other_alch, other_elixir) + if lose == true then + return ([[SON OF A RITCH! YOU SHOW UP TEN MINUTES AFTER I GET THE NEWS THAT SOME JACKASS ALREADY FINISHED THE ELIXIRS AND IS GETTING ACCEPTED BY THE BROTHERHOOD. WHAT THE HELL TOOK YOU SO LONG? MIRVENIA'S MAMMARIES, I'LL TAKE THESE AND MAKE YOU YOUR REWARD, BUT ONLY BECAUSE A CURSE WILL KILL ME IF I DON'T. AND IF IT TASTES LIKE PISS, THAT'S YOUR IMAGINATION, I'M SURE.]]) + else + return ([[#LIGHT_GREEN#*The halfling hands you a note that says, 'Heard %s managed to make a %s while you've been loafing. Hurry the hell up next time.*#WHITE# + HAD SOME IDIOT FROM THE BROTHERHOOD HERE EARLIER WHO TRIED TO RESCIND MY INVITATION TO APPLY, TALKING OUT HIS ASS ABOUT THREATENING LETTERS OR SOME SIMILAR IDIOCY. FORTUNATELY, I APPARENTLY HAVE A BETTER GRASP OF THE BROTHERHOOD'S CODE THAN THIS IDIOT DOES, SO HE HAD TO GO HOME FEELING LIKE A MORON, WHICH I'M GUESSING IS PRETTY MUCH NORMAL FOR HIM.]]):format(other_alch, other_elixir) + end +end + +if not q or (q and not q:isCompleted(e[1].start) and not q:isCompleted(e[2].start) and not q:isCompleted(e[3].start)) then + +-- Here's the dialog that pops up if the player has never worked for this alchemist before: +newChat{ id="welcome", + text = [[#LIGHT_GREEN#*After a great deal of pounding, a halfling wrapped in charred, smoking robes opens the door. He looks irritated.*#WHITE# +IT'S NOT ENOUGH THAT I WORK ALL MORNING TO MAKE A POTION THAT ENDS UP NEARLY BLOWING MY ASS OFF, BUT NOW I'VE GOT IDIOTS BEATING DOWN MY DAMNED FRONT DOOR WITH WHAT SOUNDS LIKE A BATTERING RAM, AND YES, I HEARD IT, THOUGH I CAN HARDLY MAKE OUT A BLEEDING THING WITH THESE BLEEDING, CONCUSSED EARS. WHAT DO YOU WANT?]], + answers = { + {"Perhaps there's something that I can help you with.", jump="ominous"}, + {"[leave]"}, + } +} + +newChat{ id="ominous", + text = [[SPEAK UP, HAMBRAIN. I'VE JUST GOTTEN MY EARDRUMS BLOWN OUT BY YET ANOTHER BY-THE-PYRE POTION GONE SOUTH, REMEMBER? THRICE-DAMNED THING WAS GOING PERFECTLY, TOO. TOKNOR'S TACKLE!]], + answers = { + {"I SAID, MAYBE THERE'S SOMETHING THAT I CAN HELP YOU WITH!", jump="proposal"}, + } +} + +newChat{ id="proposal", + text = [[STILL CAN'T HEAR YOU, BUT LISTEN UP. THE BROTHERHOOD OF ALCHEMISTS IS ACCEPTING THE FIRST NEW APPLICANT TO DEMONSTRATE, AMONG OTHER THINGS, THREE VERY COMPLICATED ELIXIRS. I WOULDN'T BOTHER TRYING TO JOIN SUCH A BUNCH OF ADDLE-BRAINED DEGENERATES, BUT IT SO HAPPENS THAT THE BROTHERHOOD OF ALCHEMISTS HOLDS THE SECRET CURE FOR THE COMMON BLOWN-OFF ASS, WHICH IT SO HAPPENS IS OF SOME INTEREST TO ME.]], + answers = { + {"HOW CAN I HELP?", jump="help"}, + } +} + +newChat{ id="help", + text = [[AND YOU KNOW WHAT ELSE? THEY KNOW DAMNED WELL WHAT ADVANCES IN THE FIELD OF ALCHEMY WOULD DO FOR EVERY SENTIENT CIVILIZATION, BUT THEY HOARD THEIR FEW WORTHWHILE SECRETS LIKE A GREAT BROWN WYRM SITTING ON ITS PILE OF CRAP. YOU KNOW WHAT? I DON'T EVEN WANT THE ASS-CURE FOR ME. I'M GOING TO STEAL EVERY SECRET THEY'VE GOT, WRITE THEM DOWN, MAKE A HUNDRED COPIES, AND NAIL ONE TO A TREE IN EVERY VILLAGE IN MAJ'EYAL.]], + answers = { + {"THAT'S NOT A VERY HERMIT-LIKE ATTITUDE.", jump="competition"}, + } +} + +newChat{ id="competition", + text = [[AND THEN WHAT WILL THEY DO? ONCE THEIR PRECIOUS SECRETS-- WHICH, IN ALL PROBABILITY, EITHER DON'T EXIST OR ARE THINGS LIKE RECIPES FOR ELIXIRS OF WHO-GIVES-A-FLYING-DUCK-- ARE OUT IN THE OPEN, THE BROTHERHOOD OF ASSWIPES WILL HAVE NOTHING TO HOLD IT TOGETHER BUT ELIXIRS OF THEIR TEARS AND WIDESPREAD DISDAIN FROM THE REST OF THE WORLD. SPEAK UP, THEN. ARE YOU IN OR OUT?]], + answers = { + {"I'M IN.", jump="choice", action = function(npc, player) player:grantQuest("brotherhood-of-alchemists") end,}, + {"I CANNOT AID YOU AT THIS TIME."}, + } +} + +newChat{ id="choice", + text = [[#LIGHT_GREEN#*He hands you a slip of paper with the names and properties of some elixirs on it.*#WHITE# +THE INGREDIENTS TO THESE SUCKERS ARE SORT OF A TRADE SECRET, SO I'LL TELL YOU ABOUT ONE AND WE'LL SEE HOW THAT GOES. OH, AND I'LL MAKE ENOUGH FOR YOU TO HAVE A SWIG WHEN I'M DONE, SO GOOD FOR YOU. WHICH ONE WILL IT BE? JUST POINT AT THE DAMNED LIST. I HAVEN'T HEARD A THING YOU'VE SAID YET. I HOPE TO HELL YOU'RE NOT STANDING THERE TRYING TO SELL ME SOMETHING.]], + answers = { + {"[Indicate the "..e[1].name..".]", jump="list", + cond = function(npc, player) return not game.player:hasQuest("brotherhood-of-alchemists"):isCompleted(e[1].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[1].start) + game.player:hasQuest("brotherhood-of-alchemists"):update_needed_ingredients(player) + end, + on_select=function(npc, player) + local o = art_list[e[1].id] + o:identify(true) + game.tooltip_x, game.tooltip_y = 1, 1 + game.tooltip:displayAtMap(nil, nil, game.w, game.h, "#GOLD#"..o.name.."#LAST#\n"..tostring(o:getDesc())) + end, + }, + {"[Indicate the "..e[2].name..".]", jump="list", + cond = function(npc, player) return not game.player:hasQuest("brotherhood-of-alchemists"):isCompleted(e[2].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[2].start) + game.player:hasQuest("brotherhood-of-alchemists"):update_needed_ingredients(player) + end, + on_select=function(npc, player) + local o = art_list[e[2].id] + o:identify(true) + game.tooltip_x, game.tooltip_y = 1, 1 + game.tooltip:displayAtMap(nil, nil, game.w, game.h, "#GOLD#"..o.name.."#LAST#\n"..tostring(o:getDesc())) + end, + }, + {"[Indicate the "..e[3].name..".]", jump="list", + cond = function(npc, player) return not game.player:hasQuest("brotherhood-of-alchemists"):isCompleted(e[3].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[3].start) + game.player:hasQuest("brotherhood-of-alchemists"):update_needed_ingredients(player) + end, + on_select=function(npc, player) + local o = art_list[e[3].id] + o:identify(true) + game.tooltip_x, game.tooltip_y = 1, 1 + game.tooltip:displayAtMap(nil, nil, game.w, game.h, "#GOLD#"..o.name.."#LAST#\n"..tostring(o:getDesc())) + end, + }, + {"[leave]"}, + } +} + +newChat{ id="list", + text = [[HERE'S A LIST OF THE STUFF I NEED. MOST OF IT WILL TRY TO KILL YOU, SO I HOPE YOU'RE NOT INCOMPETENT.]], + answers = { + {"I'LL BE OFF."}, + } +} + +-- Quest is complete; nobody answers the door +elseif q and q:isStatus(q.DONE) then +newChat{ id="welcome", + text = [[#LIGHT_GREEN#*The door is locked and nobody responds to your knocks*#WHITE#]], + answers = { + {"[Leave]"}, + } +} + + +else -- Here's the dialog that pops up if the player *has* worked with this alchemist before (either done quests or is in the middle of one): + +local other_alch, other_elixir, player_loses, alch_picked, e_picked = q:competition(player, other_alchemist_nums) + +newChat{ id="welcome", + text = [[#LIGHT_GREEN#*The halfling, still smoking, opens his door.*#WHITE# +I LIVE WAY THE HELL OUT HERE FOR A REASON, YOU PIECE OF... OH. IT'S YOU.]], + answers = { + -- If not the final elixir: + {"I'VE RETURNED WITH THE INGREDIENTS FOR THE "..e[1].cap_name..".", jump="complete", + cond = function(npc, player) return turn_in(npc, player, 1) end, + action = function(npc, player) + q:on_turnin(player, alch_picked, e_picked, false) + end, + }, + {"I'VE RETURNED WITH THE INGREDIENTS FOR THE "..e[2].cap_name..".", jump="complete", + cond = function(npc, player) return turn_in(npc, player, 2) end, + action = function(npc, player) + q:on_turnin(player, alch_picked, e_picked, false) + end, + }, + {"I'VE RETURNED WITH THE INGREDIENTS FOR THE "..e[3].cap_name..".", jump="complete", + cond = function(npc, player) return turn_in(npc, player, 3) end, + action = function(npc, player) + q:on_turnin(player, alch_picked, e_picked, false) + end, + }, + + -- If the final elixir: + {"I'VE RETURNED WITH THE INGREDIENTS FOR THE "..e[1].cap_name..".", jump="totally-complete", + cond = function(npc, player) return turn_in_final(npc, player, 1) end, + }, + {"I'VE RETURNED WITH THE INGREDIENTS FOR THE "..e[2].cap_name..".", jump="totally-complete", + cond = function(npc, player) return turn_in_final(npc, player, 2) end, + }, + {"I'VE RETURNED WITH THE INGREDIENTS FOR THE "..e[3].cap_name..".", jump="totally-complete", + cond = function(npc, player) return turn_in_final(npc, player, 3) end, + }, + + -- If the elixir got made while you were out: + {"I'VE RETURNED WITH THE INGREDIENTS FOR THE "..e[1].cap_name..".", jump="poached", + cond = function(npc, player) return turn_in_poached(npc, player, 1) end, + }, + {"I'VE RETURNED WITH THE INGREDIENTS FOR THE "..e[2].cap_name..".", jump="poached", + cond = function(npc, player) return turn_in_poached(npc, player, 2) end, + }, + {"I'VE RETURNED WITH THE INGREDIENTS FOR THE "..e[3].cap_name..".", jump="poached", + cond = function(npc, player) return turn_in_poached(npc, player, 3) end, + }, + + --Don't let player work on multiple elixirs for the same alchemist. + --See comments in more_aid function above for all the gory detail + {"I'VE COME TO OFFER MORE AID.", jump="choice", + cond = function(npc, player) return more_aid(npc, player) end, + }, + {"[leave]"}, + } +} + +--Not final elixir: +newChat{ id="complete", + text = alchemist_reaction_complete(npc, player, player_loses, other_alch, other_elixir), + answers = { + {"[Give him the monster bits.]", jump="complete2", + cond = function(npc, player) return give_bits(npc, player, 1) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[1].almost) + q:remove_ingredients(player, e[1].short_name, 1) + end + }, + {"[Give him the monster bits.]", jump="complete2", + cond = function(npc, player) return give_bits(npc, player, 2) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[2].almost) + q:remove_ingredients(player, e[2].short_name, 2) + end + }, + {"[Give him the monster bits.]", jump="complete2", + cond = function(npc, player) return give_bits(npc, player, 3) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[3].almost) + q:remove_ingredients(player, e[3].short_name, 3) + end + }, +-- {"Sorry, it seems I lack some stuff. I will be back."}, + } +} + +--Final elixir: +newChat{ id="totally-complete", + text = [[#LIGHT_GREEN#*For the first time you've seen, genuine pleasure lights up the halfling's soot-smeared face.*#WHITE# +OHHH, THOSE BROTHERHOOD FOOLS HAVE NO IDEA WHAT'S ABOUT TO HIT THEM. GOOD WORK, WHOEVER YOU ARE. ALL OF MAJ'EYAL OWES YOU THEIR THANKS, EXCEPT FOR MEMBERS OF THE BROTHERHOOD OF ALCHEMISTS, WHO MIGHT TRY TO DO YOU BODILY HARM. FORTUNATELY FOR YOU, THEY'RE MOSTLY HARMLESS.]], + answers = { + {"[Give him the monster bits]", jump="totally-complete2", + cond = function(npc, player) return give_bits(npc, player, 1) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[1].almost) + q:remove_ingredients(player, e[1].short_name, 1) + end + }, + {"[Give him the monster bits]", jump="totally-complete2", + cond = function(npc, player) return give_bits(npc, player, 2) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[2].almost) + q:remove_ingredients(player, e[2].short_name, 2) + end + }, + {"[Give him the monster bits]", jump="totally-complete2", + cond = function(npc, player) return give_bits(npc, player, 3) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[3].almost) + q:remove_ingredients(player, e[3].short_name, 3) + end + }, + --{"Sorry, it seems I lack some stuff. I will be back."}, + } +} + +--Not final elixir: +newChat{ id="complete2", + text = [[WAIT HERE. THERE'S A GOOD CHANCE YOU'LL GET BLOWN INTO ADVENTURER KIBBLE IF YOU STEP INSIDE THIS BUILDING. MY ROBE OF MAD ALCHEMIST PROTECTION IS THE ONLY REASON I'M NOT VAPOUR.]], + answers = { + {"[Wait]", jump="complete3"}, + + } +} + +--Final Elixir: +newChat{ id="totally-complete2", + text = [[GIVE ME AN HOUR, AND THINK UNPLEASANT THOUGHTS ABOUT THE BROTHERHOOD. IF ANYTHING EXPLODES, COME RESCUE ME, EVEN IF IT LOOKS LIKE THE BUILDING IS AN INFERNO OF POISONOUS SMOKE AND POLKA-DOT FLAMES.]], + answers = { + {"[Wait]", jump="totally-complete3"}, + + } +} + +--Not final elixir: +newChat{ id="complete3", + text = [[#LIGHT_GREEN#*Disaster fails to occur. The halfling finally returns and hands you a small vial of sooty glass.*#WHITE# +ENJOY, AND COME BACK ANY TIME IF YOU'RE INTERESTED IN SIMILAR WORK. I HAVEN'T WON YET. THE LONGER YOU WAIT, THE MORE LIKELY IT IS THAT YOU'LL RETURN TO A SMOKING CRATER AND ONE TRULY IRATE HALFLING.]], + answers = { + {"THANK YOU. I'LL BE OFF.", + cond = function(npc, player) return q and q:isCompleted(e[1].almost) and not q:isCompleted(e[1].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[1].full) + q:reward(player, e[1].id) + q:update_needed_ingredients(player) + end + }, + {"THANK YOU. I'LL BE OFF.", + cond = function(npc, player) return q and q:isCompleted(e[2].almost) and not q:isCompleted(e[2].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[2].full) + q:reward(player, e[2].id) + q:update_needed_ingredients(player) + end + }, + {"THANK YOU. I'LL BE OFF.", + cond = function(npc, player) return q and q:isCompleted(e[3].almost) and not q:isCompleted(e[3].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[3].full) + q:reward(player, e[3].id) + q:update_needed_ingredients(player) + end + }, + } +} + +--Final elixir: +newChat{ id="totally-complete3", + text = [[#LIGHT_GREEN#*The halfling finally returns with a vial and a small pouch.*#WHITE# +YOUR DOSE OF THE ELIXIR, AS WELL AS SOMETHING ELSE. THIS INFUSION IS RARE AS HELL, SO DON'T GO WASTING IT.]], + answers = { + {"THANK YOU. I'LL BE OFF.", + cond = function(npc, player) return q and q:isCompleted(e[1].almost) and not q:isCompleted(e[1].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[1].full) + q:reward(player, e[1].id) + q:reward(player, final_reward) + q:update_needed_ingredients(player) + q:winner_is(player, alchemist_num) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.DONE) + + end + }, + {"THANK YOU. I'LL BE OFF.", + cond = function(npc, player) return q and q:isCompleted(e[2].almost) and not q:isCompleted(e[2].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[2].full) + q:reward(player, e[2].id) + q:reward(player, final_reward) + q:update_needed_ingredients(player) + q:winner_is(player, alchemist_num) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.DONE) + end + }, + {"THANK YOU. I'LL BE OFF.", + cond = function(npc, player) return q and q:isCompleted(e[3].almost) and not q:isCompleted(e[3].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[3].full) + q:reward(player, e[3].id) + q:reward(player, final_reward) + q:update_needed_ingredients(player) + q:winner_is(player, alchemist_num) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.DONE) + end + }, + } +} + +newChat{ id="choice", + text = [[WHICH ELIXIR DO YOU WANT TO HELP ME WITH? YOU ARE HERE TO DO JUST THAT, RIGHT? YOU'RE NOT SOME IMBECILE HERE LOOKING FOR A LOVE POTION?]], + answers = { + {"[Indicate the "..e[1].name..".]", jump="list", + cond = function(npc, player) return not q:isCompleted(e[1].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[1].start) + q:update_needed_ingredients(player) + end, + on_select=function(npc, player) + local o = art_list[e[1].id] + o:identify(true) + game.tooltip_x, game.tooltip_y = 1, 1 + game.tooltip:displayAtMap(nil, nil, game.w, game.h, "#GOLD#"..o.name.."#LAST#\n"..tostring(o:getDesc())) + end, + }, + {"[Indicate the "..e[2].name..".]", jump="list", + cond = function(npc, player) return not q:isCompleted(e[2].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[2].start) + q:update_needed_ingredients(player) + end, + on_select=function(npc, player) + local o = art_list[e[2].id] + o:identify(true) + game.tooltip_x, game.tooltip_y = 1, 1 + game.tooltip:displayAtMap(nil, nil, game.w, game.h, "#GOLD#"..o.name.."#LAST#\n"..tostring(o:getDesc())) + end, + }, + {"[Indicate the "..e[3].name..".]", jump="list", + cond = function(npc, player) return not q:isCompleted(e[3].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[3].start) + q:update_needed_ingredients(player) + end, + on_select=function(npc, player) + local o = art_list[e[3].id] + o:identify(true) + game.tooltip_x, game.tooltip_y = 1, 1 + game.tooltip:displayAtMap(nil, nil, game.w, game.h, "#GOLD#"..o.name.."#LAST#\n"..tostring(o:getDesc())) + end, + }, + {"[leave]"}, + } +} + +newChat{ id="list", + text = [[TAKE THIS LIST OF INGREDIENTS, AND HURRY THE HELL UP.]], + answers = { + {"I'LL BE OFF."}, + } +} + +-- If the elixir got made while you were out: +newChat{ id="poached", + text = [[TOO SLOW, HAMBRAIN. ELIXIR'S MADE ALREADY, AND SOMEBODY ELSE WALKED OFF WITH THE REWARD. IF YOU'RE FEELING SORRY FOR YOURSELF, ASK WHETHER THIS IS MORE OR LESS PLEASANT THAN GETTING APPRECIABLE CHUNKS OF YOUR ANATOMY BLASTED CLEAN OFF YOUR BODY THIS MORNING. THAT'S RIGHT. BYE.]], + answers = { + {"Hrmph.", + cond = function(npc, player) return empty_handed(npc, player, 1) end, + action = function(npc, player) + q:remove_ingredients(player, e[1].short_name, 1) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[1].almost) + q:update_needed_ingredients(player) + end, + }, + {"Hrmph.", + cond = function(npc, player) return empty_handed(npc, player, 2) end, + action = function(npc, player) + q:remove_ingredients(player, e[2].short_name, 2) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[2].almost) + q:update_needed_ingredients(player) + end, + }, + {"Hrmph.", + cond = function(npc, player) return empty_handed(npc, player, 3) end, + action = function(npc, player) + q:remove_ingredients(player, e[3].short_name, 3) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[3].almost) + q:update_needed_ingredients(player) + end, + }, + } +} + +end + +return "welcome" diff --git a/game/modules/tome/data/chats/alchemist-last-hope.lua b/game/modules/tome/data/chats/alchemist-last-hope.lua new file mode 100644 index 0000000000000000000000000000000000000000..1d45de28348399ec4cdd051d4452ae18c43de8ed --- /dev/null +++ b/game/modules/tome/data/chats/alchemist-last-hope.lua @@ -0,0 +1,521 @@ +-- ToME - Tales of Maj'Eyal +-- Copyright (C) 2009, 2010 Nicolas Casalini +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +-- Nicolas Casalini "DarkGod" +-- darkgod@te4.org + +local art_list = mod.class.Object:loadList("/data/general/objects/brotherhood-artifacts.lua") +local ing_list = mod.class.Object:loadList("/data/general/objects/elixir-ingredients.lua") +local alchemist_num = 4 +local other_alchemist_nums = {1, 2, 3} +local q = game.player:hasQuest("brotherhood-of-alchemists") +local final_reward = "TAINT_TELEPATHY" +local e = { + { + short_name = "brawn", + name = "elixir of brawn", + id = "ELIXIR_BRAWN", + start = "brawn_start", + almost = "brawn_almost_done", + full = "elixir_of_brawn", + full_2 = "elixir_of_stoneskin", + full_3 = "elixir_of_foundations", + poached = "brawn_poached", + }, + { + short_name = "stoneskin", + name = "elixir of stoneskin", + id = "ELIXIR_STONESKIN", + start = "stoneskin_start", + almost = "stoneskin_almost_done", + full = "elixir_of_stoneskin", + full_2 = "elixir_of_brawn", + full_3 = "elixir_of_foundations", + poached = "stoneskin_poached", + }, + { + short_name = "foundations", + name = "elixir of foundations", + id = "ELIXIR_FOUNDATIONS", + start = "foundations_start", + almost = "foundations_almost_done", + full = "elixir_of_foundations", + full_2 = "elixir_of_brawn", + full_3 = "elixir_of_stoneskin", + poached = "foundations_poached", + }, +} + +--cond function for turning in non-final elixirs +--checks that player has quest and elixir ingredients, hasn't completed it yet, has started that elixir, and hasn't completed both other elixirs since that would make this the last one: +local function turn_in(npc, player, n) -- n is the index of the elixir we're checking on + return q and q:check_ingredients(player, e[n].short_name, n) -- make sure we have the quest and the elixir's ingredients + and not q:isCompleted(e[n].almost) and not q:isCompleted(e[n].full) --make sure we haven't finished the quest already + and q:isCompleted(e[n].start) --make sure we've been given the task to make this elixir + and not (q:isCompleted(e[n].full_2) and q:isCompleted(e[n].full_3)) --make sure we haven't already finished both the other elixirs, since that would make this the final one which requires a special dialog. +end + +--cond function for turning in final elixir with index n +--checks that player has quest and elixir ingredients, hasn't completed it yet, has started that elixir, and both the other elixirs are done +local function turn_in_final(npc, player, n) -- n is the index of the elixir we're checking on + return q and q:check_ingredients(player, e[n].short_name, n) -- make sure we have the quest and the elixir's ingredients + and not q:isCompleted(e[n].almost) and not q:isCompleted(e[n].full) --make sure we haven't finished the quest already + and q:isCompleted(e[n].start) --make sure we've been given the task to make this elixir + and (q:isCompleted(e[n].full_2) and q:isCompleted(e[n].full_3)) --make sure the other two elixirs are made, thus making this the final turn-in +end + +--cond function for turning in poached (completed by somebody besides you) elixirs +--checks that the player has the quest and elixir ingredients, hasn't turned it in, the task is complete anyway, the task has actually been started, and that it's been poached +local function turn_in_poached(npc, player, n) -- n is the index of the elixir we're checking on + return q and q:check_ingredients(player, e[n].short_name, n) -- make sure we have the quest and the elixir's ingredients + and not q:isCompleted(e[n].almost) --make sure we haven't turned it in already + and q:isCompleted(e[n].full) --make sure that, even though we haven't turned it in, the elixir has been made for this alchemist + and q:isCompleted(e[n].start) --make sure we've been given the task to make this elixir + and q:isCompleted(e[n].poached) --make sure this task has been poached +end + +local function more_aid(npc, player) + return not (q:isCompleted(e[1].full) and q:isCompleted(e[2].full) and q:isCompleted(e[3].full)) --make sure all the elixirs aren't already made + --Next, for each of the three elixirs, make sure it's not the case that: + --1) we're either working on it or... 2) we've started (but not finished) the elixir and it got poached. + and not ((q:isCompleted(e[1].start) and not q:isCompleted(e[1].full)) or (q:isCompleted(e[1].start) and q:isCompleted(e[1].poached) and q:isCompleted(e[1].almost)) ) + and not ((q:isCompleted(e[2].start) and not q:isCompleted(e[2].full)) or (q:isCompleted(e[2].start) and q:isCompleted(e[2].poached) and q:isCompleted(e[2].almost)) ) + and not ((q:isCompleted(e[3].start) and not q:isCompleted(e[3].full)) or (q:isCompleted(e[3].start) and q:isCompleted(e[3].poached) and q:isCompleted(e[3].almost)) ) +end + +local function give_bits(npc, player, n) -- n is the index of the elixir we're checking on + return q and q:check_ingredients(player, e[n].short_name) -- make sure we have the quest and the elixir's ingredients + and q:isCompleted(e[n].start) --make sure we've started the task + and not q:isCompleted(e[n].full) --... but not finished +end + +local function empty_handed(npc, player, n) -- n is the index of the elixir we're checking on + return q and q:check_ingredients(player, e[n].short_name, n) -- make sure we have the quest and the elixir's ingredients + and q:isCompleted(e[n].start) --make sure we've started the task + and not q:isCompleted(e[n].almost) --make sure we've not turned the stuff in before... + and q:isCompleted(e[n].full) --... and yet the elixir is already made (poached!) +end + +--Make the alchemist's reaction to your turn-in vary depending on whether he lost. +local function alchemist_reaction_complete(npc, player, lose, other_alch, other_elixir) + if lose == true then + return ([[Damn it all. You're too late. %s has already finished. But I suppose you did your best, so I'll take these and keep my end of the bargian.]]):format(other_alch) + else + return ([[Great work! And you're still in one piece, I see. Always nice. I feel the same way after safely brewing up a particularly tricky mixture. I've near blown my face clean off several times. Oh, while you were gone a little bird told me that %s has managed to create a %s. Don't let him finish before me!]]):format(other_alch, other_elixir) + end +end + +if not q or (q and not q:isCompleted(e[1].start) and not q:isCompleted(e[2].start) and not q:isCompleted(e[3].start)) then + +-- Here's the dialog that pops up if the player has never worked for this alchemist before: +newChat{ id="welcome", + text = [[#LIGHT_GREEN#*A dwarf in stained, battered mail armor opens the door.*#WHITE# +Say, you interested in dismembering stuff and getting paid?]], + answers = { + {"Always.", jump="ominous"}, + {"[leave]"}, + } +} + +newChat{ id="ominous", + text = [[By the corpses of the gods, I love adventurers. Was about to become one myself when it suddenly hit me. And by "it" I mean "my wife." Har!]], + answers = { + {"What do you propose?", jump="proposal"}, + } +} + +newChat{ id="proposal", + text = [[I propose that I give you a list of monster parts to fetch, then you go and fetch them, then I make some blindingly amazing brews with said monster parts, then I get accepted into the Brotherhood of Alchemists.]], + answers = { + {"Sounds like a plan.", jump="help"}, + } +} + +newChat{ id="help", + text = [[I make excellent plans. And brews, which the Brotherhood will no doubt make me call 'elixirs' once I'm in. And I'll obey, because they have ways of getting what they want. Now, where were we?]], + answers = { + {"Aiding you with getting into some Brotherhood. What's in it for me?", jump="competition"}, + } +} + +newChat{ id="competition", + text = [[Oh, easy. You get a swig of each brew, of course. They'll put hair on your chest, and possibly your eyelids and fingernails. And, if your aid proves the deciding factor, then I've got a real treat for you: perhaps the last Taint of Telepathy left in Maj'Eyal.]], + answers = { + {"I accept.", jump="choice", action = function(npc, player) player:grantQuest("brotherhood-of-alchemists") end,}, + {"I cannot aid you at this time."}, + } +} + +newChat{ id="choice", + text = [[One last thing. There's a few other fellows angling for the same slot in the Brotherhood that I am. They're not going to be sitting on their hands while we're at work here, so best move quick-like. Now, which of these do you want to help me with first: the Brew of Brawn, the Brew of Stoneskin, or the Brew of Foundations? Or Elixirs, rather. Not Brews. Best get in the habit now, I suppose.]], + answers = { + {"The "..e[1].name..".", jump="list", + cond = function(npc, player) return not game.player:hasQuest("brotherhood-of-alchemists"):isCompleted(e[1].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[1].start) + game.player:hasQuest("brotherhood-of-alchemists"):update_needed_ingredients(player) + end, + on_select=function(npc, player) + local o = art_list[e[1].id] + o:identify(true) + game.tooltip_x, game.tooltip_y = 1, 1 + game.tooltip:displayAtMap(nil, nil, game.w, game.h, "#GOLD#"..o.name.."#LAST#\n"..tostring(o:getDesc())) + end, + }, + {"The "..e[2].name..".", jump="list", + cond = function(npc, player) return not game.player:hasQuest("brotherhood-of-alchemists"):isCompleted(e[2].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[2].start) + game.player:hasQuest("brotherhood-of-alchemists"):update_needed_ingredients(player) + end, + on_select=function(npc, player) + local o = art_list[e[2].id] + o:identify(true) + game.tooltip_x, game.tooltip_y = 1, 1 + game.tooltip:displayAtMap(nil, nil, game.w, game.h, "#GOLD#"..o.name.."#LAST#\n"..tostring(o:getDesc())) + end, + }, + {"The "..e[3].name..".", jump="list", + cond = function(npc, player) return not game.player:hasQuest("brotherhood-of-alchemists"):isCompleted(e[3].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[3].start) + game.player:hasQuest("brotherhood-of-alchemists"):update_needed_ingredients(player) + end, + on_select=function(npc, player) + local o = art_list[e[3].id] + o:identify(true) + game.tooltip_x, game.tooltip_y = 1, 1 + game.tooltip:displayAtMap(nil, nil, game.w, game.h, "#GOLD#"..o.name.."#LAST#\n"..tostring(o:getDesc())) + end, + }, + {"[leave]"}, + } +} + +newChat{ id="list", + text = [[Right, here's the list. Hurry back.]], + answers = { + {"I'll be off."}, + } +} + +-- Quest is complete; nobody answers the door +elseif q and q:isStatus(q.DONE) then +newChat{ id="welcome", + text = [[#LIGHT_GREEN#*The door is locked and nobody responds to your knocks*#WHITE#]], + answers = { + {"[Leave]"}, + } +} + + +else -- Here's the dialog that pops up if the player *has* worked with this alchemist before (either done quests or is in the middle of one): + +local other_alch, other_elixir, player_loses, alch_picked, e_picked = q:competition(player, other_alchemist_nums) + +newChat{ id="welcome", + text = [[#LIGHT_GREEN#*The mailed dwarf opens his door.*#WHITE# +Aha, my favorite adventurer.]], + answers = { + -- If not the final elixir: + {"I've returned with the ingredients for the "..e[1].name..".", jump="complete", + cond = function(npc, player) return turn_in(npc, player, 1) end, + action = function(npc, player) + q:on_turnin(player, alch_picked, e_picked, false) + end, + }, + {"I've returned with the ingredients for the "..e[2].name..".", jump="complete", + cond = function(npc, player) return turn_in(npc, player, 2) end, + action = function(npc, player) + q:on_turnin(player, alch_picked, e_picked, false) + end, + }, + {"I've returned with the ingredients for the "..e[3].name..".", jump="complete", + cond = function(npc, player) return turn_in(npc, player, 3) end, + action = function(npc, player) + q:on_turnin(player, alch_picked, e_picked, false) + end, + }, + + -- If the final elixir: + {"I've returned with the ingredients for the "..e[1].name..".", jump="totally-complete", + cond = function(npc, player) return turn_in_final(npc, player, 1) end, + }, + {"I've returned with the ingredients for the "..e[2].name..".", jump="totally-complete", + cond = function(npc, player) return turn_in_final(npc, player, 2) end, + }, + {"I've returned with the ingredients for the "..e[3].name..".", jump="totally-complete", + cond = function(npc, player) return turn_in_final(npc, player, 3) end, + }, + + -- If the elixir got made while you were out: + {"I've returned with the ingredients for the "..e[1].name..".", jump="poached", + cond = function(npc, player) return turn_in_poached(npc, player, 1) end, + }, + {"I've returned with the ingredients for the "..e[2].name..".", jump="poached", + cond = function(npc, player) return turn_in_poached(npc, player, 2) end, + }, + {"I've returned with the ingredients for the "..e[3].name..".", jump="poached", + cond = function(npc, player) return turn_in_poached(npc, player, 3) end, + }, + + --Don't let player work on multiple elixirs for the same alchemist. + --See comments in more_aid function above for all the gory detail + {"I've come to offer more aid.", jump="choice", + cond = function(npc, player) return more_aid(npc, player) end, + }, + {"[leave]"}, + } +} + +--Not final elixir: +newChat{ id="complete", + text = alchemist_reaction_complete(npc, player, player_loses, other_alch, other_elixir), + answers = { + {"[Give him the monster bits.]", jump="complete2", + cond = function(npc, player) return give_bits(npc, player, 1) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[1].almost) + q:remove_ingredients(player, e[1].short_name, 1) + end + }, + {"[Give him the monster bits.]", jump="complete2", + cond = function(npc, player) return give_bits(npc, player, 2) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[2].almost) + q:remove_ingredients(player, e[2].short_name, 2) + end + }, + {"[Give him the monster bits.]", jump="complete2", + cond = function(npc, player) return give_bits(npc, player, 3) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[3].almost) + q:remove_ingredients(player, e[3].short_name, 3) + end + }, +-- {"Sorry, it seems I lack some stuff. I will be back."}, + } +} + +--Final elixir: +newChat{ id="totally-complete", + text = [[#LIGHT_GREEN#*He gleefully claps you on the shoulder.*#WHITE# +Ha ha! This is the last one! Stire and Marus and that damned hermit can suck on my beard! And so can my wife! YES, I KNOW YOU CAN HEAR ME. Good work, friend. Let's have them.]], + answers = { + {"[Give him the monster bits]", jump="totally-complete2", + cond = function(npc, player) return give_bits(npc, player, 1) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[1].almost) + q:remove_ingredients(player, e[1].short_name, 1) + end + }, + {"[Give him the monster bits]", jump="totally-complete2", + cond = function(npc, player) return give_bits(npc, player, 2) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[2].almost) + q:remove_ingredients(player, e[2].short_name, 2) + end + }, + {"[Give him the monster bits]", jump="totally-complete2", + cond = function(npc, player) return give_bits(npc, player, 3) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[3].almost) + q:remove_ingredients(player, e[3].short_name, 3) + end + }, + --{"Sorry, it seems I lack some stuff. I will be back."}, + } +} + +--Not final elixir: +newChat{ id="complete2", + text = [[Give me an hour or so to make with the alchemy. Don't go anywhere.]], + answers = { + {"[Wait]", jump="complete3"}, + + } +} + +--Final Elixir: +newChat{ id="totally-complete2", + text = [[I'd invite you inside while you wait, but the she-dwarf's in there, and I've grown fond of you.]], + answers = { + {"[Wait]", jump="totally-complete3"}, + + } +} + +--Not final elixir: +newChat{ id="complete3", + text = [[#LIGHT_GREEN#*The dwarf finally returns with a vial.*#WHITE# +It tastes like Urh'Rok's own piss, but gets the job done.]], + answers = { + {"Thank you. I'll be off.", + cond = function(npc, player) return q and q:isCompleted(e[1].almost) and not q:isCompleted(e[1].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[1].full) + q:reward(player, e[1].id) + q:update_needed_ingredients(player) + end + }, + {"Thank you. I'll be off.", + cond = function(npc, player) return q and q:isCompleted(e[2].almost) and not q:isCompleted(e[2].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[2].full) + q:reward(player, e[2].id) + q:update_needed_ingredients(player) + end + }, + {"Thank you. I'll be off.", + cond = function(npc, player) return q and q:isCompleted(e[3].almost) and not q:isCompleted(e[3].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[3].full) + q:reward(player, e[3].id) + q:update_needed_ingredients(player) + end + }, + } +} + +--Final elixir: +newChat{ id="totally-complete3", + text = [[#LIGHT_GREEN#*The dwarf finally returns with a vial and a small pouch.*#WHITE# +I put a bit of the good stuff in this one, though it won't do you any favors tomorrow morning. And careful with that Taint of Telepathy, especially if the wife answers the door the next time you knock. Har!]], + answers = { + {"Thank you. I'll be off.", + cond = function(npc, player) return q and q:isCompleted(e[1].almost) and not q:isCompleted(e[1].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[1].full) + q:reward(player, e[1].id) + q:reward(player, final_reward) + q:update_needed_ingredients(player) + q:winner_is(player, alchemist_num) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.DONE) + + end + }, + {"Thank you. I'll be off.", + cond = function(npc, player) return q and q:isCompleted(e[2].almost) and not q:isCompleted(e[2].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[2].full) + q:reward(player, e[2].id) + q:reward(player, final_reward) + q:update_needed_ingredients(player) + q:winner_is(player, alchemist_num) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.DONE) + end + }, + {"Thank you. I'll be off.", + cond = function(npc, player) return q and q:isCompleted(e[3].almost) and not q:isCompleted(e[3].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[3].full) + q:reward(player, e[3].id) + q:reward(player, final_reward) + q:update_needed_ingredients(player) + q:winner_is(player, alchemist_num) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.DONE) + end + }, + } +} + +newChat{ id="choice", + text = [[Bless you adventurers. Which will it be?]], + answers = { + {"The "..e[1].name..".", jump="list", + cond = function(npc, player) return not q:isCompleted(e[1].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[1].start) + q:update_needed_ingredients(player) + end, + on_select=function(npc, player) + local o = art_list[e[1].id] + o:identify(true) + game.tooltip_x, game.tooltip_y = 1, 1 + game.tooltip:displayAtMap(nil, nil, game.w, game.h, "#GOLD#"..o.name.."#LAST#\n"..tostring(o:getDesc())) + end, + }, + {"The "..e[2].name..".", jump="list", + cond = function(npc, player) return not q:isCompleted(e[2].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[2].start) + q:update_needed_ingredients(player) + end, + on_select=function(npc, player) + local o = art_list[e[2].id] + o:identify(true) + game.tooltip_x, game.tooltip_y = 1, 1 + game.tooltip:displayAtMap(nil, nil, game.w, game.h, "#GOLD#"..o.name.."#LAST#\n"..tostring(o:getDesc())) + end, + }, + {"The "..e[3].name..".", jump="list", + cond = function(npc, player) return not q:isCompleted(e[3].full) end, + action = function(npc, player) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[3].start) + q:update_needed_ingredients(player) + end, + on_select=function(npc, player) + local o = art_list[e[3].id] + o:identify(true) + game.tooltip_x, game.tooltip_y = 1, 1 + game.tooltip:displayAtMap(nil, nil, game.w, game.h, "#GOLD#"..o.name.."#LAST#\n"..tostring(o:getDesc())) + end, + }, + {"[leave]"}, + } +} + +newChat{ id="list", + text = [[Here's a list of the creature bits I need. Good luck with the murdering!]], + answers = { + {"I'll be off."}, + } +} + +-- If the elixir got made while you were out: +newChat{ id="poached", + text = [[Er, it seems that while you were out, somebody else managed to bring me the ingredients. I've got no reward for you! Sorry about that, but when time is of the essence, 'first come, first served' is the only sensible policy.]], + answers = { + {"Hrmph.", + cond = function(npc, player) return empty_handed(npc, player, 1) end, + action = function(npc, player) + q:remove_ingredients(player, e[1].short_name, 1) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[1].almost) + q:update_needed_ingredients(player) + end, + }, + {"Hrmph.", + cond = function(npc, player) return empty_handed(npc, player, 2) end, + action = function(npc, player) + q:remove_ingredients(player, e[2].short_name, 2) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[2].almost) + q:update_needed_ingredients(player) + end, + }, + {"Hrmph.", + cond = function(npc, player) return empty_handed(npc, player, 3) end, + action = function(npc, player) + q:remove_ingredients(player, e[3].short_name, 3) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, e[3].almost) + q:update_needed_ingredients(player) + end, + }, + } +} + +end + +return "welcome" diff --git a/game/modules/tome/data/damage_types.lua b/game/modules/tome/data/damage_types.lua index 37c7426d31be0d781c15d02ea1ae9b0ef227e642..e8ba8470c2521c4669d17afee8b8bd0e7866a499 100644 --- a/game/modules/tome/data/damage_types.lua +++ b/game/modules/tome/data/damage_types.lua @@ -1369,3 +1369,19 @@ newDamageType{ end end, } + +newDamageType{ + name = "entangle", type = "ENTANGLE", + projector = function(src, x, y, type, dam) + DamageType:get(DamageType.PHYSICAL).projector(src, x, y, DamageType.PHYSICAL, dam/3) + DamageType:get(DamageType.NATURE).projector(src, x, y, DamageType.NATURE, 2*dam/3) + local target = game.level.map(x, y, Map.ACTOR) + if target then + if target:canBe("pin") then + target:setEffect(target.EFF_PINNED, 5, {}) + else + game.logSeen(target, "%s resists!", target.name:capitalize()) + end + end + end, +} diff --git a/game/modules/tome/data/general/encounters/maj-eyal.lua b/game/modules/tome/data/general/encounters/maj-eyal.lua index 37787a9c413402e1475e1a6b28e5cbe7a6b5d403..d54e675c0c6d2ea07aa385059f019f4e1d00ec77 100644 --- a/game/modules/tome/data/general/encounters/maj-eyal.lua +++ b/game/modules/tome/data/general/encounters/maj-eyal.lua @@ -231,3 +231,25 @@ newEntity{ return true end, } + +newEntity{ + name = "Agrimley the Hermit", + type = "harmless", subtype = "special", unique = true, + immediate = {"world-encounter", "maj-eyal"}, + -- Spawn the hermit + on_encounter = function(self, who) + local x, y = self:findSpot(who) + if not x then return end + + local g = mod.class.WorldNPC.new{ + name="Agrimley the Hermit", + type="humanoid", subtype="elf", faction="angolwen", + display='@', color=colors.BLUE, + can_talk = "alchemist-hermit", + unit_power = 300, + } + g:resolve() g:resolve(nil, true) + game.zone:addEntity(game.level, g, "actor", x, y) + return true + end, +} diff --git a/game/modules/tome/data/general/npcs/ant.lua b/game/modules/tome/data/general/npcs/ant.lua index d5e39e230e99fd427127a2a10c5bdaaf2900ec3b..7100869877980e7599163965621c35b28370f44f 100644 --- a/game/modules/tome/data/general/npcs/ant.lua +++ b/game/modules/tome/data/general/npcs/ant.lua @@ -121,6 +121,12 @@ newEntity{ base = "BASE_NPC_ANT", combat = { damtype=DamageType.ICE }, combat_armor = 5, combat_def = 5, on_melee_hit = {[DamageType.ICE]=5}, + on_die = function(self, who) + local part = "FROST_ANT_STINGER" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } newEntity{ base = "BASE_NPC_ANT", diff --git a/game/modules/tome/data/general/npcs/aquatic_critter.lua b/game/modules/tome/data/general/npcs/aquatic_critter.lua index 9cf38c93e793887a303904486bf08ac25e1eabdc..0c0066fda61e3b413d01a679128104c5984b37a6 100644 --- a/game/modules/tome/data/general/npcs/aquatic_critter.lua +++ b/game/modules/tome/data/general/npcs/aquatic_critter.lua @@ -56,6 +56,12 @@ newEntity{ base = "BASE_NPC_AQUATIC_CRITTER", autolevel = "warriormage", combat = {damtype=DamageType.LIGHTNING}, resolvers.talents{ [Talents.T_CHAIN_LIGHTNING]=3, [Talents.T_LIGHTNING]=3 }, + on_die = function(self, who) + local part = "ELECTRIC_EEL_TAIL" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } newEntity{ base = "BASE_NPC_AQUATIC_CRITTER", @@ -87,6 +93,12 @@ newEntity{ base = "BASE_NPC_AQUATIC_CRITTER", level_range = {1, nil}, exp_worth = 1, rarity = 1, resolvers.talents{ [Talents.T_GRAB]=3, }, + on_die = function(self, who) + local part = "SQUID_INK" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } newEntity{ base = "BASE_NPC_AQUATIC_CRITTER", @@ -96,4 +108,10 @@ newEntity{ base = "BASE_NPC_AQUATIC_CRITTER", rarity = 2, stats = { mag=30, }, resolvers.talents{ [Talents.T_GRAB]=3, [Talents.T_BLINDING_INK]=3, }, + on_die = function(self, who) + local part = "SQUID_INK" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } diff --git a/game/modules/tome/data/general/npcs/bear.lua b/game/modules/tome/data/general/npcs/bear.lua index 9e05479620f06104ae38272084a11bc18b936e1b..ed9e0ce864797b6273a187c1d634e729bb7f7f5f 100644 --- a/game/modules/tome/data/general/npcs/bear.lua +++ b/game/modules/tome/data/general/npcs/bear.lua @@ -43,6 +43,12 @@ newEntity{ resolvers.tmasteries{ ["technique/other"]=0.25 }, resists = { [DamageType.FIRE] = 20, [DamageType.COLD] = 20, [DamageType.POISON] = 20 }, + on_die = function(self, who) + local part = "BEAR_PAW" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } newEntity{ base = "BASE_NPC_BEAR", diff --git a/game/modules/tome/data/general/npcs/bone-giant.lua b/game/modules/tome/data/general/npcs/bone-giant.lua index 223fd9838e90e5fbcd5445915f74fae70d9b3385..484d3ce468ccc5bcede9f12f51b402fd5f71dbd5 100644 --- a/game/modules/tome/data/general/npcs/bone-giant.lua +++ b/game/modules/tome/data/general/npcs/bone-giant.lua @@ -51,6 +51,12 @@ newEntity{ stun_immune = 1, see_invisible = resolvers.mbonus(15, 5), undead = 1, + on_die = function(self, who) + local part = "BONE_GOLEM_DUST" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } newEntity{ base = "BASE_NPC_BONE_GIANT", diff --git a/game/modules/tome/data/general/npcs/canine.lua b/game/modules/tome/data/general/npcs/canine.lua index 5b455c1bcbb7133b516c72d35afeb233afadd519..1bc430f34dd468ac2a024c5bb833f589b428e64e 100644 --- a/game/modules/tome/data/general/npcs/canine.lua +++ b/game/modules/tome/data/general/npcs/canine.lua @@ -94,6 +94,12 @@ newEntity{ base = "BASE_NPC_CANINE", combat_armor = 5, combat_def = 7, combat = { dam=resolvers.levelup(10, 1, 1), atk=17, apr=5 }, resolvers.talents{ [Talents.T_HOWL]=3, }, + on_die = function(self, who) + local part = "WARG_CLAW" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } newEntity{ base = "BASE_NPC_CANINE", diff --git a/game/modules/tome/data/general/npcs/cold-drake.lua b/game/modules/tome/data/general/npcs/cold-drake.lua index 11d909ea2b00a3608e7540f9ebf4dc6915221549..983b5a956ea8b14ce831dd9bbd6b2395084d5ff5 100644 --- a/game/modules/tome/data/general/npcs/cold-drake.lua +++ b/game/modules/tome/data/general/npcs/cold-drake.lua @@ -104,4 +104,10 @@ newEntity{ base = "BASE_NPC_COLD_DRAKE", [Talents.T_ICY_SKIN]={base=3, every=5}, [Talents.T_ICE_BREATH]={base=5, every=4}, }, + on_die = function(self, who) + local part = "ICE_WYRM_TOOTH" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } diff --git a/game/modules/tome/data/general/npcs/crystal.lua b/game/modules/tome/data/general/npcs/crystal.lua index 5ddaf9c2e4bb85786393c9b5a37dc13d8e351538..98224a658760a92c684e6dc430387fa1bb42e95a 100644 --- a/game/modules/tome/data/general/npcs/crystal.lua +++ b/game/modules/tome/data/general/npcs/crystal.lua @@ -79,6 +79,12 @@ newEntity{ base = "BASE_NPC_CRYSTAL", resolvers.talents{ [Talents.T_FLAME]={base=1, every=7, max=5}, } + on_die = function(self, who) + local part = "RED_CRYSTAL_SHARD" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } newEntity{ base = "BASE_NPC_CRYSTAL", diff --git a/game/modules/tome/data/general/npcs/faeros.lua b/game/modules/tome/data/general/npcs/faeros.lua index 0bc89774ba715520ff45bcb5a84f7532e339d7d7..fb2d80c1ac5b0848f3c0e16441a0c7404c71ff64 100644 --- a/game/modules/tome/data/general/npcs/faeros.lua +++ b/game/modules/tome/data/general/npcs/faeros.lua @@ -45,6 +45,12 @@ newEntity{ no_breath = 1, poison_immune = 1, disease_immune = 1, + on_die = function(self, who) + local part = "FAEROS_ASH" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } newEntity{ base = "BASE_NPC_FAEROS", diff --git a/game/modules/tome/data/general/npcs/fire-drake.lua b/game/modules/tome/data/general/npcs/fire-drake.lua index fd28fcb334b6361ab2ed7aa614569ef15e1a6ef4..54820fcbb5f78a852ccecff91746c7ba922b2cc1 100644 --- a/game/modules/tome/data/general/npcs/fire-drake.lua +++ b/game/modules/tome/data/general/npcs/fire-drake.lua @@ -108,4 +108,10 @@ newEntity{ base = "BASE_NPC_FIRE_DRAKE", [Talents.T_FIRE_BREATH]={base=5, every=4}, [Talents.T_DEVOURING_FLAME]={base=5, every=6}, }, + on_die = function(self, who) + local part = "FIRE_WYRM_SALIVA" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } diff --git a/game/modules/tome/data/general/npcs/ghoul.lua b/game/modules/tome/data/general/npcs/ghoul.lua index b19c8e3b39c652a0f90b43645ef74bd6f6fac586..6ad857bf67ed4fbe1ad5e2025e314c17766a6176 100644 --- a/game/modules/tome/data/general/npcs/ghoul.lua +++ b/game/modules/tome/data/general/npcs/ghoul.lua @@ -44,6 +44,12 @@ newEntity{ blind_immune = 1, see_invisible = 2, undead = 1, + on_die = function(self, who) + local part = "GHOUL_FLESH" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } newEntity{ base = "BASE_NPC_GHOUL", diff --git a/game/modules/tome/data/general/npcs/horror.lua b/game/modules/tome/data/general/npcs/horror.lua index 7195236248526c475f1afb71b8a072b5c2daf956..93261ae9d43431e5b805fd93ad4c771a189fd075 100644 --- a/game/modules/tome/data/general/npcs/horror.lua +++ b/game/modules/tome/data/general/npcs/horror.lua @@ -204,7 +204,12 @@ newEntity{ base = "BASE_NPC_HORROR", end, -- Needs an on death affect that kills off any remaining eyes. - on_die = function(self, src) + on_die = function(self, src, who) + local part = "HEADLESS_HORROR_HEART" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + local nb = 0 for eye, _ in pairs(self.eyes) do if not eye.dead then eye:die(src) nb = nb + 1 end @@ -389,6 +394,12 @@ newEntity{ base = "BASE_NPC_HORROR", make_escort = { {type="horror", subtype="eldritch", name="luminous horror", number=2, no_subescort=true}, }, + on_die = function(self, who) + local part = "LUMINOUS_HORROR_DUST" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } newEntity{ base = "BASE_NPC_HORROR", diff --git a/game/modules/tome/data/general/npcs/major-demon.lua b/game/modules/tome/data/general/npcs/major-demon.lua index be0dd34510832af1aef9845bd1c5bf5242902f0a..4b02ba4d4f01e553792162068af1b94357e4d43d 100644 --- a/game/modules/tome/data/general/npcs/major-demon.lua +++ b/game/modules/tome/data/general/npcs/major-demon.lua @@ -43,6 +43,12 @@ newEntity{ demon = 1, resolvers.inscriptions(1, "rune"), + on_die = function(self, who) + local part = "GREATER_DEMON_BILE" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } newEntity{ base = "BASE_NPC_MAJOR_DEMON", diff --git a/game/modules/tome/data/general/npcs/minor-demon.lua b/game/modules/tome/data/general/npcs/minor-demon.lua index 0726cb0e26e448d95967f19469e29a0f093718f0..9f41e724c029e12e93f406b280be34528a952f8c 100644 --- a/game/modules/tome/data/general/npcs/minor-demon.lua +++ b/game/modules/tome/data/general/npcs/minor-demon.lua @@ -84,6 +84,12 @@ newEntity{ base = "BASE_NPC_DEMON", make_escort = { {type="demon", subtype="minor", name="wretchling", number=rng.range(1, 4), no_subescort=true}, }, + on_die = function(self, who) + local part = "WRETCHLING_EYE" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } newEntity{ base = "BASE_NPC_DEMON", diff --git a/game/modules/tome/data/general/npcs/minotaur.lua b/game/modules/tome/data/general/npcs/minotaur.lua index b2f78f16ee222e31a30567f73d672ef8fbb21121..2c49bab7aaac436b967144f2cecd19decc390837 100644 --- a/game/modules/tome/data/general/npcs/minotaur.lua +++ b/game/modules/tome/data/general/npcs/minotaur.lua @@ -49,6 +49,12 @@ newEntity{ stats = { str=15, dex=12, mag=6, cun=12, con=15 }, resolvers.tmasteries{ ["technique/2hweapon-offense"]=0.3, ["technique/2hweapon-cripple"]=0.3, ["technique/combat-training"]=0.3, }, + on_die = function(self, who) + local part = "MINOTAUR_NOSE" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } newEntity{ base = "BASE_NPC_MINOTAUR", diff --git a/game/modules/tome/data/general/npcs/multihued-drake.lua b/game/modules/tome/data/general/npcs/multihued-drake.lua index 76dc40979d2f4425baa817404f769ae509db75d0..c8721faa4772911bed11c283493d8949731d2f53 100644 --- a/game/modules/tome/data/general/npcs/multihued-drake.lua +++ b/game/modules/tome/data/general/npcs/multihued-drake.lua @@ -130,6 +130,12 @@ newEntity{ base = "BASE_NPC_MULTIHUED_DRAKE", [Talents.T_LIGHTNING_BREATH]={base=9, every=4}, [Talents.T_ACID_BREATH]={base=9, every=4}, }, + on_die = function(self, who) + local part = "MULTIHUED_WYRM_SCALE" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } newEntity{ base = "BASE_NPC_MULTIHUED_DRAKE", diff --git a/game/modules/tome/data/general/npcs/mummy.lua b/game/modules/tome/data/general/npcs/mummy.lua index 14feb8663e0f5486276d724639202a8442369d35..fa34a845d825605dbbd9819c853dc6c85d24ca09 100644 --- a/game/modules/tome/data/general/npcs/mummy.lua +++ b/game/modules/tome/data/general/npcs/mummy.lua @@ -46,4 +46,10 @@ newEntity{ blind_immune = 1, see_invisible = 4, undead = 1, + on_die = function(self, who) + local part = "MUMMY_BONE" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } diff --git a/game/modules/tome/data/general/npcs/naga.lua b/game/modules/tome/data/general/npcs/naga.lua index a13e2da826693c5ab3533b097118f89bd066b39d..f78bf5d60d9dcba6976b2776ed88908f38661e18 100644 --- a/game/modules/tome/data/general/npcs/naga.lua +++ b/game/modules/tome/data/general/npcs/naga.lua @@ -46,6 +46,12 @@ newEntity{ ai = "dumb_talented_simple", ai_state = { ai_move="move_dmap", talent_in=1, }, energy = { mod=1.2 }, stats = { str=15, dex=15, mag=15, con=10 }, + on_die = function(self, who) + local part = "NAGA_TONGUE" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } newEntity{ base = "BASE_NPC_NAGA", diff --git a/game/modules/tome/data/general/npcs/orc-gorbat.lua b/game/modules/tome/data/general/npcs/orc-gorbat.lua index 876cb3299463c9a859812d9a08c45aa06bc16978..b0fa997c09a1b361da32f78c09f610a542beaa66 100644 --- a/game/modules/tome/data/general/npcs/orc-gorbat.lua +++ b/game/modules/tome/data/general/npcs/orc-gorbat.lua @@ -48,4 +48,10 @@ newEntity{ ai = "dumb_talented_simple", ai_state = { ai_move="move_dmap", talent_in=3, }, energy = { mod=1 }, stats = { str=20, dex=8, mag=6, con=16 }, + on_die = function(self, who) + local part = "ORC_HEART" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } diff --git a/game/modules/tome/data/general/npcs/orc-grushnak.lua b/game/modules/tome/data/general/npcs/orc-grushnak.lua index 8f5db0119961d59b16b95d0da92fd9db7e2e88db..b1d9c6cb80aedc42c5721d5f14c69dfea19844a1 100644 --- a/game/modules/tome/data/general/npcs/orc-grushnak.lua +++ b/game/modules/tome/data/general/npcs/orc-grushnak.lua @@ -47,6 +47,12 @@ newEntity{ ai = "dumb_talented_simple", ai_state = { ai_move="move_dmap", talent_in=3, }, energy = { mod=1 }, stats = { str=20, dex=8, mag=6, con=16 }, + on_die = function(self, who) + local part = "ORC_HEART" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } newEntity{ base = "BASE_NPC_ORC_GRUSHNAK", diff --git a/game/modules/tome/data/general/npcs/orc-rak-shor.lua b/game/modules/tome/data/general/npcs/orc-rak-shor.lua index 5c2e3eed524939f91fb07aee786ba4d9a7db18d1..08488cf187496034d5b32c3ba90aa29075a6531a 100644 --- a/game/modules/tome/data/general/npcs/orc-rak-shor.lua +++ b/game/modules/tome/data/general/npcs/orc-rak-shor.lua @@ -46,6 +46,12 @@ newEntity{ ai = "dumb_talented_simple", ai_state = { ai_move="move_dmap", talent_in=1, }, energy = { mod=1 }, stats = { str=20, dex=8, mag=6, con=16 }, + on_die = function(self, who) + local part = "ORC_HEART" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } newEntity{ base = "BASE_NPC_ORC_RAK_SHOR", diff --git a/game/modules/tome/data/general/npcs/orc-vor.lua b/game/modules/tome/data/general/npcs/orc-vor.lua index a46248ba4ab92536fa3a6355018c074371368557..fa9c8254f5fd90235013acba4ad23472b8bd416a 100644 --- a/game/modules/tome/data/general/npcs/orc-vor.lua +++ b/game/modules/tome/data/general/npcs/orc-vor.lua @@ -48,6 +48,12 @@ newEntity{ ai = "dumb_talented_simple", ai_state = { ai_move="move_dmap", talent_in=1, }, energy = { mod=1 }, stats = { str=10, dex=8, mag=20, con=16 }, + on_die = function(self, who) + local part = "ORC_HEART" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } newEntity{ base = "BASE_NPC_ORC_VOR", diff --git a/game/modules/tome/data/general/npcs/orc.lua b/game/modules/tome/data/general/npcs/orc.lua index 99757e3f324887b277883dc171a754b813cc6ded..4d1e63d43fbd2f8540b4fd2e830c5ec5c8296cd9 100644 --- a/game/modules/tome/data/general/npcs/orc.lua +++ b/game/modules/tome/data/general/npcs/orc.lua @@ -44,6 +44,12 @@ newEntity{ energy = { mod=1 }, stats = { str=20, dex=8, mag=6, con=16 }, resolvers.talents{ [Talents.T_WEAPON_COMBAT]={base=1, every=5, max=10}, }, + on_die = function(self, who) + local part = "ORC_HEART" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } newEntity{ base = "BASE_NPC_ORC", diff --git a/game/modules/tome/data/general/npcs/plant.lua b/game/modules/tome/data/general/npcs/plant.lua index 57f870952e74a7272103c53a07e8584541c774e8..c573cb4c9211376a156338bfe1a4a5f1a0af4c20 100644 --- a/game/modules/tome/data/general/npcs/plant.lua +++ b/game/modules/tome/data/general/npcs/plant.lua @@ -95,4 +95,10 @@ newEntity{ base = "BASE_NPC_PLANT", }, resolvers.talents{ [Talents.T_SUMMON]=1 }, + on_die = function(self, who) + local part = "HONEY_TREE_ROOT" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } diff --git a/game/modules/tome/data/general/npcs/ritch.lua b/game/modules/tome/data/general/npcs/ritch.lua index 473b1051fa555ba20baf21a199f1c8efe0c3b7ea..2ba89823f409bc25aef79d76b81e4481e25f7077 100644 --- a/game/modules/tome/data/general/npcs/ritch.lua +++ b/game/modules/tome/data/general/npcs/ritch.lua @@ -43,6 +43,12 @@ Vicious predators, they inject corrupting diseases into their foes, and their sh poison_immune = 0.5, disease_immune = 0.5, resists = { [DamageType.BLIGHT] = 20, [DamageType.FIRE] = 100 }, + on_die = function(self, who) + local part = "RITCH_STINGER" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } newEntity{ base = "BASE_NPC_RITCH", diff --git a/game/modules/tome/data/general/npcs/sandworm.lua b/game/modules/tome/data/general/npcs/sandworm.lua index b4ce7474344cc7ed7ca2ab62ccf3769bd604456a..8d38b5a33e0a5a30b412a7069ecd0799a9c9c2b6 100644 --- a/game/modules/tome/data/general/npcs/sandworm.lua +++ b/game/modules/tome/data/general/npcs/sandworm.lua @@ -43,6 +43,12 @@ newEntity{ ai = "dumb_talented_simple", ai_state = { ai_move="move_dmap", talent_in=3, }, stats = { str=15, dex=7, mag=3, con=3 }, combat_armor = 1, combat_def = 1, + on_die = function(self, who) + local part = "SANDWORM_TOOTH" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } newEntity{ base = "BASE_NPC_SANDWORM", diff --git a/game/modules/tome/data/general/npcs/skeleton.lua b/game/modules/tome/data/general/npcs/skeleton.lua index 615a589a215328d21c8b571ad6053be8b5c3c783..13fc17b805be16df68a7d02b92c4198a393cad91 100644 --- a/game/modules/tome/data/general/npcs/skeleton.lua +++ b/game/modules/tome/data/general/npcs/skeleton.lua @@ -85,6 +85,12 @@ newEntity{ base = "BASE_NPC_SKELETON", autolevel = "caster", ai = "dumb_talented_simple", ai_state = { talent_in=3, }, + on_die = function(self, who) + local part = "SKELETON_MAGE_SKULL" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } newEntity{ base = "BASE_NPC_SKELETON", diff --git a/game/modules/tome/data/general/npcs/snake.lua b/game/modules/tome/data/general/npcs/snake.lua index 1be5e5b08774ee981d130237115a0f50d5773de9..e18a96f6d5a84dc52193373162c566057a6c7bf8 100644 --- a/game/modules/tome/data/general/npcs/snake.lua +++ b/game/modules/tome/data/general/npcs/snake.lua @@ -104,6 +104,12 @@ newEntity{ base = "BASE_NPC_SNAKE", combat = { dam=resolvers.levelup(10, 1, 0.7), atk=30, apr=10 }, resolvers.talents{ [Talents.T_BITE_POISON]=3 }, + on_die = function(self, who) + local part = "BLACK_MAMBA_HEAD" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } newEntity{ base = "BASE_NPC_SNAKE", diff --git a/game/modules/tome/data/general/npcs/snow-giant.lua b/game/modules/tome/data/general/npcs/snow-giant.lua index b2c1db06d5d119888dc5586d04d883540ebffe42..62f2cccb4518320311761217afbaff379386786c 100644 --- a/game/modules/tome/data/general/npcs/snow-giant.lua +++ b/game/modules/tome/data/general/npcs/snow-giant.lua @@ -47,6 +47,12 @@ newEntity{ no_breath = 1, confusion_immune = 1, poison_immune = 1, + on_die = function(self, who) + local part = "SNOW_GIANT_KIDNEY" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } newEntity{ base = "BASE_NPC_SNOW_GIANT", diff --git a/game/modules/tome/data/general/npcs/spider.lua b/game/modules/tome/data/general/npcs/spider.lua index 8d89e82a868d911dec0f0cba823764691f4fb767..1ae6dc0e430e8930d6c795476b55da706297402e 100644 --- a/game/modules/tome/data/general/npcs/spider.lua +++ b/game/modules/tome/data/general/npcs/spider.lua @@ -61,7 +61,12 @@ newEntity{ base = "BASE_NPC_SPIDER", [Talents.T_SPIDER_WEB]={base=1, every=10, max=5}, [Talents.T_LAY_WEB]={base=1, every=10, max=5}, }, - + on_die = function(self, who) + local part = "SPIDER_SPINNERET" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } newEntity{ base = "BASE_NPC_SPIDER", @@ -176,6 +181,12 @@ newEntity{ base = "BASE_NPC_SPIDER", [Talents.T_DISRUPTION_SHIELD]={base=3, every=6, max=6}, [Talents.T_ARCANE_POWER]={base=3, every=6, max=6}, }, + on_die = function(self, who) + local part = "FAERLHING_FANG" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } diff --git a/game/modules/tome/data/general/npcs/storm-drake.lua b/game/modules/tome/data/general/npcs/storm-drake.lua index 62b697df2f5d3cd81111a1a1455b2ff3e9f8ce2a..9ba08bce9857aebfb5cb8ab055e381bf30c8e689 100644 --- a/game/modules/tome/data/general/npcs/storm-drake.lua +++ b/game/modules/tome/data/general/npcs/storm-drake.lua @@ -108,4 +108,10 @@ newEntity{ base = "BASE_NPC_STORM_DRAKE", [Talents.T_STATIC_FIELD]={base=3, every=10}, [Talents.T_TORNADO]={base=5, every=4}, }, + on_die = function(self, who) + local part = "STORM_WYRM_CLAW" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } diff --git a/game/modules/tome/data/general/npcs/swarm.lua b/game/modules/tome/data/general/npcs/swarm.lua index 67956dda37c9ea8546ddba8cce48d30adc016d60..a0f2917499905c12d18261a7753887470fe992ba 100644 --- a/game/modules/tome/data/general/npcs/swarm.lua +++ b/game/modules/tome/data/general/npcs/swarm.lua @@ -79,4 +79,10 @@ newEntity{ base = "BASE_NPC_INSECT", can_multiply = 4, resolvers.talents{ [Talents.T_BITE_POISON]={base=3, every=10, max=8} }, + on_die = function(self, who) + local part = "HUMMERHORN_WING" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } diff --git a/game/modules/tome/data/general/npcs/troll.lua b/game/modules/tome/data/general/npcs/troll.lua index 92af49e4d94d948c1b413ef10a31e4230f1b767a..5b81a45e171dfc764f3a6e396a66e3f2efc12684 100644 --- a/game/modules/tome/data/general/npcs/troll.lua +++ b/game/modules/tome/data/general/npcs/troll.lua @@ -48,6 +48,12 @@ newEntity{ resists = { [DamageType.FIRE] = -50 }, fear_immune = 1, + on_die = function(self, who) + local part = "TROLL_INTESTINE" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } newEntity{ base = "BASE_NPC_TROLL", diff --git a/game/modules/tome/data/general/npcs/vampire.lua b/game/modules/tome/data/general/npcs/vampire.lua index 02afa9e6aa99877124b4f298bd66600f2a82bae6..ab5d2cbeeeb228684e5634c5ba0d8955ad85162c 100644 --- a/game/modules/tome/data/general/npcs/vampire.lua +++ b/game/modules/tome/data/general/npcs/vampire.lua @@ -118,6 +118,12 @@ It can summon the very shades of its victims from beyond the grave to come ensla resolvers.inscriptions(1, "rune"), summon = {{type="undead", number=1, hasxp=false}, }, resolvers.talents{ [Talents.T_STUN]={base=2, every=7, max=6}, [Talents.T_SUMMON]=1, [Talents.T_BLUR_SIGHT]={base=3, every=7, max=7}, [Talents.T_PHANTASMAL_SHIELD]={base=2, every=7, max=6}, [Talents.T_ROTTING_DISEASE]={base=3, every=7, max=7}, }, + on_die = function(self, who) + local part = "ELDER_VAMPIRE_BLOOD" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } newEntity{ base = "BASE_NPC_VAMPIRE", @@ -135,4 +141,10 @@ newEntity{ base = "BASE_NPC_VAMPIRE", make_escort = { {type="undead", number=resolvers.mbonus(2, 2)}, }, + on_die = function(self, who) + local part = "VAMPIRE_LORD_FANG" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } diff --git a/game/modules/tome/data/general/npcs/vermin.lua b/game/modules/tome/data/general/npcs/vermin.lua index 1dcdcbc619e1fdcfd6985ea8324b3e5b0a8a9d56..8c2420283e81f8d17ce2d5d6d6ecf5dd79c9d823 100644 --- a/game/modules/tome/data/general/npcs/vermin.lua +++ b/game/modules/tome/data/general/npcs/vermin.lua @@ -56,6 +56,12 @@ newEntity{ base = "BASE_NPC_WORM", combat = { dam=1, atk=15, apr=100 }, resolvers.talents{ [Talents.T_CRAWL_ACID]=2, [Talents.T_MULTIPLY]=1 }, + on_die = function(self, who) + local part = "GREEN_WORM" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } newEntity{ base = "BASE_NPC_WORM", diff --git a/game/modules/tome/data/general/npcs/wight.lua b/game/modules/tome/data/general/npcs/wight.lua index 6b8f904963b8a5c02a16842652fbdaa8f499e387..ad0f445781a4a11bc7b0cd0cc9ea2cae1b2adbe2 100644 --- a/game/modules/tome/data/general/npcs/wight.lua +++ b/game/modules/tome/data/general/npcs/wight.lua @@ -58,6 +58,12 @@ newEntity{ undead = 1, -- free_action = 1, -- sleep_immune = 1, + on_die = function(self, who) + local part = "WIGHT_ECTOPLASM" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } newEntity{ base = "BASE_NPC_WIGHT", diff --git a/game/modules/tome/data/general/npcs/xorn.lua b/game/modules/tome/data/general/npcs/xorn.lua index 54f620675773f5d6104b20e160d20466a910dd7a..beaf43d536cd8f0d1bd8d451295e3134241dbd06 100644 --- a/game/modules/tome/data/general/npcs/xorn.lua +++ b/game/modules/tome/data/general/npcs/xorn.lua @@ -51,6 +51,12 @@ newEntity{ confusion_immune = 1, poison_immune = 1, stone_immune = 1, + on_die = function(self, who) + local part = "XORN_FRAGMENT" + if game.player:hasQuest("brotherhood-of-alchemists") then + game.player:hasQuest("brotherhood-of-alchemists"):need_part(who, part, self) + end + end, } newEntity{ base = "BASE_NPC_XORN", diff --git a/game/modules/tome/data/general/objects/brotherhood-artifacts.lua b/game/modules/tome/data/general/objects/brotherhood-artifacts.lua new file mode 100644 index 0000000000000000000000000000000000000000..eeeb2fb5d227c54e9f0f3d9823b7850c23a6e251 --- /dev/null +++ b/game/modules/tome/data/general/objects/brotherhood-artifacts.lua @@ -0,0 +1,333 @@ +-- ToME - Tales of Maj'Eyal +-- Copyright (C) 2009, 2010 Nicolas Casalini +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +-- Nicolas Casalini "DarkGod" +-- darkgod@te4.org +load("/data/general/objects/scrolls.lua") +load("/data/general/objects/gem.lua") + +local Stats = require "engine.interface.ActorStats" +local Talents = require "engine.interface.ActorTalents" + +-- This file describes the twelve elixirs and three artifacts obtainable through the Brotherhood of Alchemists quest + +newEntity{ + power_source = {nature=true}, + define_as = "ELIXIR_FOX", + type = "potion", subtype="potion", + name = "Elixir of the Fox", unique=true, unided_name="vial of pink fluid", + display = "!", color=colors.VIOLET, + desc = [[A vial of pink, airy fluid.]], + no_unique_lore = true, + cost = 1000, + + use_simple = { name="permanently increase your dexterity and cunning by three", use = function(self, who) + game.logPlayer(who, "#00FFFF#You drink the elixir and feel forever transformed!") + who.inc_stats[who.STAT_DEX] = who.inc_stats[who.STAT_DEX] + 3 + who:onStatChange(who.STAT_DEX, 3) + who.inc_stats[who.STAT_CUN] = who.inc_stats[who.STAT_CUN] + 3 + who:onStatChange(who.STAT_CUN, 3) + game.logPlayer(who, "#00FF00#The elixir has given you foxlike physical and mental agility!") + return true, "destroy", true + end} +} + +newEntity{ + power_source = {nature=true}, + define_as = "ELIXIR_AVOIDANCE", + type = "potion", subtype="potion", + name = "Elixir of Avoidance", unique=true, unided_name="vial of green fluid", + display = "!", color=colors.GREEN, + desc = [[A vial of opaque green fluid.]], + no_unique_lore = true, + cost = 1000, + + use_simple = { name="permanently increase your defense and ranged defense by six", use = function(self, who) + game.logPlayer(who, "#00FFFF#You drink the elixir and feel forever transformed!") + who.combat_def = who.combat_def + 6 + game.logPlayer(who, "#00FF00#The elixir has improved your defensive instincts!") + return true, "destroy", true + end} +} + +newEntity{ + power_source = {nature=true}, + define_as = "ELIXIR_PRECISION", + type = "potion", subtype="potion", + name = "Elixir of Precision", unique=true, unided_name="vial of red fluid", + display = "!", color=colors.GREEN, + desc = [[A vial of chunky red fluid.]], + no_unique_lore = true, + cost = 1000, + + use_simple = { name="permanently increase your physical critical strike chance by 4%", use = function(self, who) + game.logPlayer(who, "#00FFFF#You drink the elixir and feel forever transformed!") + who.combat_physcrit = who.combat_physcrit + 4 + game.logPlayer(who, "#00FF00#The elixir has improved your eye for an enemy's weak points!") + return true, "destroy", true + end} +} + +newEntity{ + power_source = {nature=true}, + define_as = "ELIXIR_MYSTICISM", + type = "potion", subtype="potion", + name = "Elixir of Mysticism", unique=true, unided_name="vial of cyan fluid", + display = "!", color=colors.BLUE, + desc = [[A vial of glowing cyan fluid.]], + no_unique_lore = true, + cost = 1000, + + use_simple = { name="permanently increase your magic and willpower by three", use = function(self, who) + game.logPlayer(who, "#00FFFF#You drink the elixir and feel forever transformed!") + who.inc_stats[who.STAT_MAG] = who.inc_stats[who.STAT_MAG] + 3 + who:onStatChange(who.STAT_MAG, 3) + who.inc_stats[who.STAT_WIL] = who.inc_stats[who.STAT_WIL] + 3 + who:onStatChange(who.STAT_WIL, 3) + game.logPlayer(who, "#00FF00#The elixir has augmented your magical and mental capacity!") + return true, "destroy", true + end} +} + +newEntity{ + power_source = {nature=true}, + define_as = "ELIXIR_SAVIOR", + type = "potion", subtype="potion", + name = "Elixir of the Savior", unique=true, unided_name="vial of grey fluid", + display = "!", color=colors.GREY, + desc = [[A vial of bubbling, slate-colored fluid.]], + no_unique_lore = true, + cost = 1000, + + use_simple = { name="permanently increase all your saving throws by 4", use = function(self, who) + game.logPlayer(who, "#00FFFF#You drink the elixir and feel forever transformed!") + who.combat_physresist = who.combat_physresist + 4 + who.combat_spellresist = who.combat_spellresist + 4 + who.combat_mentalresist = who.combat_mentalresist + 4 + game.logPlayer(who, "#00FF00#The elixir has improved your resistance to unpleasant effects!") + return true, "destroy", true + end} +} + +newEntity{ + power_source = {nature=true}, + define_as = "ELIXIR_MASTERY", + type = "potion", subtype="potion", + name = "Elixir of Mastery", unique=true, unided_name="vial of maroon fluid", + display = "!", color=colors.PURPLE, + desc = [[A vial of thick maroon fluid.]], + no_unique_lore = true, + cost = 1000, + + use_simple = { name="grant you four additional stat points", use = function(self, who) + game.logPlayer(who, "#00FFFF#You drink the elixir and feel forever transformed!") + who.unused_stats = who.unused_stats + 3 + game.logPlayer(who, "#00FF00#The elixir has greatly expanded your capacity for improving your mind and body.") + game.logPlayer(who, "You have %d stat point(s) to spend. Press G to use them.", who.unused_stats) + return true, "destroy", true + end} +} + +newEntity{ + power_source = {nature=true}, + define_as = "ELIXIR_FORCE", + type = "potion", subtype="potion", + name = "Elixir of Explosive Force", unique=true, unided_name="vial of orange fluid", + display = "!", color=colors.ORANGE, + desc = [[A vial of churning orange fluid.]], + no_unique_lore = true, + cost = 1000, + + use_simple = { name="permanently increase your chance to critically strike with spells by 4%", use = function(self, who) + game.logPlayer(who, "#00FFFF#You drink the elixir and feel forever transformed!") + who.combat_spellcrit = who.combat_spellcrit + 4 + game.logPlayer(who, "#00FF00#The elixir has improved your eye for an enemy's magical weak points!") + return true, "destroy", true + end} +} + +newEntity{ + power_source = {nature=true}, + define_as = "ELIXIR_SERENDIPITY", + type = "potion", subtype="potion", + name = "Elixir of Serendipity", unique=true, unided_name="vial of yellow fluid", + display = "!", color=colors.YELLOW, + desc = [[A vial of lifelike yellow fluid.]], + no_unique_lore = true, + cost = 1000, + + use_simple = { name="permanently increase your luck by 5", use = function(self, who) + game.logPlayer(who, "#00FFFF#You drink the elixir and feel forever transformed!") + who.inc_stats[who.STAT_LCK] = who.inc_stats[who.STAT_LCK] + 5 + who:onStatChange(who.STAT_LCK, 5) + game.logPlayer(who, "#00FF00#The elixir seems to have subtly repositioned your entire being within the fabric of reality!") + return true, "destroy", true + end} +} + +newEntity{ + power_source = {nature=true}, + define_as = "ELIXIR_FOCUS", + type = "potion", subtype="potion", + name = "Elixir of Focus", unique=true, unided_name="vial of clear fluid", + display = "!", color=colors.WHITE, + desc = [[A vial of clear, steaming fluid.]], + no_unique_lore = true, + cost = 1000, + + use_simple = { name="grant you two additional class talent points", use = function(self, who) + game.logPlayer(who, "#00FFFF#You drink the elixir and feel forever transformed!") + who.unused_talents = who.unused_talents + 2 + game.logPlayer(who, "#00FF00#The elixir has improved your capacity for exercising your core talents.") + return true, "destroy", true + end} +} + +newEntity{ + power_source = {nature=true}, + define_as = "ELIXIR_BRAWN", + type = "potion", subtype="potion", + name = "Elixir of Brawn", unique=true, unided_name="vial of tan fluid", + display = "!", color=colors.TAN, + desc = [[A vial of sluggish tan fluid.]], + no_unique_lore = true, + cost = 1000, + + use_simple = { name="permanently increase your strength and constitution by three", use = function(self, who) + game.logPlayer(who, "#00FFFF#You drink the elixir and feel forever transformed!") + who.inc_stats[who.STAT_STR] = who.inc_stats[who.STAT_STR] + 3 + who:onStatChange(who.STAT_STR, 3) + who.inc_stats[who.STAT_CON] = who.inc_stats[who.STAT_CON] + 3 + who:onStatChange(who.STAT_CON, 3) + game.logPlayer(who, "#00FF00#The elixir has augmented your physical might and resilience!") + return true, "destroy", true + end} +} + +newEntity{ + power_source = {nature=true}, + define_as = "ELIXIR_STONESKIN", + type = "potion", subtype="potion", + name = "Elixir of Stoneskin", unique=true, unided_name="vial of iron-colored fluid", + display = "!", color=colors.SLATE, + desc = [[A vial of grainy, iron-colored fluid.]], + no_unique_lore = true, + cost = 1000, + + use_simple = { name="permanently increase your armor by four", use = function(self, who) + game.logPlayer(who, "#00FFFF#You drink the elixir and feel forever transformed!") + who.combat_armor = who.combat_armor + 4 + game.logPlayer(who, "#00FF00#The elixir has thickened and toughened your skin!") + return true, "destroy", true + end} +} + +newEntity{ + power_source = {nature=true}, + define_as = "ELIXIR_FOUNDATIONS", + type = "potion", subtype="potion", + name = "Elixir of Foundations", unique=true, unided_name="vial of white fluid", + display = "!", color=colors.WHITE, + desc = [[A vial of murky wuite fluid.]], + no_unique_lore = true, + cost = 1000, + + use_simple = { name="grant you two additional generic talent points", use = function(self, who) + game.logPlayer(who, "#00FFFF#You drink the elixir and feel forever transformed!") + who.unused_generics = who.unused_generics + 2 + game.logPlayer(who, "#00FF00#The elixir has improved your capacity for exercising your core talents.") + return true, "destroy", true + end} +} + +-- The four possible final rewards for the Brotherhood of Alchemists quest: + +newEntity{ base = "BASE_TAINT", + name = "Taint of Telepathy", + define_as = "TAINT_TELEPATHY", + unique = true, + identified = true, + cost = 200, + material_level = 3, + + inscription_kind = "utility", + inscription_data = { + cooldown = 30, + dur = 5, + }, + inscription_talent = "TAINT:_TELEPATHY", +} + +newEntity{ base = "BASE_INFUSION", + name = "Infusion of Wild Growth", + define_as = "INFUSION_WILD_GROWTH", + unique = true, + identified = true, + cost = 200, + material_level = 3, + + inscription_kind = "utility", + inscription_data = { + cooldown = 30, + dur = 5, + }, + inscription_talent = "INFUSION:_WILD_GROWTH", +} + +newEntity{ base = "BASE_GEM", + define_as = "LIFEBINDING_EMERALD", + power_source = {nature=true}, + unique = true, + unided_name = "cloudy, heavy emerald", + name = "Lifebinding Emerald", subtype = "green", + color = colors.GREEN, image="object/emerald.png", + desc = [[A lopsided, heavy emerald with murky green clouds shifting sluggishly under the surface.]], + cost = 200, + material_level = 5, + wielder = { + inc_stats = {[Stats.STAT_CON] = 10, }, + healing_factor = 0.3, + life_regen = 2, + resists = { + [DamageType.BLIGHT] = 10, + }, + }, + imbue_powers = { + inc_stats = {[Stats.STAT_CON] = 10, }, + healing_factor = 0.3, + life_regen = 2, + resists = { + [DamageType.BLIGHT] = 10, + }, + }, +} + +newEntity{ + power_source = {nature=true}, + define_as = "ELIXIR_INVULNERABILITY", + encumber = 2, + type = "potion", subtype="potion", + name = "Elixir of Invulnerability", unique=true, unided_name="vial of black fluid", + display = "!", color=colors.SLATE, + desc = [[A vial of thick fluid, metallic and reflective. It's incredibly heavy.]], + cost = 200, + + use_simple = { name="grant you complete invulnerability for five turns", use = function(self, who) + who:setEffect(who.EFF_DAMAGE_SHIELD, 5, {power=1000000}) + game.logPlayer(who, "#00FF00#You feel indestructible!") + return true, "destroy", true + end} +} diff --git a/game/modules/tome/data/general/objects/elixir-ingredients.lua b/game/modules/tome/data/general/objects/elixir-ingredients.lua new file mode 100644 index 0000000000000000000000000000000000000000..bb999b1a26b1a56f579597cf9dac26dbf0337f55 --- /dev/null +++ b/game/modules/tome/data/general/objects/elixir-ingredients.lua @@ -0,0 +1,451 @@ +-- ToME - Tales of Maj'Eyal +-- Copyright (C) 2009, 2010 Nicolas Casalini +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +-- Nicolas Casalini "DarkGod" +-- darkgod@te4.org + + +newEntity{ define_as = "TROLL_INTESTINE", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + level_range = {50, 50}, + encumber = 0, + unided_name = "troll guts", + name = "length of troll intestine", + display = "&", color=colors.VIOLET, + desc = [[A length of troll intestines. Fortunately, the troll appears to have eaten nothing in some time.]], + alch = "Kindly empty it before returning.", +} + +newEntity{ define_as = "SKELETON_MAGE_SKULL", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + unided_name = "battered skull", + name = "skeleton mage skull", + level_range = {50, 50}, + display = "*", color=colors.WHITE, + encumber = 0, + desc = [[The skull of a skeleton mage. The eyes have stopped glowing... for now.]], + alch = "If the eyes are still glowing, please bash it around a bit until they fade. I'll not have another one of those coming alive and wreaking havoc in my lab.", +} + +newEntity{ define_as = "RITCH_STINGER", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + unided_name = "giant stinger", + name = "ritch stinger", + level_range = {50, 50}, + display = "/", color=colors.GREEN, + encumber = 0, + desc = [[A ritch stinger, still glistening with venom.]], + alch = "Keep as much venom in it as possible.", +} + +newEntity{ define_as = "ORC_HEART", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + unided_name = "heart", + name = "orc heart", + level_range = {50, 50}, + display = "*", color=colors.RED, + encumber = 0, + desc = [[The heart of an orc. Perhaps surprisingly, it isn't green.]], + alch = "If you can fetch me a still-beating orc heart, that would be even better. But you don't look like a master necromancer to me.", +} + +newEntity{ define_as = "NAGA_TONGUE", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + level_range = {50, 50}, + encumber = 0, + unided_name = "naga tongue", + name = "naga tongue", + display = "-", color=colors.RED, + desc = [[A severed naga tongue. It reeks of brine.]], + alch = "Best results occur with tongues never tainted by profanity, so if you happen to know any saintly nagas...", +} + +newEntity{ define_as = "GREATER_DEMON_BILE", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + level_range = {50, 50}, + encumber = 0, + unided_name = "demon bile", + name = "vial of greater demon bile", + display = "~", color=colors.GREEN, + desc = [[A vial of greater demon bile. It hurts your sinuses even with the vial's stopper firmly in place.]], + alch = "Don't drink it, even if it tells you to.", +} + +newEntity{ define_as = "BONE_GOLEM_DUST", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + level_range = {50, 50}, + encumber = 0, + unided_name = "bone giant dust", + name = "pouch of bone giant dust", + display = "~", color=colors.WHITE, + desc = [[Once the magics animating the bone giant fled, its remains crumbled to dust. It might be your imagination, but it looks like the dust occasionally stirs on its own.]], + alch = "Never, ever to be confused with garlic powder. Trust me.", +} + +newEntity{ define_as = "FROST_ANT_STINGER", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + level_range = {50, 50}, + encumber = 0, + unided_name = "stinger", + name = "ice ant stinger", + display = "-", color=colors.WHITE, + desc = [[Wickedly sharp and still freezing cold.]], + alch = "If you've the means to eliminate the little venom problem, these make miraculous instant drink-chilling straws.", +} + +newEntity{ define_as = "MINOTAUR_NOSE", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + level_range = {50, 50}, + encumber = 0, + unided_name = "minotaur nose", + name = "minotaur nose", + display = "*", color=colors.GREY, + desc = [[The severed front half of a minotaur snout, ring and all.]], + alch = "You'll need to find one with a ring, preferably an expensive one.", +} + +newEntity{ define_as = "ELDER_VAMPIRE_BLOOD", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + level_range = {50, 50}, + encumber = 0, + unided_name = "black blood", + name = "vial of elder vampire blood", + display = "~", color=colors.GREY, + desc = [[Thick, clotted, and foul. The vial is cold to the touch.]], + alch = "Once you've gotten it, cross some moving water on your way back.", +} + +newEntity{ define_as = "MULTIHUED_WYRM_SCALE", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + level_range = {50, 50}, + encumber = 0, + unided_name = "shimmering scale", + name = "multi-hued wyrm scale", + display = "~", color=colors.VIOLET, + desc = [[Beautiful and nearly impregnable. Separating it from the dragon was hard work.]], + alch = "If you think collecting one of these is hard, try liquefying one.", +} + +newEntity{ define_as = "SPIDER_SPINNERET", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + level_range = {50, 50}, + encumber = 0, + unided_name = "spinneret", + name = "giant spider spinneret", + display = "*", color=colors.GREEN, + desc = [[An ugly, ripped-out chunk of giant spider. Bits of silk protrude from an orifice.]], + alch = "The spiders in your barn won't do. You'll know a giant spider when you see one, though they're rare in Maj'Eyal.", +} + +newEntity{ define_as = "HONEY_TREE_ROOT", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + level_range = {50, 50}, + encumber = 0, + unided_name = "dirty root", + name = "honey tree root", + display = "~", color=colors.TAN, + desc = [[The severed end of one of a honey tree's roots. It wriggles around occasionally, seemingly unwilling to admit that it's dead... and a *plant*.]], + alch = "Keep a firm grip on it. These things will dig themselves right back into the ground if you drop them.", +} + +newEntity{ define_as = "HEADLESS_HORROR_HEART", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + level_range = {50, 50}, + encumber = 0, + unided_name = "heart", + name = "headless horror heart", + display = "*", color=colors.GREY, + desc = [[Diseased-looking and reeking. It seems to be decaying as you watch.]], + alch = "Don't worry if it dissolves. Just don't get any on you.", +} + +newEntity{ define_as = "ELECTRIC_EEL_TAIL", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + level_range = {50, 50}, + encumber = 0, + unided_name = "eel tail", + name = "electric eel tail", + display = "~", color=colors.BLUE, + desc = [[Slimy, wriggling, and crackling with electricity.]], + alch = "I know, I know. Where does the eel stop and the tail start? It doesn't much matter. The last ten inches or so should do nicely.", +} + +newEntity{ define_as = "SQUID_INK", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + level_range = {50, 50}, + encumber = 0, + unided_name = "black liquid", + name = "vial of squid ink", + display = "~", color=colors.DARK_GREY, + desc = [[Thick, black and opaque.]], + alch = "However annoying this will be for you to gather, I promise that the reek it produces in my lab will prove even more annoying.", +} + +newEntity{ define_as = "BEAR_PAW", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + level_range = {50, 50}, + encumber = 0, + unided_name = "large, clawed paw", + name = "bear paw", + display = "*", color=colors.TAN, + desc = [[Large and hairy with flesh-rending claws. It smells slightly of fish.]], + alch = "You'd think I could get one of these from a local hunter, but they've had no luck. Don't get eaten.", +} + +newEntity{ define_as = "ICE_WYRM_TOOTH", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + level_range = {50, 50}, + encumber = 0, + unided_name = "tooth", + name = "ice wyrm tooth", + display = "/", color=colors.WHITE, + desc = [[This tooth has been blunted with age, but still looks more than capable of doing its job.]], + alch = "Ice Wyrms lose teeth fairly often, so you might get lucky and not have to do battle with one. But dress warm just in case.", +} + +newEntity{ define_as = "RED_CRYSTAL_SHARD", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + level_range = {50, 50}, + encumber = 0, + unided_name = "red crystal shard", + name = "red crystal shard", + display = "/", color=colors.RED, + desc = [[Tiny flames still dance etherally inside this transparent crystal, though its heat has faded.]], + alch = "I hear these can be found in a cave near Elvala. I also hear that they can cause you to spontaneously combust, so no need to explain if you come back hideously scarred.", +} + +newEntity{ define_as = "FIRE_WYRM_SALIVA", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + level_range = {50, 50}, + encumber = 0, + unided_name = "wyrm saliva", + name = "vial of fire wyrm saliva", + display = "~", color=colors.RED, + desc = [[Clear and slightly thicker than water. It froths when shaken.]], + alch = "Keep this stuff well away from your campfire unless you want me to have to find a new, more alive adventurer.", +} + +newEntity{ define_as = "GHOUL_FLESH", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + level_range = {50, 50}, + encumber = 0, + unided_name = "chunk of rotten flesh", + name = "chunk of ghoul flesh", + display = "*", color=colors.TAN, + desc = [[Rotten and reeking. It still twitches occasionally.]], + alch = "Unfortunately for you, the chunks that regularly fall off ghouls won't do. I need one freshly carved off.", +} + +newEntity{ define_as = "MUMMY_BONE", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + level_range = {50, 50}, + encumber = 0, + unided_name = "dry, flesh-encrusted bone", + name = "mummified bone", + display = "-", color=colors.WHITE, + desc = [[Bits of dry flesh still cling to this ancient bone.]], + alch = "That is, a bone from a corpse that's undergone mummification. Actually, any bit of the body would do, but the bones are the only parts you're certain to find when you kick a mummy apart. I recommend finding one that doesn't apply curses.", +} + +newEntity{ define_as = "SANDWORM_TOOTH", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + level_range = {50, 50}, + encumber = 0, + unided_name = "small, pointed tooth", + name = "sandworm tooth", + display = "/", color=colors.GREY, + desc = [[Tiny, dark grey, and wickedly sharp. It looks more like rock than bone.]], + alch = "Yes, sandworms have teeth. They're just very small and well back from where you're ever likely to see them and live.", +} + +newEntity{ define_as = "BLACK_MAMBA_HEAD", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + level_range = {50, 50}, + encumber = 0, + unided_name = "snake head", + name = "black mamba head", + display = "*", color=colors.GREY, + desc = [[Unlike the rest of the black mamba, the severed head isn't moving.]], + alch = "If you get bitten, I can save your life if you still manage to bring back the head... and if it happens within about a minute from my door. Good luck.", +} + +newEntity{ define_as = "SNOW_GIANT_KIDNEY", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + level_range = {50, 50}, + encumber = 0, + unided_name = "kidney", + name = "snow giant kidney", + display = "*", color=colors.VIOLET, + desc = [[As unpleasant-looking as any exposed organ.]], + alch = "I suggest not killing the snow giant by impaling it through the kidneys. You'll just have to find another.", +} + +newEntity{ define_as = "STORM_WYRM_CLAW", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + level_range = {50, 50}, + encumber = 0, + unided_name = "claw", + name = "storm wyrm claw", + display = "/", color=colors.BLUE, + desc = [[Bluish and wickedly sharp. It makes your arm hair stand on end.]], + alch = "I recommend severing one of dewclaws. They're smaller and easier to remove, but they've never been blunted by use, so be careful you don't poke yourself. Oh yes, and don't get eaten.", +} + +newEntity{ define_as = "GREEN_WORM", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + level_range = {50, 50}, + encumber = 0, + unided_name = "dead green worm", + name = "green worm", + display = "~", color=colors.GREEN, + desc = [[A dead green worm, painstakingly separated from its tangle of companions.]], + alch = "Try to get any knots out before returning. Wear gloves.", +} + +newEntity{ define_as = "WIGHT_ECTOPLASM", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + level_range = {50, 50}, + encumber = 0, + unided_name = "viscous slime", + name = "vial of wight ectoplasm", + display = "*", color=colors.GREEN, + desc = [[Cloudy and thick. Only by bottling it can you prevent it from evaporating within minutes.]], + alch = "If you ingest any of this, never mind coming back here. Please.", +} + +newEntity{ define_as = "XORN_FRAGMENT", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + level_range = {50, 50}, + encumber = 0, + unided_name = "chunk of stone", + name = "xorn fragment", + display = "*", color=colors.TAN, + desc = [[Looks much like any other rock, though this one was recently sentient and trying to murder you.]], + alch = "Avoid fragments that contained the xorn's eyes. You've no idea how unpleasant it is being watched by your ingredients.", +} + +newEntity{ define_as = "WARG_CLAW", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + level_range = {50, 50}, + encumber = 0, + unided_name = "claw", + name = "warg claw", + display = "/", color=colors.TAN, + desc = [[Unpleasantly large and sharp for a canine's claw.]], + alch = "My usual ingredient gatherers draw the line at hunting wargs. Feel free to mock them on your way back.", +} + +newEntity{ define_as = "FAEROS_ASH", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + level_range = {50, 50}, + encumber = 0, + unided_name = "ash", + name = "pouch of faeros ash", + display = "*", color=colors.GREY, + desc = [[Unremarkable grey ash.]], + alch = "They're creatures of pure flame, and likely of extraplanar origin, but the ash of objects consumed by their fire has remarkable properties.", +} + +newEntity{ define_as = "WRETCHLING_EYE", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + level_range = {50, 50}, + encumber = 0, + unided_name = "eyeball", + name = "wretchling eyeball", + display = "*", color=colors.WHITE, + desc = [[Small and bloodshot. Its dead gaze still burns your skin.]], + alch = "Evil little things, wretchlings. Feel free to kill as many as you can, though I just need the one intact eyeball.", +} + +newEntity{ define_as = "FAERLHING_FANG", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + level_range = {50, 50}, + encumber = 0, + unided_name = "fang", + name = "faerlhing fang", + display = "/", color=colors.GREEN, + desc = [[It still drips venom and crackles with magical energy.]], + alch = "I've lost a number of adventurers to this one, but I'm sure you'll be fine.", +} + +newEntity{ define_as = "VAMPIRE_LORD_FANG", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + level_range = {50, 50}, + encumber = 0, + unided_name = "fang", + name = "vampire lord fang", + display = "/", color=colors.WHITE, + desc = [[Brilliantly white, but surrounded by blackest magic.]], + alch = "You should definitely consider not pricking yourself with it.", +} + +newEntity{ define_as = "HUMMERHORN_WING", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + level_range = {50, 50}, + encumber = 0, + unided_name = "translucent insect wing", + name = "hummerhorn wing", + display = "~", color=colors.VIOLET, + desc = [[Translucent and delicate-looking, but surprisingly durable.]], + alch = "If you've not encountered hummerhorns before, they're like wasps, only gigantic and lethal.", +} + +newEntity{ define_as = "LUMINOUS_HORROR_DUST", + quest=true, identified=true, no_unique_lore=true, + type = "misc", subtype="ingredient", + level_range = {50, 50}, + encumber = 0, + unided_name = "glowing dust", + name = "pouch of luminous horror dust", + display = "*", color=colors.YELLOW, + desc = [[Weightless and glowing; not your usual dust.]], + alch = "Not to be confused with radiant horrors. If you encounter the latter, then I suppose there are always more adventurers.", +} diff --git a/game/modules/tome/data/maps/towns/derth.lua b/game/modules/tome/data/maps/towns/derth.lua index 0bf49301472b14f8470b7f9da48782c707ea7260..47182273f59db91589a5cf317311e8fc51e58bfa 100644 --- a/game/modules/tome/data/maps/towns/derth.lua +++ b/game/modules/tome/data/maps/towns/derth.lua @@ -39,6 +39,7 @@ defineTile('3', "HARDWALL", nil, nil, "HEAVY_ARMOR_STORE") defineTile('1', "HARDWALL", nil, nil, "LIGHT_ARMOR_STORE") defineTile('4', "HARDWALL", nil, nil, "HERBALIST") defineTile('9', "HARDWALL", nil, nil, "JEWELRY") +quickEntity('a', {show_tooltip=true, name="Home of Stire the Alchemist", display='+', color=colors.LIGHT_UMBER, resolvers.chatfeature("alchemist-derth"), image="terrain/wood_store_closed.png"}, {no_teleport=true}) startx = 0 starty = 20 @@ -100,7 +101,7 @@ ttttttt~~~tt.__.........._......_.......t~~~tttttt ttttttt~~~t.._.#####....._......_.###...t~~~tttttt ttttttt~~~t.._.#####....._.####._.###...t~~~tttttt ttttttt~~~t.._.#####....._.####._.###...t~~~tttttt -ttttttt~~~t.._.#5#2#....___####._.###...t~~~tttttt +ttttttt~~~t.._.#5#2#....___##a#._.###...t~~~tttttt ttttttt~~~t.._______..___._.._.._.###...t~~~tttttt ttttttt~~~t......._..__..._______.###..tt~~~tttttt ttttttt~~~tt......_.._.........._.._...t~~~ttttttt diff --git a/game/modules/tome/data/maps/towns/elvala.lua b/game/modules/tome/data/maps/towns/elvala.lua index 24790726dbc8f4e8f823b0fd02071d8f3b866c38..f2d43c6cfbfde9f19f567f73164db41c6ff18baa 100644 --- a/game/modules/tome/data/maps/towns/elvala.lua +++ b/game/modules/tome/data/maps/towns/elvala.lua @@ -35,6 +35,7 @@ defineTile("2", "HARDWALL", nil, nil, "LIGHT_ARMOR_STORE") defineTile("3", "HARDWALL", nil, nil, "STAFF_WEAPON_STORE") defineTile("4", "HARDWALL", nil, nil, "SWORD_WEAPON_STORE") defineTile("5", "HARDWALL", nil, nil, "RUNEMASTER") +quickEntity('a', {show_tooltip=true, name="Home of Marus the Alchemist", display='+', color=colors.LIGHT_UMBER, resolvers.chatfeature("alchemist-elvala"), image="terrain/wood_store_closed.png"}, {no_teleport=true}) -- addSpot section @@ -61,7 +62,7 @@ return [[ ~~...............##___________##......ttt..~~~~~~~ ~~....ttt........#__#########__#...........~~~~~~~ ~....ttt.........#_###########_#...........~~~~~~~ -~...ttt.....######__#5#####1#__######.......~~~~~~ +~...ttt.....######__#5#a###1#__######.......~~~~~~ ~...t....####_______________________####......~~~~ ~......###_______#_____..._____#_______###.....~~~ ~.....##________###___.....___###________##....~~~ diff --git a/game/modules/tome/data/maps/towns/last-hope.lua b/game/modules/tome/data/maps/towns/last-hope.lua index 6c1e8447fc307f7d5e499ff19412176979a7b0c1..4f5cac2ff436d40a6e88a7ef52b0edbb6bc5e239 100644 --- a/game/modules/tome/data/maps/towns/last-hope.lua +++ b/game/modules/tome/data/maps/towns/last-hope.lua @@ -53,6 +53,7 @@ quickEntity('g', {type="store", show_tooltip=true, name="Rich merchant", display ]] quickEntity('E', {type="store", show_tooltip=true, name="The Elder", display='*', color=colors.VIOLET, resolvers.chatfeature("last-hope-elder"), image="terrain/wood_store_closed.png"}) quickEntity('T', {type="store", show_tooltip=true, name="Tannen's Tower", display='*', color=colors.VIOLET, resolvers.chatfeature("tannen"), image="terrain/wood_store_closed.png"}) +quickEntity('h', {show_tooltip=true, name="Home of Ungrol the Alchemist", display='+', color=colors.LIGHT_UMBER, resolvers.chatfeature("alchemist-last-hope"), image="terrain/wood_store_closed.png"}, {no_teleport=true}) quickEntity('@', {show_tooltip=true, name="Statue of King Tolak the Fair", display='@', image="terrain/grass.png", add_displays = {mod.class.Grid.new{image="terrain/statue1.png"}}, color=colors.LIGHT_BLUE, block_move=function(self, x, y, e, act, couldpass) if e and e.player and act then e:learnLore("last-hope-tolak-statue") end return true end}) quickEntity('Z', {show_tooltip=true, name="Statue of King Toknor the Brave", display='@', image="terrain/grass.png", add_displays = {mod.class.Grid.new{image="terrain/statue1.png"}}, color=colors.LIGHT_BLUE, block_move=function(self, x, y, e, act, couldpass) if e and e.player and act then e:learnLore("last-hope-toknor-statue") end return true end}) @@ -130,7 +131,7 @@ tt~~~## __~~###ttt###~~__ ##~~~t tt~~~~# __~~~#####~~~__ #~~~~t ttt~~~## ___~~~~~~~___ # ##~~~tt ttt~~~~# # _________ ### #~~~~tt -tttt~~~## ### # # ### ##~~~ttt +tttt~~~## ### # # ##h ##~~~ttt tttt~~~~## ### ### ### ### ##~~~~ttt ttttt~~~~# ### #### #### # #~~~~tttt tttttt~~~## # ####### ##~~~ttttt diff --git a/game/modules/tome/data/quests/brotherhood-of-alchemists.lua b/game/modules/tome/data/quests/brotherhood-of-alchemists.lua new file mode 100644 index 0000000000000000000000000000000000000000..22890d7f431b246a2854616b54b7485ccf4af943 --- /dev/null +++ b/game/modules/tome/data/quests/brotherhood-of-alchemists.lua @@ -0,0 +1,463 @@ +-- ToME - Tales of Maj'Eyal +-- Copyright (C) 2009, 2010 Nicolas Casalini +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +-- Nicolas Casalini "DarkGod" +-- darkgod@te4.org +name = "The Brotherhood of Alchemists" + +desc = function(self, player, who) + local desc = {} + + if self:isStatus(self.DONE) and self.player_won == true then + desc[#desc+1] = "#LIGHT_GREEN#Thanks to your timely aid, "..self.winner.." is the newest member of the Brotherhood of Alchemists.#WHITE#" + elseif self:isStatus(self.DONE) and self.player_won == false then + desc[#desc+1] = "#RED#You aided various denizens of Maj'Eyal in their attempts to join the Brotherhood of Alchemists, though you did not prove the deciding factor for any. This year's new member is "..self.winner..".#WHITE#" + else + desc[#desc+1] = "#LIGHT_BLUE#Various alchemists around Maj'Eyal are competing to gain entry into the great Brotherhood of Alchemists, and one or more has enlisted your aid.#WHITE#" + end + --e (for elixir) is the name of the table listing all the elixirs and their various strings and ingredients and such. self.e[2][3], for example, refers to the table containing all the information for the second alchemist's third elixir. self.e[2][3].ingredients[1] refers to the first ingredient of the third elixir of the second alchemist. This saves a ton of work in making the desc function, since it's messy and it would suck to copy/paste twelve of them (one for each elixir). + for i = 1, 4 do --run through list of four alchemists + for j = 1, 3 do --run through each alchemist's list of three elixirs + if self:isCompleted(self.e[i][j].full) and not self:isCompleted(self.e[i][j].poached) then + desc[#desc+1] = "#GREEN#You have aided "..self.e[i][j].alchemist.." in creating an "..self.e[i][j].name..".#WHITE#" + elseif self:isCompleted(self.e[i][j].full) and self:isCompleted(self.e[i][j].poached) then + desc[#desc+1] = "#RED#"..self.e[i][j].alchemist.." has completed an "..self.e[i][j].name.." without your aid.#WHITE#" + elseif self:isCompleted(self.e[i][j].start) and not self:isCompleted(self.e[i][j].full) and self:isStatus(self.DONE) then + desc[#desc+1] = "#SLATE#Having failed to gain admittance to the Brotherhood of the Alchemists, "..self.e[i][j].alchemist.." no longer needs your help making the "..self.e[i][j].name.."." + elseif self:isCompleted(self.e[i][j].start) and not self:isCompleted(self.e[i][j].full) then + desc[#desc+1] = ""..self.e[i][j].alchemist.." needs your help making an "..self.e[i][j].name..". He has given you some notes on the ingredients:" + if not self:check_i(player, self.e[i][j].ingredients[1]) then + desc[#desc+1] = "#SLATE# * 'Needed: one "..self.e[i][j].ingredients[1].name..". "..self.e[i][j].ingredients[1].alch.."'#WHITE#" + else + desc[#desc+1] = "#LIGHT_GREEN# * You've found the needed "..self.e[i][j].ingredients[1].name..".#WHITE#" + end + if not self:check_i(player, self.e[i][j].ingredients[2]) then + desc[#desc+1] = "#SLATE# * 'Needed: one "..self.e[i][j].ingredients[2].name..". "..self.e[i][j].ingredients[2].alch.."'#WHITE#" + else + desc[#desc+1] = "#LIGHT_GREEN# * You've found the needed "..self.e[i][j].ingredients[2].name..".#WHITE#" + end + if not self:check_i(player, self.e[i][j].ingredients[3]) then + desc[#desc+1] = "#SLATE# * 'Needed: one "..self.e[i][j].ingredients[3].name..". "..self.e[i][j].ingredients[3].alch.."'#WHITE#" + else + desc[#desc+1] = "#LIGHT_GREEN# * You've found the needed "..self.e[i][j].ingredients[3].name..".#WHITE#" + end + end + end + end + return table.concat(desc, "\n") +end + +on_grant = function(self, who) + self.cookbook, self.elixirs, self.alchemists, self.e = self:recipes() + self.needed_ingredients = {} + self.player_loses = false +end + +-- called whenever getting the task for or turning in an elixir. Wipes the shopping list and rewrites it. +update_needed_ingredients = function(self, player) + self.needed_ingredients = {} + for i = 1, 4 do + for j = 1, 3 do + if self:isCompleted(self.e[i][j].start) and not self:isCompleted(self.e[i][j].full) then + for k = 1, 3 do + table.insert(self.needed_ingredients, self.e[i][j].ingredients[k]) + --game.logPlayer(player, "Supposedly added one %s", self.e[i][j].ingredients[k].name) + end + end + end + end + local list = self.needed_ingredients +-- game.logPlayer(player, "List updated. Now needed:") +-- for l = 1, #list do +-- game.logPlayer(player, "one %s", self.needed_ingredients[l].name) +-- end + + --game.logPlayer(player, "Hey! %s", self.needed_ingredients[2].name) +end + +--only used in the desc function +check_i = function(self, player, ingredient) + local ing_list = mod.class.Object:loadList("/data/general/objects/elixir-ingredients.lua") + --local ing = ing_list[ingredient] + local o, item, inven_id = player:findInAllInventories(ingredient.name) + return o +end + +--called in various chat cond functions +check_ingredients = function(self, player, elixir, n) + local o = {self.cookbook[elixir][1], self.cookbook[elixir][2], self.cookbook[elixir][3]} + local first_o, first_item, first_inven_id = player:findInAllInventories(o[1].name) + local second_o, second_item, second_inven_id = player:findInAllInventories(o[2].name) + local third_o, third_item, third_inven_id = player:findInAllInventories(o[3].name) + return first_o and second_o and third_o +end + +--called in the on_die functions of ingredient-dropping monsters to determine if they should really drop their ingredient +need_part = function(self, player, ingredient, monster) + if self:isEnded() then return end + local list = self.needed_ingredients + local needed = false + local ing_list = mod.class.Object:loadList("/data/general/objects/elixir-ingredients.lua") + local ing = ing_list[ingredient]:clone() + ing:resolve() + ing:resolve(nil, true) + for i = 1, #list do + if list[i].name == ing.name then needed = true end + end + local o, item, inven_id = player:findInAllInventories(ing.name) + if needed and not o then + game.zone:addEntity(game.level, ing, "object", monster.x, monster.y) + end +end + +--called in various chat cond functions +remove_ingredients = function(self, player, elixir, n) + local o = {self.cookbook[elixir][1], self.cookbook[elixir][2], self.cookbook[elixir][3]} + for i = 1, 3 do + local object, item, inven_id = player:findInAllInventories(o[i].name) + player:removeObject(inven_id, item, false) + object:removed() + end +end + +--called both when handing out elixirs and when handing out the final reward (if any) +reward = function(self, player, reward) + local art_list = mod.class.Object:loadList("/data/general/objects/brotherhood-artifacts.lua") + local o = art_list[reward]:clone() + o:resolve() + o:resolve(nil, true) + if o then + player:addObject(player.INVEN_INVEN, o) + game.logPlayer(player, "You receive: %s", o:getName{do_color=true}) + end +end + +--reward = function(self, player, reward) +-- local o = game.zone:makeEntityByName(game.level, "object", reward) +-- if o then +-- player:addObject(player.INVEN_INVEN, o) +-- game.logPlayer(player, "You receive: %s", o:getName{do_color=true}) +-- end +--end + +--elixirs_finished isn't used, but it probably should be. Likely some of the cond functions in the chats could be much improved. +elixirs_finished = function(self, player, alchemist_num) + local total = 0 + for i = 1, 3 do + if self:isCompleted(self.e[alchemist_num][i].full) then + total = total + 1 + end + end + return total +end + +--called in chats. It doesn't change quest status at all. It mainly supplies chats with the names and indices of alchemists and the elixirs they're making off stage. +competition = function(self, player, other_alchemist_nums) + local alch_picked = rng.table(other_alchemist_nums) + local player_loses = false + --game.logPlayer(player, "Alchemist picked: %s", alch_picked) + local e_picked + local set = {1, 2, 3} + for j = 1, 3 do + e_picked = rng.tableRemove(set) + if not self:isCompleted(self.e[alch_picked][e_picked].full) then break end + end + + if e_picked == 1 and self:isCompleted(self.e[alch_picked][2].full) and self:isCompleted(self.e[alch_picked][3].full) then + player_loses = true + elseif e_picked == 2 and self:isCompleted(self.e[alch_picked][1].full) and self:isCompleted(self.e[alch_picked][3].full) then + player_loses = true + elseif e_picked == 3 and self:isCompleted(self.e[alch_picked][1].full) and self:isCompleted(self.e[alch_picked][2].full) then + player_loses = true + else + player_loses = false + end + + self.other_alch = self.e[alch_picked][e_picked].alchemist + self.alch_picked = alch_picked + self.other_elixir = self.e[alch_picked][e_picked].name + self.e_picked = e_picked + self.player_loses = player_loses + return self.other_alch, self.other_elixir, self.player_loses, self.alch_picked, self.e_picked +end + +--called in chats to force completion of the random alchemist+elixir picked in competition above. +on_turnin = function(self, player, alch_picked, e_picked, player_last_elixir) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, self.e[alch_picked][e_picked].full) + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.COMPLETED, self.e[alch_picked][e_picked].poached) + if player_last_elixir == false and self:isCompleted(self.e[alch_picked][1].full) and self:isCompleted(self.e[alch_picked][2].full) and self:isCompleted(self.e[alch_picked][3].full) then + player:setQuestStatus("brotherhood-of-alchemists", engine.Quest.DONE) + self.winner = self.e[alch_picked][1].alchemist + self.player_won = false + end +end + +--sets the name of the winner. Only called in the case of the player turning in an alchemist's final potion. An alchemist that completes his third potion without the player's aid gets named the winner in the on_turning function above. +winner_is = function(self, player, alchemist_num) + self.winner = self.e[alchemist_num][1].alchemist + self.player_won = true +end + +--list of object definitions used to randomly generate ingredients for the elixirs in the table e in the recipes function. +local monster_parts = { "TROLL_INTESTINE", "SKELETON_MAGE_SKULL", "RITCH_STINGER", "ORC_HEART", "NAGA_TONGUE", "GREATER_DEMON_BILE", "BONE_GOLEM_DUST", "FROST_ANT_STINGER", "MINOTAUR_NOSE", + "ELDER_VAMPIRE_BLOOD", "MULTIHUED_WYRM_SCALE", "SPIDER_SPINNERET", "HONEY_TREE_ROOT", "HEADLESS_HORROR_HEART", "ELECTRIC_EEL_TAIL", "SQUID_INK", "BEAR_PAW", "ICE_WYRM_TOOTH", + "RED_CRYSTAL_SHARD", "FIRE_WYRM_SALIVA", "GHOUL_FLESH", "MUMMY_BONE", "SANDWORM_TOOTH", "BLACK_MAMBA_HEAD", "SNOW_GIANT_KIDNEY", "STORM_WYRM_CLAW", "GREEN_WORM", + "WIGHT_ECTOPLASM", "XORN_FRAGMENT", "WARG_CLAW", "FAEROS_ASH", "WRETCHLING_EYE", "FAERLHING_FANG", "VAMPIRE_LORD_FANG", "HUMMERHORN_WING", "LUMINOUS_HORROR_DUST" } + +recipes = function() + local ing_list = mod.class.Object:loadList("/data/general/objects/elixir-ingredients.lua") + local e = { + { + { + short_name = "fox", + name = "elixir of the fox", + id = "ELIXIR_FOX", + start = "fox_start", + almost = "fox_almost_done", + full = "elixir_of_the_fox", + full_2 = "elixir_of_avoidance", + full_3 = "elixir_of_precision", + poached = "fox_poached", + alchemist = "Stire of Derth", + ingredients = { + ing_list[rng.tableRemove(monster_parts)], + ing_list[rng.tableRemove(monster_parts)], + ing_list[rng.tableRemove(monster_parts)], + }, + }, + { + short_name = "avoidance", + name = "elixir of avoidance", + id = "ELIXIR_AVOIDANCE", + start = "avoidance_start", + almost = "avoidance_almost_done", + full = "elixir_of_avoidance", + full_2 = "elixir_of_the_fox", + full_3 = "elixir_of_precision", + poached = "avoidance_poached", + alchemist = "Stire of Derth", + ingredients = { + ing_list[rng.tableRemove(monster_parts)], + ing_list[rng.tableRemove(monster_parts)], + ing_list[rng.tableRemove(monster_parts)], + }, + }, + { + short_name = "precision", + name = "elixir of precision", + id = "ELIXIR_PRECISION", + start = "precision_start", + almost = "precision_almost_done", + full = "elixir_of_precision", + full_2 = "elixir_of_the_fox", + full_3 = "elixir_of_avoidance", + poached = "precision_poached", + alchemist = "Stire of Derth", + ingredients = { + ing_list[rng.tableRemove(monster_parts)], + ing_list[rng.tableRemove(monster_parts)], + ing_list[rng.tableRemove(monster_parts)], + }, + }, + }, + { + { + short_name = "mysticism", + name = "elixir of mysticism", + id = "ELIXIR_MYSTICISM", + start = "mysticism_start", + almost = "mysticism_almost_done", + full = "elixir_of_mysticism", + full_2 = "elixir_of_the_savior", + full_3 = "elixir_of_mastery", + poached = "mysticism_poached", + alchemist = "Marus of Elvala", + ingredients = { + ing_list[rng.tableRemove(monster_parts)], + ing_list[rng.tableRemove(monster_parts)], + ing_list[rng.tableRemove(monster_parts)], + }, + }, + { + short_name = "savior", + name = "elixir of the savior", + id = "ELIXIR_SAVIOR", + start = "savior_start", + almost = "savior_almost_done", + full = "elixir_of_the_savior", + full_2 = "elixir_of_mysticism", + full_3 = "elixir_of_mastery", + poached = "savior_poached", + alchemist = "Marus of Elvala", + ingredients = { + ing_list[rng.tableRemove(monster_parts)], + ing_list[rng.tableRemove(monster_parts)], + ing_list[rng.tableRemove(monster_parts)], + }, + }, + { + short_name = "mastery", + name = "elixir of mastery", + id = "ELIXIR_MASTERY", + start = "mastery_start", + almost = "mastery_almost_done", + full = "elixir_of_mastery", + full_2 = "elixir_of_mysticism", + full_3 = "elixir_of_the_savior", + poached = "mastery_poached", + alchemist = "Marus of Elvala", + ingredients = { + ing_list[rng.tableRemove(monster_parts)], + ing_list[rng.tableRemove(monster_parts)], + ing_list[rng.tableRemove(monster_parts)], + }, + }, + }, + { + { + short_name = "force", + name = "elixir of explosive force", + id = "ELIXIR_FORCE", + start = "force_start", + almost = "force_almost_done", + full = "elixir_of_explosive_force", + full_2 = "elixir_of_serendipity", + full_3 = "elixir_of_focus", + poached = "force_poached", + alchemist = "Agrimley the hermit", + ingredients = { + ing_list[rng.tableRemove(monster_parts)], + ing_list[rng.tableRemove(monster_parts)], + ing_list[rng.tableRemove(monster_parts)], + }, + }, + { + short_name = "serendipity", + name = "elixir of serendipity", + id = "ELIXIR_SERENDIPITY", + start = "serendipity_start", + almost = "serendipity_almost_done", + full = "elixir_of_serendipity", + full_2 = "elixir_of_explosive_force", + full_3 = "elixir_of_focus", + poached = "serendipity_poached", + alchemist = "Agrimley the hermit", + ingredients = { + ing_list[rng.tableRemove(monster_parts)], + ing_list[rng.tableRemove(monster_parts)], + ing_list[rng.tableRemove(monster_parts)], + }, + }, + { + short_name = "focus", + name = "elixir of focus", + id = "ELIXIR_FOCUS", + start = "focus_start", + almost = "focus_almost_done", + full = "elixir_of_focus", + full_2 = "elixir_of_explosive_force", + full_3 = "elixir_of_serendipity", + poached = "focus_poached", + alchemist = "Agrimley the hermit", + ingredients = { + ing_list[rng.tableRemove(monster_parts)], + ing_list[rng.tableRemove(monster_parts)], + ing_list[rng.tableRemove(monster_parts)], + }, + }, + }, + { + { + short_name = "brawn", + name = "elixir of brawn", + id = "ELIXIR_BRAWN", + start = "brawn_start", + almost = "brawn_almost_done", + full = "elixir_of_brawn", + full_2 = "elixir_of_stoneskin", + full_3 = "elixir_of_foundations", + poached = "brawn_poached", + alchemist = "Ungrol of Last Hope", + ingredients = { + ing_list[rng.tableRemove(monster_parts)], + ing_list[rng.tableRemove(monster_parts)], + ing_list[rng.tableRemove(monster_parts)], + }, + }, + { + short_name = "stoneskin", + name = "elixir of stoneskin", + id = "ELIXIR_STONESKIN", + start = "stoneskin_start", + almost = "stoneskin_almost_done", + full = "elixir_of_stoneskin", + full_2 = "elixir_of_brawn", + full_3 = "elixir_of_foundations", + poached = "stoneskin_poached", + alchemist = "Ungrol of Last Hope", + ingredients = { + ing_list[rng.tableRemove(monster_parts)], + ing_list[rng.tableRemove(monster_parts)], + ing_list[rng.tableRemove(monster_parts)], + }, + }, + { + short_name = "foundations", + name = "elixir of foundations", + id = "ELIXIR_FOUNDATIONS", + start = "foundations_start", + almost = "foundations_almost_done", + full = "elixir_of_foundations", + full_2 = "elixir_of_brawn", + full_3 = "elixir_of_stoneskin", + poached = "foundations_poached", + alchemist = "Ungrol of Last Hope", + ingredients = { + ing_list[rng.tableRemove(monster_parts)], + ing_list[rng.tableRemove(monster_parts)], + ing_list[rng.tableRemove(monster_parts)], + }, + }, + }, + } + -- cookbook is redundant with the completeness of e, but going through the chat and quest code and changing all the cookbook reference seemed like more trouble than just keeping this around + local cookbook = { + fox = e[1][1].ingredients, + avoidance = e[1][2].ingredients, + precision = e[1][3].ingredients, + mysticism = e[2][1].ingredients, + savior = e[2][2].ingredients, + mastery = e[2][3].ingredients, + force = e[3][1].ingredients, + serendipity = e[3][2].ingredients, + focus = e[3][3].ingredients, + brawn = e[4][1].ingredients, + stoneskin = e[4][2].ingredients, + foundations = e[4][3].ingredients, + } + -- elixirs table is a relic from an earlier version of the code. Keeping it around because it sums things up nicely for anybody reading this + local elixirs = { + derth = {"elixir_of_the_fox", "elixir_of_avoidance", "elixir_of_precision"}, + elvala = {"elixir_of_mysticism", "elixir_of_the_savior", "elixir_of_mastery"}, + hermit = {"elixir_of_explosive_force", "elixir_of_serendipity", "elixir_of_focus"}, + hope = {"elixir_of_brawn", "elixir_of_stoneskin", "elixir_of_foundations"}, + } + + -- another relic from the pre-e days. + local alchemists = {"Stire of Derth", "Marus of Elvala", "Agrimley the hermit", "Ungrol of Last Hope", } + + return cookbook, elixirs, alchemists, e +end diff --git a/game/modules/tome/data/talents/misc/inscriptions.lua b/game/modules/tome/data/talents/misc/inscriptions.lua index 7da3c2b6510b94929fb7f037b45cc8be27f12db1..65b09d3b8083780e3409553925462993155a1a89 100644 --- a/game/modules/tome/data/talents/misc/inscriptions.lua +++ b/game/modules/tome/data/talents/misc/inscriptions.lua @@ -259,6 +259,39 @@ newInscription{ end, } +newInscription{ + name = "Infusion: Wild Growth", + type = {"inscriptions/infusions", 1}, + points = 1, + tactical = { ATTACKAREA = 2, DISABLE = 3 }, + range = 0, + radius = 5, + direct_hit = true, + target = function(self, t) + return {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t), selffire=false, talent=t} + end, + getDamage = function(self, t) return self:combatTalentMindDamage(t, 3, 20) end, + action = function(self, t) + local dam = t.getDamage(self, t) + local tg = self:getTalentTarget(t) + self:project(tg, self.x, self.y, function(tx, ty) + DamageType:get(DamageType.ENTANGLE).projector(self, tx, ty, DamageType.ENTANGLE, dam) + end) + game:playSoundNear(self, "talents/earth") + return true + end, + info = function(self, t) + local data = self:getInscriptionData(t.short_name) + local damage = t.getDamage(self, t) + return ([[Causes thick vines to spring from the ground and entangle all targets within %d squares for %d turns, pinning them in place and dealing %0.2f physical damage and %0.2f nature damage each turn.]]): + format(self:getTalentRadius(t), data.dur, damDesc(self, DamageType.PHYSICAL, damage)/3, damDesc(self, DamageType.Nature, 2*damage)/3) + end, + short_info = function(self, t) + local data = self:getInscriptionData(t.short_name) + return ([[Rad %d for %d turns]]):format(self:getTalentRadius(t), data.dur) + end, +} + ----------------------------------------------------------------------- -- Runes ----------------------------------------------------------------------- @@ -792,3 +825,29 @@ newInscription{ return ([[%d effects / %d heal]]):format(data.effects, data.heal + data.inc_stat) end, } + + +newInscription{ + name = "Taint: Telepathy", + type = {"inscriptions/taints", 1}, + points = 1, + is_spell = true, + range = 10, + action = function(self, t) + local rad = self:getTalentRange(t) + self:setEffect(self.EFF_SENSE, 5, { + range = rad, + actor = 1, + }) + self:setEffect(self.EFF_WEAKENED_MIND, 10, {power=20}) + return true + end, + info = function(self, t) + local data = self:getInscriptionData(t.short_name) + return ([[Strip the protective barriers from your mind for %d turns, allowing in the thoughts all creatures within %d squares but reducing mind save by %d for 10 turns.]]):format(data.dur, self:getTalentRange(t), 20) + end, + short_info = function(self, t) + local data = self:getInscriptionData(t.short_name) + return ([[Range %d telepathy for %d turns]]):format(self:getTalentRange(t), data.dur) + end, +} diff --git a/game/modules/tome/data/timed_effects.lua b/game/modules/tome/data/timed_effects.lua index 2ee8c33546b900e5189910271b15cf81122bf199..a31cb4aab505c39bafea834816c33ef4ddcac443 100644 --- a/game/modules/tome/data/timed_effects.lua +++ b/game/modules/tome/data/timed_effects.lua @@ -3537,3 +3537,18 @@ newEffect{ self:removeTemporaryValue("combat_mindpower", eff.mindid) end, } + +newEffect{ + name = "WEAKENED_MIND", + desc = "Weakened Mind", + long_desc = function(self, eff) return ("Decreases mind save by %d."):format(eff.power) end, + type = "mental", + status = "detrimental", + parameters = { power=10 }, + activate = function(self, eff) + eff.mindid = self:addTemporaryValue("combat_mentalresist", eff.power) + end, + deactivate = function(self, eff) + self:removeTemporaryValue("combat_mentalresist", eff.mindid) + end, +}