-- Library quest in Minas Anor -- Partially based on Fireproofing quest library_quest = {} -- The map definition itself library_quest.MAP = [[#!map # Permanent wall F:X:63:3 # Granite Wall F:#:57:3 # Cobblestone Road F:O:200:3 # Floor F:.:1:3 # Lich F:l:200:3:518 # Master lich F:L:200:3:658 # Quest exit F:<:6:3 D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX D:X###############################################################X D:X#= first then if index == current then color = TERM_GREEN elseif library_quest.book_contains_spell(spell) == TRUE then color = TERM_WHITE else color = TERM_ORANGE end library_quest.print_spell(color, row, spell) if row == height - 1 then return end row = row + 1 end end end library_quest.fill_book = function() -- Always start with a cleared book school_book[61] = {-1, -1, -1} screen_save() width, height = library_quest.get_term_size() -- room for legend margin = 3 first = 1 current = 1 done = FALSE while done == FALSE do library_quest.print_spells(first, current) inkey_scan = FALSE inkey_base = TRUE char = inkey() dir = get_keymap_dir(char) if char == ESCAPE then if library_quest.book_slots_left() == 0 then flush() done = get_check("Really create the book?") else done = TRUE end elseif char == strbyte('\r') then -- TODO: make tree of schools elseif char == strbyte('n') then current = current + height elseif char == strbyte('p') then current = current - height elseif char == strbyte('I') then print_spell_desc(library_quest.bookable_spells[current], 0) inkey() elseif dir == 2 then current = current + 1 elseif dir == 8 then current = current - 1 elseif dir == 6 then if library_quest.book_contains_spell(library_quest.bookable_spells[current]) == FALSE then library_quest.add_spell(library_quest.bookable_spells[current]) end elseif dir == 4 then library_quest.remove_spell(library_quest.bookable_spells[current]) end total = getn(library_quest.bookable_spells) if current > total then current = total elseif current < 1 then current = 1 end if current > (first + height - margin - 1) then first = current - height + margin + 1 elseif first > current then first = current end end screen_load() end -- Quest data and hooks add_quest { ["global"] = "LIBRARY_QUEST", ["name"] = "Library quest", ["desc"] = function() -- Quest taken if (quest(LIBRARY_QUEST).status == QUEST_STATUS_TAKEN) then print_hook("#####yAn Old Mages Quest! (Danger Level: 35)\n") print_hook("Make the library safe for the old mage in Minas Anor.\n") print_hook("\n") -- Quest done, book not gotten yet elseif (quest(LIBRARY_QUEST).status == QUEST_STATUS_COMPLETED) then print_hook("#####yAn Old Mages Quest!\n") print_hook("You have made the library safe for the old mage in Minas Anor.\n") print_hook("Perhaps you should see about a reward.\n") print_hook("\n") end end, ["level"] = 35, ["data"] = { ["school_book[61][1]"] = -1, ["school_book[61][2]"] = -1, ["school_book[61][3]"] = -1 }, ["hooks"] = { -- Start the game without the quest, need to request it [HOOK_BIRTH_OBJECTS] = function() quest(LIBRARY_QUEST).status = QUEST_STATUS_UNTAKEN school_book[61] = {-1, -1, -1} end, [HOOK_GEN_QUEST] = function() -- Only if player doing this quest if (player.inside_quest ~= LIBRARY_QUEST) then return FALSE end load_map(library_quest.MAP, 2, 2) level_flags2 = DF2_NO_GENO -- generate the Liches 518 liches = damroll(4, 2) -- plus one on the map while(liches > 0) do if 0 < library_quest.place_random(4, 4, 14, 37, 518) then liches = liches - 1 end end -- generate the Monastic liches 611 liches = damroll(1, 2) while(liches > 0) do if 0 < library_quest.place_random(14, 34, 37, 67, 611) then liches = liches - 1 end end -- generate more Monastic liches 611 liches = damroll(1, 2) - 1 while(liches > 0) do if 0 < library_quest.place_random(4, 34, 14, 67, 611) then liches = liches - 1 end end -- generate even more Monastic liches 611 liches = damroll(1, 2) - 1 while(liches > 0) do if 0 < library_quest.place_random(14, 4, 37, 34, 611) then liches = liches - 1 end end -- Flesh golem 256 golems = 2 while(golems > 0) do if 0 < library_quest.place_random(10, 10, 37, 67, 256) then golems = golems - 1 end end -- Clay golem 261 golems = 2 while(golems > 0) do if 0 < library_quest.place_random(10, 10, 37, 67, 261) then golems = golems - 1 end end -- Iron golem 367 golems = 2 while(golems > 0) do if 0 < library_quest.place_random(10, 10, 37, 67, 367) then golems = golems - 1 end end -- Mithril Golem 464 golems = 1 while(golems > 0) do if 0 < library_quest.place_random(10, 10, 37, 67, 464) then golems = golems - 1 end end -- one Master lich is on the map return TRUE end, [HOOK_STAIR] = function() local ret -- only ask this if player about to go up stairs of quest and hasn't won yet if (player.inside_quest ~= LIBRARY_QUEST) or (quest(LIBRARY_QUEST).status == QUEST_STATUS_COMPLETED) then return FALSE end if cave(player.py, player.px).feat ~= FEAT_LESS then return end -- flush all pending input flush() -- confirm ret = get_check("Really abandon the quest?") -- if yes, then if ret == TRUE then -- fail the quest quest(LIBRARY_QUEST).status = QUEST_STATUS_FAILED return FALSE else -- if no, they stay in the quest return TRUE end end, [HOOK_MONSTER_DEATH] = function() -- if they're in the quest and haven't won, continue if (player.inside_quest ~= LIBRARY_QUEST) or (quest(LIBRARY_QUEST).status == QUEST_STATUS_COMPLETED) then return FALSE end i = 1 count = -1 while i <= m_max do local monster = m_list[i] if (monster.r_idx > 0) and (monster.status <= MSTATUS_ENEMY) then count = count + 1 end i = i + 1 end if count == 0 then quest(LIBRARY_QUEST).status = QUEST_STATUS_COMPLETED msg_print(TERM_YELLOW, "The library is safe now.") end end, }, } -- Library store action add_building_action { ["index"] = 61, ["action"] = function() -- the quest hasn't been requested already, right? if quest(LIBRARY_QUEST).status == QUEST_STATUS_UNTAKEN then -- quest has been taken now quest(LIBRARY_QUEST).status = QUEST_STATUS_TAKEN -- issue instructions msg_print("I need get some stock from my main library, but it is infested with monsters!") msg_print("Please use the side entrance and vanquish the intruders for me.") return TRUE, FALSE, TRUE -- if quest completed elseif (quest(LIBRARY_QUEST).status == QUEST_STATUS_COMPLETED) then msg_print("Thank you! Let me make a special book for you.") msg_print("Tell me three spells and I will write them in the book.") library_quest.fill_book() if library_quest.book_slots_left() == 0 then quest(LIBRARY_QUEST).status = QUEST_STATUS_REWARDED book = create_object(TV_BOOK, 61) book.art_name = quark_add(player_name()) book.found = OBJ_FOUND_REWARD set_aware(book) set_known(book) inven_carry(book, FALSE) end -- if the player asks for a quest when they already have it, but haven't failed it, give them some extra instructions elseif (quest(LIBRARY_QUEST).status == QUEST_STATUS_TAKEN) then msg_print("Please use the side entrance and vanquish the intruders for me.") -- quest failed or completed, then give no more quests elseif (quest(LIBRARY_QUEST).status == QUEST_STATUS_FAILED) or (quest(LIBRARY_QUEST).status == QUEST_STATUS_REWARDED) then msg_print("I have no more quests for you.") end return TRUE end, }