diff options
Diffstat (limited to 'lib/mods/theme/scpt/fireprof.lua')
-rw-r--r-- | lib/mods/theme/scpt/fireprof.lua | 480 |
1 files changed, 480 insertions, 0 deletions
diff --git a/lib/mods/theme/scpt/fireprof.lua b/lib/mods/theme/scpt/fireprof.lua new file mode 100644 index 00000000..ea5153d8 --- /dev/null +++ b/lib/mods/theme/scpt/fireprof.lua @@ -0,0 +1,480 @@ +-- The Old Mages/Fireproofing quest: Bring back a rune from a fiery cave and get some books/scrolls/staves fireproofed in return + +fireproof_quest = {} + +-- The map definition itself +fireproof_quest.MAP = +[[#!map +# Created by fearoffours (fearoffours@moppy.co.uk) +# Made for ToME 2.1.x on 03/09/02 + +# Permanent wall +F:X:63:3 + +# Floor with dirt +F:.:88:3 + +# shallow lava +F:f:86:3 + +# Deep lava +F:F:85:3 + +### Random Monsters and/or Items +# Random object (upto 3 levels ood) +F:!:88:5:0:*21 + +# red mold +F:m:88:5:324 + +# Chimaera +F:H:88:5:341 + +# Red dragon bat +F:b:88:5:377 + +# Hellhound and +# Random object (upto 7 levels ood) on normal floor +F:C:88:5:613:*25 + +# Quest exit +F:<:6:3 + +D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +D:X......m.................H.........b...m......X +D:X.............b...............................X +D:X.......................m.....m.......H...b.C.X +D:X...............m.!........b.............FFFf.X +D:X.........m!............H....!........fffFFFffX +D:X..................................fffFFFFFFfFX +D:XFFf..............................fFFFFff..fffX +D:XFFFff........FFFFFF...........fffFFFfff......X +D:XfFFFFfff....FFFFFFFf.......fffFFFFFf.........X +D:X.fFFFFFFff.FFFFFFFFFfF..fffFFFFFFff..........X +D:X..fFFFFFFFffFFFfffFFFfffFFFFFFFFf............X +D:X...fFFFFFFFFFFff.ffFFFFFFFFFFFff.............X +D:X....fffFFFFFFff...ffFFFFFFFFFf...............X +D:X.......ffFFFf.......ffffFFfff................X +D:X.........fff.................................X +D:X.............................................X +D:X.............................................X +D:X.............................................X +D:X..................................<..........X +D:X.............................................X +D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + +# Starting position +P:22:26 +]] + + +-- change this constant (and the FOO_POINTS ones) to adjust the no of items fire-proofed as a reward +fireproof_quest.TOTAL_ITEM_POINTS = 24 + +-- These constants are how many 'points' each type of item will take up. So currently, you can fireproof 3 books, 4 staves or 12 scrolls. +fireproof_quest.BOOK_POINTS = 4 +fireproof_quest.STAFF_POINTS = 3 +fireproof_quest.SCROLL_POINTS = 1 + +add_quest +{ + ["global"] = "FIREPROOF_QUEST", + ["name"] = "Old Mages quest", + ["desc"] = function() + local num_books, num_staff, num_scroll + + num_books = fireproof_quest.item_points_remaining / fireproof_quest.BOOK_POINTS + num_staff = fireproof_quest.item_points_remaining / fireproof_quest.STAFF_POINTS + num_scroll = fireproof_quest.item_points_remaining / fireproof_quest.SCROLL_POINTS + + -- Quest taken + if (quest(FIREPROOF_QUEST).status == QUEST_STATUS_TAKEN) then + print_hook("#####yAn Old Mages Quest!\n") + print_hook("Retrieve the strange rune for the old mage in Lothlorien.\n") + print_hook("\n") + -- essence retrieved, not taken to mage + elseif (quest(FIREPROOF_QUEST).status == QUEST_STATUS_COMPLETED) then + print_hook("#####yAn Old Mages Quest!\n") + print_hook("You have retrieved the rune for the old mage in Lothlorien. Perhaps you \n") + print_hook("should see about a reward.\n") + print_hook("\n") + -- essence returned, not all books fireproofed + elseif (quest(FIREPROOF_QUEST).status == QUEST_STATUS_FINISHED) and (fireproof_quest.item_points_remaining > 0) then + print_hook("#####yAn Old Mages Quest!\n") + print_hook("You have retrieved the rune for the old mage in Lothlorien. He will still \n") + print_hook("fireproof "..num_books.." book(s) or "..num_staff.." staff/staves or "..num_scroll.." scroll(s) for you.\n") + print_hook("\n") + end + end, + ["level"] = 20, + ["data"] = { + -- store some variables + ["fireproof_quest.item_points_remaining"] = fireproof_quest.TOTAL_ITEM_POINTS, + ["fireproof_quest.essence"] = 0, + }, + ["hooks"] = { + -- Start the game without the quest, need to request it + [HOOK_BIRTH_OBJECTS] = function() + quest(FIREPROOF_QUEST).status = QUEST_STATUS_UNTAKEN + + -- reset some variables on birth + fireproof_quest.item_points_remaining = fireproof_quest.TOTAL_ITEM_POINTS + fireproof_quest.essence = 0 + end, + [HOOK_GEN_QUEST] = function() + local essence, y, x, traps, tries, trap_y, trap_x, grid + + -- Only if player doing this quest + if (player.inside_quest ~= FIREPROOF_QUEST) then + return FALSE + else + -- load the map + load_map(fireproof_quest.MAP, 2, 2) + + -- no teleport + level_flags2 = DF2_NO_TELEPORT + + -- determine type of rune + fireproof_quest.essence = randint(5) + + -- create essence + essence = create_object(TV_RUNE2, fireproof_quest.essence) + + -- mark rune + essence.pval2 = fireproof_quest.essence + essence.note = quark_add("quest") + + -- roll for co-ordinates in top half of map + y = randint(3) + 2 + x = randint(45) + 2 + + -- drop it + drop_near(essence, -1, y, x) + + -- how many traps to generate + traps = rand_range(10, 30) + + -- generate the traps + while (traps > 0) do + + -- initialise tries variable + tries = 0 + + -- make sure it's a safe place + while (tries == 0) do + + -- get grid coordinates + trap_y = randint(19) + 2 + trap_x = randint(45) + 2 + grid = cave(trap_y, trap_x) + + -- are the coordinates on a stair, or a wall? + if (cave_is(grid, FF1_PERMANENT) ~= 0) or (cave_is(grid, FF1_FLOOR) == 0) then + + -- try again + tries = 0 + else + -- not a stair, then stop this 'while' + tries = 1 + end + end + + -- randomise level of trap + trap_level = rand_range(20, 40) + + -- put the trap there + place_trap(trap_y, trap_x, trap_level) + + -- that's one less trap to place + traps = traps - 1 + end + return TRUE + end + end, + [HOOK_STAIR] = function() + local ret + + -- only ask this if player about to go up stairs of quest and hasn't retrieved rune + if (player.inside_quest ~= FIREPROOF_QUEST) or + (quest(FIREPROOF_QUEST).status == QUEST_STATUS_COMPLETED) then + return FALSE + else + 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(FIREPROOF_QUEST).status = QUEST_STATUS_FAILED + return FALSE + else + -- if no, they stay in the quest + return TRUE + end + end + end, + [HOOK_GET] = function(o_ptr) + + -- if they're in the quest and haven't picked up the rune already, continue + if (player.inside_quest ~= FIREPROOF_QUEST) or + (quest(FIREPROOF_QUEST).status == QUEST_STATUS_COMPLETED) then + return FALSE + else + + -- check that it's the real rune and not another one generated via the random object placing in fireproof.map + if (o_ptr.pval2 == fireproof_quest.essence) then + + -- ok mark the quest 'completed' + quest(FIREPROOF_QUEST).status = QUEST_STATUS_COMPLETED + msg_print(TERM_YELLOW, "Fine! Looks like you've found it.") + end + end + end, + + }, +} + +-- add the bit that determines what happens when the request 'q'uest bit is done in the wizard spire +add_building_action +{ + -- Index is used in ba_info.txt to set the actions + ["index"] = 56, + ["action"] = function() + + local num_books, num_staff, num_scroll + + num_books = fireproof_quest.item_points_remaining / fireproof_quest.BOOK_POINTS + num_staff = fireproof_quest.item_points_remaining / fireproof_quest.STAFF_POINTS + num_scroll = fireproof_quest.item_points_remaining / fireproof_quest.SCROLL_POINTS + + -- the quest hasn;t been requested already, right? + if quest(FIREPROOF_QUEST).status == QUEST_STATUS_UNTAKEN then + + -- quest has been taken now + quest(FIREPROOF_QUEST).status = QUEST_STATUS_TAKEN + fireproof_quest.item_points_remaining = fireproof_quest.TOTAL_ITEM_POINTS + + -- issue instructions + msg_print("I need a very special rune for a spell I am working on. I am too old to ") + msg_print("fetch it myself. Please bring it back to me. You can find it north of here.") + msg_print("Be careful with it, it's fragile and might be destroyed easily.") + + return TRUE, FALSE, TRUE + -- if quest completed (rune was retrieved) + elseif (quest(FIREPROOF_QUEST).status == QUEST_STATUS_COMPLETED) then + + -- ask for rune + ret, item = get_item("Which rune?", + "You have no runes to return", + bor(USE_INVEN), + function (obj) + + -- check it's the 'marked' rune + if (obj.tval == TV_RUNE2) and (obj.sval == fireproof_quest.essence) and (obj.pval2 == fireproof_quest.essence) then + return TRUE + end + return FALSE + end + ) + + -- didn't get the rune? + if (ret == FALSE) then + return TRUE + + -- got the rune! + else + + -- take rune + inven_item_increase(item, -1) + inven_item_optimize(item) + msg_print("Great! Let me fireproof some of your items in thanks. I can do "..num_books.." books, ") + msg_print(num_staff.." staves, or "..num_scroll.." scrolls.") + + -- how many items to proof? + local items = fireproof_quest.item_points_remaining + + -- repeat till up to 3 (value defined as TOTAL_ITEM_POINTS constant) books fireproofed + while items > 0 do + ret = fireproof() + + -- don't loop the fireproof if there's nothing to fireproof + if ret == FALSE then + break + end + + -- subtract item points + items = fireproof_quest.item_points_remaining + end + + -- have they all been done? + if (fireproof_quest.item_points_remaining == 0) then + -- mark quest to make sure no more quests are given + quest(FIREPROOF_QUEST).status = QUEST_STATUS_REWARDED + else + -- mark in preparation of anymore books to fireproof + quest(FIREPROOF_QUEST).status = QUEST_STATUS_FINISHED + end + + + 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(FIREPROOF_QUEST).status == QUEST_STATUS_TAKEN) then + msg_print("The rune is in a cave just behind the shop.") + + -- ok not all books have been fireproofed... lets do the rest + elseif (quest(FIREPROOF_QUEST).status == QUEST_STATUS_FINISHED) then + + -- how many books still to proof? + local items = fireproof_quest.item_points_remaining + + -- repeat as necessary + while items > 0 do + ret = fireproof() + + -- don't loop the fireproof if there's nothing to fireproof + if ret == FALSE then + break + else + -- have they all been done? + if (fireproof_quest.item_points_remaining == 0) then quest(FIREPROOF_QUEST).status = QUEST_STATUS_REWARDED end + end + + -- subtract item points + items = fireproof_quest.item_points_remaining + end + + -- quest failed or completed, then give no more quests + elseif (quest(FIREPROOF_QUEST).status == QUEST_STATUS_FAILED) or (quest(FIREPROOF_QUEST).status == QUEST_STATUS_REWARDED) then + msg_print("I have no more quests for you") + end + return TRUE + end, +} + +-- the routine that checks for a book and actually fireproofs it +function fireproof() + + local ret, item, obj2, stack, obj3, carry_it + + ret, item = get_item("Which item shall I fireproof?", + "You have no more items I can fireproof, come back when you have some.", + bor(USE_INVEN), + function (obj) + + -- get some flags + local f1, f2, f3, f4, f5, esp = object_flags(obj) + + -- is it a book/staff/scroll, is it already fireproof? + if ((obj.tval == TV_BOOK) or (obj.tval == TV_SCROLL) or (obj.tval == TV_STAFF)) and (band(f3, TR3_IGNORE_FIRE) == 0) then + return TRUE + end + return FALSE + end + ) + + -- get the object type from the number + obj2 = get_object(item) + + -- check we have enough points (if we 'got' an item) + if (ret == TRUE) then + ret2, stack = enough_points(obj2) + end + + -- did either routine fail? + if (ret == FALSE) or (ret2 == FALSE) then + return FALSE + else + + -- are we part of the items from a stack? + if (obj2.number ~= stack) then + + -- make a new object to handle + object_copy(obj_forge, obj2) + + -- give it the right number of items + obj_forge.number = stack + + -- adjust for number of items in pack not to be fireproofed + obj2.number = obj2.number - stack + obj3 = obj_forge + + -- we'll need to add this to the inventory after fireproofing + carry_it = TRUE + else + + -- use the whole stack + obj3 = obj2 + + -- we'll be dealing this while it's still in the inventory + carry_it = FALSE + end + + -- make it fireproof + obj3.name2 = 149 + + -- apply it, making sure the pvals don't change with apply_magic (it would change the type of book!) + local oldpval = obj3.pval + local oldpval2 = obj3.pval2 + local oldpval3 = obj3.pval3 + apply_magic(obj3, -1, FALSE, FALSE, FALSE) + obj3.pval = oldpval + obj3.pval2 = oldpval2 + obj3.pval3 = oldpval3 + + -- put it in the inventory if it's only part of a stack + if (carry_it == TRUE) then + inven_carry(obj3, TRUE) + end + + -- id and notice it + set_known(obj3) + set_aware(obj3) + + return TRUE + end +end + +-- This function makes sure the player has enough 'points' left to fireproof stuff. +function enough_points(obj) + local item_value, stack + + -- are the items in a stack? + if (obj.number > 1) then + + -- how many to fireproof? + stack = get_quantity("How many would you like fireproofed?", obj.number) + else + stack = 1 + end + + -- check for item type and multiply number in the stack by the amount of points per item of that type + if (obj.tval == TV_BOOK) then + item_value = fireproof_quest.BOOK_POINTS * stack + elseif (obj.tval == TV_STAFF) then + item_value = fireproof_quest.STAFF_POINTS * stack + elseif (obj.tval == TV_SCROLL) then + item_value = fireproof_quest.SCROLL_POINTS * stack + end + + -- do we have enough points? + if (item_value > fireproof_quest.item_points_remaining) then + msg_print("I do not have enough fireproofing material for that.") + return FALSE + else + -- if so then subtract those points before we do the fireproofing + fireproof_quest.item_points_remaining = fireproof_quest.item_points_remaining - item_value + end + + -- Used all the points? the quest is completely rewarded. + if fireproof_quest.item_points_remaining == 0 then quest(FIREPROOF_QUEST).status = QUEST_STATUS_REWARDED end + + return TRUE, stack +end + |